1
#![allow(clippy::unwrap_used)]
2
#![allow(clippy::expect_used)]
3
use std::sync::{Arc, RwLock};
4
use ustr::Ustr;
5

            
6
use serde_json::Map as JsonMap;
7
use serde_json::Value;
8
use serde_json::Value as JsonValue;
9

            
10
use crate::ast::Moo;
11
use crate::ast::abstract_comprehension::AbstractComprehensionBuilder;
12
use crate::ast::ac_operators::ACOperatorKind;
13
use crate::ast::comprehension::ComprehensionBuilder;
14
use crate::ast::records::RecordValue;
15
use crate::ast::{
16
    AbstractLiteral, Atom, DeclarationPtr, Domain, Expression, FuncAttr, IntVal, JectivityAttr,
17
    Literal, MSetAttr, Name, PartialityAttr, Range, RecordEntry, SetAttr, SymbolTable,
18
    SymbolTablePtr,
19
};
20
use crate::ast::{DomainPtr, Metadata};
21
use crate::context::Context;
22
use crate::error::{Error, Result};
23
use crate::{Model, bug, error, into_matrix_expr, throw_error};
24

            
25
#[allow(unused_macros)]
26
macro_rules! parser_trace {
27
    ($($arg:tt)+) => {
28
        log::trace!(target:"jsonparser",$($arg)+)
29
    };
30
}
31

            
32
#[allow(unused_macros)]
33
macro_rules! parser_debug {
34
    ($($arg:tt)+) => {
35
        log::debug!(target:"jsonparser",$($arg)+)
36
    };
37
}
38

            
39
10004
pub fn model_from_json(str: &str, context: Arc<RwLock<Context<'static>>>) -> Result<Model> {
40
10004
    let mut m = Model::new(context);
41
10004
    let v: JsonValue = serde_json::from_str(str)?;
42
10004
    let statements = v["mStatements"]
43
10004
        .as_array()
44
10004
        .ok_or(error!("mStatements is not an array"))?;
45

            
46
29630
    for statement in statements {
47
29630
        let entry = statement
48
29630
            .as_object()
49
29630
            .ok_or(error!("mStatements contains a non-object"))?
50
29630
            .iter()
51
29630
            .next()
52
29630
            .ok_or(error!("mStatements contains an empty object"))?;
53

            
54
29630
        match entry.0.as_str() {
55
29630
            "Declaration" => {
56
20720
                let decl = entry
57
20720
                    .1
58
20720
                    .as_object()
59
20720
                    .ok_or(error!("Declaration is not an object".to_owned()))?;
60

            
61
                // One field in the declaration should tell us what kind it is.
62
                //
63
                // Find it, ignoring the other fields.
64
                //
65
                // e.g. FindOrGiven,
66

            
67
20720
                let mut valid_decl: bool = false;
68
20720
                let scope = m.symbols_ptr_unchecked().clone();
69
20720
                let model = &mut m;
70
20720
                for (kind, value) in decl {
71
20720
                    match kind.as_str() {
72
20720
                        "FindOrGiven" => {
73
18782
                            parse_variable(value, &mut model.symbols_mut())?;
74
18782
                            valid_decl = true;
75
18782
                            break;
76
                        }
77
1938
                        "Letting" => {
78
1938
                            parse_letting(value, &scope)?;
79
1918
                            valid_decl = true;
80
1918
                            break;
81
                        }
82
                        _ => continue,
83
                    }
84
                }
85

            
86
20700
                if !valid_decl {
87
                    throw_error!("Declaration is not a valid kind")?;
88
20700
                }
89
            }
90
8910
            "SuchThat" => {
91
8910
                let constraints_arr = match entry.1.as_array() {
92
8910
                    Some(x) => x,
93
                    None => bug!("SuchThat is not a vector"),
94
                };
95

            
96
8910
                let constraints: Vec<Expression> = constraints_arr
97
8910
                    .iter()
98
13890
                    .map(|x| parse_expression(x, m.symbols_ptr_unchecked()))
99
8910
                    .collect::<Result<Vec<_>>>()?;
100
8910
                m.add_constraints(constraints);
101
            }
102
            otherwise => bug!("Unhandled Statement {:#?}", otherwise),
103
        }
104
    }
105
9984
    Ok(m)
106
10004
}
107

            
108
18782
fn parse_variable(v: &JsonValue, symtab: &mut SymbolTable) -> Result<()> {
109
18782
    let arr = v.as_array().ok_or(error!("FindOrGiven is not an array"))?;
110

            
111
18782
    let variable_type = arr[0]
112
18782
        .as_str()
113
18782
        .ok_or(error!("FindOrGiven[0] is not a string"))?;
114

            
115
18782
    let name = arr[1]
116
18782
        .as_object()
117
18782
        .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
118
18782
        .as_str()
119
18782
        .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
120

            
121
18782
    let name = Name::User(Ustr::from(name));
122

            
123
18782
    let domain = arr[2]
124
18782
        .as_object()
125
18782
        .ok_or(error!("FindOrGiven[2] is not an object"))?
126
18782
        .iter()
127
18782
        .next()
128
18782
        .ok_or(error!("FindOrGiven[2] is an empty object"))?;
129

            
130
18782
    let domain = parse_domain(domain.0, domain.1, symtab)?;
131

            
132
18782
    let decl = match variable_type {
133
18782
        "Find" => DeclarationPtr::new_find(name.clone(), domain),
134
52
        "Given" => DeclarationPtr::new_given(name.clone(), domain),
135
        _ => {
136
            return Err(error!("FindOrGiven[0] is not 'Find' or 'Given'"));
137
        }
138
    };
139

            
140
18782
    symtab.insert(decl).ok_or(Error::Parse(format!(
141
18782
        "Could not add {name} to symbol table as it already exists"
142
18782
    )))
143
18782
}
144

            
145
1938
fn parse_letting(v: &JsonValue, scope: &SymbolTablePtr) -> Result<()> {
146
1938
    let arr = v.as_array().ok_or(error!("Letting is not an array"))?;
147
1938
    let name = arr[0]
148
1938
        .as_object()
149
1938
        .ok_or(error!("Letting[0] is not an object"))?["Name"]
150
1938
        .as_str()
151
1938
        .ok_or(error!("Letting[0].Name is not a string"))?;
152
1938
    let name = Name::User(Ustr::from(name));
153
    // value letting
154
1938
    if let Ok(value) = parse_expression(&arr[1], scope) {
155
1618
        let mut symtab = scope.write();
156
1618
        symtab
157
1618
            .insert(DeclarationPtr::new_value_letting(name.clone(), value))
158
1618
            .ok_or(Error::Parse(format!(
159
1618
                "Could not add {name} to symbol table as it already exists"
160
1618
            )))
161
    } else {
162
        // domain letting
163
320
        let domain = &arr[1]
164
320
            .as_object()
165
320
            .ok_or(error!("Letting[1] is not an object".to_owned()))?["Domain"]
166
320
            .as_object()
167
320
            .ok_or(error!("Letting[1].Domain is not an object"))?
168
320
            .iter()
169
320
            .next()
170
320
            .ok_or(error!("Letting[1].Domain is an empty object"))?;
171

            
172
320
        let mut symtab = scope.write();
173
320
        let domain = parse_domain(domain.0, domain.1, &mut symtab)?;
174

            
175
320
        symtab
176
320
            .insert(DeclarationPtr::new_domain_letting(name.clone(), domain))
177
320
            .ok_or(Error::Parse(format!(
178
320
                "Could not add {name} to symbol table as it already exists"
179
320
            )))
180
    }
181
1938
}
182

            
183
34662
fn parse_domain(
184
34662
    domain_name: &str,
185
34662
    domain_value: &JsonValue,
186
34662
    symbols: &mut SymbolTable,
187
34662
) -> Result<DomainPtr> {
188
34662
    match domain_name {
189
34662
        "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
190
8552
        "DomainBool" => Ok(Domain::bool()),
191
4124
        "DomainReference" => {
192
640
            let name = Name::user(
193
640
                domain_value
194
640
                    .as_array()
195
640
                    .ok_or(error!("DomainReference is not an array"))?[0]
196
640
                    .as_object()
197
640
                    .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
198
640
                    .as_str()
199
640
                    .ok_or(error!("DomainReference[0].Name is not a string"))?,
200
            );
201
640
            let ptr = symbols
202
640
                .lookup(&name)
203
640
                .ok_or(error!(format!("Name {name} not found")))?;
204
640
            let dom =
205
640
                Domain::reference(ptr).ok_or(error!("Could not construct reference domain"))?;
206
640
            Ok(dom)
207
        }
208
3484
        "DomainSet" => {
209
260
            let dom = domain_value.get(2).and_then(|v| v.as_object());
210
260
            let domain_obj = dom.ok_or(error!("DomainSet is missing domain object"))?;
211
260
            let domain = domain_obj
212
260
                .iter()
213
260
                .next()
214
260
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
215
260
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
216
260
            let size = domain_value
217
260
                .get(1)
218
260
                .and_then(|v| v.as_object())
219
260
                .ok_or(error!("Set size attributes is not an object"))?;
220
260
            let size = parse_size_attr(size, symbols)?;
221
260
            let attr: SetAttr<IntVal> = SetAttr { size };
222
260
            Ok(Domain::set(attr, domain))
223
        }
224
3224
        "DomainMSet" => {
225
360
            let dom = domain_value
226
360
                .get(2)
227
360
                .and_then(|v| v.as_object())
228
360
                .expect("domain object exists");
229
360
            let domain = dom
230
360
                .iter()
231
360
                .next()
232
360
                .ok_or(Error::Parse("DomainMSet is an empty object".to_owned()))?;
233
360
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
234

            
235
            // Parse Attributes
236
360
            let attributes = domain_value
237
360
                .get(1)
238
360
                .and_then(|v| v.as_array())
239
360
                .ok_or(error!("MSet attributes is not a json array"))?;
240

            
241
360
            let size = attributes
242
360
                .first()
243
360
                .and_then(|v| v.as_object())
244
360
                .ok_or(error!("MSet size attributes is not an object"))?;
245
360
            let size = parse_size_attr(size, symbols)?;
246

            
247
360
            let occurrence = attributes
248
360
                .get(1)
249
360
                .and_then(|v| v.as_object())
250
360
                .ok_or(error!("MSet occurrence attributes is not an object"))?;
251
360
            let occurrence = parse_occur_attr(occurrence, symbols)?;
252

            
253
360
            let attr: MSetAttr<IntVal> = MSetAttr { size, occurrence };
254
360
            Ok(Domain::mset(attr, domain))
255
        }
256

            
257
2864
        "DomainMatrix" => {
258
2184
            let domain_value = domain_value
259
2184
                .as_array()
260
2184
                .ok_or(error!("Domain matrix is not an array"))?;
261

            
262
2184
            let indexed_by_domain = domain_value[0].clone();
263
2184
            let (index_domain_name, index_domain_value) = indexed_by_domain
264
2184
                .as_object()
265
2184
                .ok_or(error!("DomainMatrix[0] is not an object"))?
266
2184
                .iter()
267
2184
                .next()
268
2184
                .ok_or(error!(""))?;
269

            
270
2184
            let (value_domain_name, value_domain_value) = domain_value[1]
271
2184
                .as_object()
272
2184
                .ok_or(error!(""))?
273
2184
                .iter()
274
2184
                .next()
275
2184
                .ok_or(error!(""))?;
276

            
277
            // Conjure stores a 2-d matrix as a matrix of a matrix.
278
            //
279
            // Therefore, the index is always a Domain.
280

            
281
2184
            let mut index_domains: Vec<DomainPtr> = vec![];
282

            
283
2184
            index_domains.push(parse_domain(
284
2184
                index_domain_name,
285
2184
                index_domain_value,
286
2184
                symbols,
287
            )?);
288

            
289
            // We want to store 2-d matrices as a matrix with two index domains, not a matrix in a
290
            // matrix.
291
            //
292
            // Walk through the value domain until it is not a DomainMatrix, adding the index to
293
            // our list of indices.
294
2184
            let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
295
2544
            while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
296
360
                index_domains.append(&mut indices);
297
360
                value_domain = new_value_domain.clone()
298
            }
299

            
300
2184
            Ok(Domain::matrix(value_domain, index_domains))
301
        }
302
680
        "DomainTuple" => {
303
140
            let domain_value = domain_value
304
140
                .as_array()
305
140
                .ok_or(error!("Domain tuple is not an array"))?;
306

            
307
            //iterate through the array and parse each domain
308
140
            let domain = domain_value
309
140
                .iter()
310
280
                .map(|x| {
311
280
                    let domain = x
312
280
                        .as_object()
313
280
                        .ok_or(error!("DomainTuple[0] is not an object"))?
314
280
                        .iter()
315
280
                        .next()
316
280
                        .ok_or(error!("DomainTuple[0] is an empty object"))?;
317
280
                    parse_domain(domain.0, domain.1, symbols)
318
280
                })
319
140
                .collect::<Result<Vec<DomainPtr>>>()?;
320

            
321
140
            Ok(Domain::tuple(domain))
322
        }
323
540
        "DomainRecord" => {
324
20
            let domain_value = domain_value
325
20
                .as_array()
326
20
                .ok_or(error!("Domain Record is not a json array"))?;
327

            
328
20
            let mut record_entries = vec![];
329

            
330
40
            for item in domain_value {
331
                //collect the name of the record field
332
40
                let name = item[0]
333
40
                    .as_object()
334
40
                    .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
335
40
                    .as_str()
336
40
                    .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
337

            
338
40
                let name = Name::User(Ustr::from(name));
339
                // then collect the domain of the record field
340
40
                let domain = item[1]
341
40
                    .as_object()
342
40
                    .ok_or(error!("FindOrGiven[2] is not an object"))?
343
40
                    .iter()
344
40
                    .next()
345
40
                    .ok_or(error!("FindOrGiven[2] is an empty object"))?;
346

            
347
40
                let domain = parse_domain(domain.0, domain.1, symbols)?;
348

            
349
40
                let rec = RecordEntry { name, domain };
350

            
351
40
                record_entries.push(rec);
352
            }
353

            
354
            // add record fields to symbol table
355
40
            for decl in record_entries
356
20
                .iter()
357
20
                .cloned()
358
20
                .map(DeclarationPtr::new_record_field)
359
            {
360
40
                symbols.insert(decl).ok_or(error!(
361
                    "record field should not already be in the symbol table"
362
                ))?;
363
            }
364

            
365
20
            Ok(Domain::record(record_entries))
366
        }
367
520
        "DomainFunction" => {
368
520
            let domain = domain_value
369
520
                .get(2)
370
520
                .and_then(|v| v.as_object())
371
520
                .ok_or(error!("Function domain is not an object"))?;
372
520
            let domain = domain
373
520
                .iter()
374
520
                .next()
375
520
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
376
520
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
377

            
378
520
            let codomain = domain_value
379
520
                .get(3)
380
520
                .and_then(|v| v.as_object())
381
520
                .ok_or(error!("Function codomain is not an object"))?;
382
520
            let codomain = codomain
383
520
                .iter()
384
520
                .next()
385
520
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
386
520
            let codomain = parse_domain(codomain.0.as_str(), codomain.1, symbols)?;
387

            
388
            // Attribute parsing
389
520
            let attributes = domain_value
390
520
                .get(1)
391
520
                .and_then(|v| v.as_array())
392
520
                .ok_or(error!("Function attributes is not a json array"))?;
393
520
            let size = attributes
394
520
                .first()
395
520
                .and_then(|v| v.as_object())
396
520
                .ok_or(error!("Function size attributes is not an object"))?;
397
520
            let size = parse_size_attr(size, symbols)?;
398
520
            let partiality = attributes
399
520
                .get(1)
400
520
                .and_then(|v| v.as_str())
401
520
                .ok_or(error!("Function partiality is not a string"))?;
402
520
            let partiality = match partiality {
403
520
                "PartialityAttr_Partial" => Some(PartialityAttr::Partial),
404
80
                "PartialityAttr_Total" => Some(PartialityAttr::Total),
405
                _ => None,
406
            };
407
520
            let partiality =
408
520
                partiality.ok_or(Error::Parse("Partiality is an unknown type".to_owned()))?;
409
520
            let jectivity = attributes
410
520
                .get(2)
411
520
                .and_then(|v| v.as_str())
412
520
                .ok_or(error!("Function jectivity is not a string"))?;
413
520
            let jectivity = match jectivity {
414
520
                "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
415
440
                "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
416
400
                "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
417
360
                "JectivityAttr_None" => Some(JectivityAttr::None),
418
                _ => None,
419
            };
420
520
            let jectivity =
421
520
                jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
422

            
423
520
            let attr: FuncAttr<IntVal> = FuncAttr {
424
520
                size,
425
520
                partiality,
426
520
                jectivity,
427
520
            };
428

            
429
520
            Ok(Domain::function(attr, domain, codomain))
430
        }
431
        _ => Err(Error::Parse(
432
            "FindOrGiven[2] is an unknown object".to_owned(), // consider covered
433
        )),
434
    }
435
34662
}
436

            
437
1140
fn parse_size_attr(
438
1140
    attr_map: &JsonMap<String, JsonValue>,
439
1140
    symbols: &mut SymbolTable,
440
1140
) -> Result<Range<IntVal>> {
441
1140
    let scope = SymbolTablePtr::new();
442
1140
    *scope.write() = symbols.clone();
443

            
444
1140
    let attr_obj = attr_map
445
1140
        .iter()
446
1140
        .next()
447
1140
        .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
448
1140
    match attr_obj.0.as_str() {
449
1140
        "SizeAttr_None" => Ok(Range::Unbounded),
450
580
        "SizeAttr_MinSize" => {
451
260
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
452
260
            Ok(Range::UnboundedR(size))
453
        }
454
320
        "SizeAttr_MaxSize" => {
455
96
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
456
96
            Ok(Range::UnboundedL(size))
457
        }
458
224
        "SizeAttr_MinMaxSize" => {
459
104
            let min_max = attr_obj
460
104
                .1
461
104
                .as_array()
462
104
                .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
463
104
            let min = min_max
464
104
                .first()
465
104
                .ok_or(error!("SizeAttr Min is not present"))?;
466
104
            let min_int = parse_expression_to_int_val(min, &scope)?;
467
104
            let max = min_max
468
104
                .get(1)
469
104
                .ok_or(error!("SizeAttr Max is not present"))?;
470
104
            let max_int = parse_expression_to_int_val(max, &scope)?;
471
104
            Ok(Range::Bounded(min_int, max_int))
472
        }
473
120
        "SizeAttr_Size" => {
474
120
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
475
120
            Ok(Range::Single(size))
476
        }
477
        _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
478
    }
479
1140
}
480

            
481
360
fn parse_occur_attr(
482
360
    attr_map: &JsonMap<String, JsonValue>,
483
360
    symbols: &mut SymbolTable,
484
360
) -> Result<Range<IntVal>> {
485
360
    let scope = SymbolTablePtr::new();
486
360
    *scope.write() = symbols.clone();
487
360
    let attr_obj = attr_map
488
360
        .iter()
489
360
        .next()
490
360
        .ok_or(Error::Parse("OccurAttr is an empty object".to_owned()))?;
491
360
    match attr_obj.0.as_str() {
492
360
        "OccurAttr_None" => Ok(Range::Unbounded),
493
200
        "OccurAttr_MinOccur" => {
494
40
            let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
495
40
            Ok(Range::UnboundedR(size_int))
496
        }
497
160
        "OccurAttr_MaxOccur" => {
498
80
            let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
499
80
            Ok(Range::UnboundedL(size_int))
500
        }
501
80
        "OccurAttr_MinMaxOccur" => {
502
80
            let min_max = attr_obj
503
80
                .1
504
80
                .as_array()
505
80
                .ok_or(error!("OccurAttr MinMaxOccur is not a json array"))?;
506
80
            let min = min_max
507
80
                .first()
508
80
                .ok_or(error!("OccurAttr Min is not present"))?;
509
80
            let min_int = parse_expression_to_int_val(min, &scope)?;
510
80
            let max = min_max
511
80
                .get(1)
512
80
                .ok_or(error!("OccurAttr Max is not present"))?;
513
80
            let max_int = parse_expression_to_int_val(max, &scope)?;
514
80
            Ok(Range::Bounded(min_int, max_int))
515
        }
516
        "OccurAttr_Size" => {
517
            let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
518
            Ok(Range::Single(size_int))
519
        }
520
        _ => Err(Error::Parse("OccurAttr is an unknown type".to_owned())),
521
    }
522
360
}
523

            
524
26110
fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<DomainPtr> {
525
26110
    let scope = SymbolTablePtr::new();
526
26110
    *scope.write() = symbols.clone();
527

            
528
26110
    let mut ranges = Vec::new();
529
26110
    let arr = v
530
26110
        .as_array()
531
26110
        .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
532
26110
        .as_array()
533
26110
        .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
534
27170
    for range in arr {
535
27162
        let range = range
536
27162
            .as_object()
537
27162
            .ok_or(error!("DomainInt[1] contains a non-object"))?
538
27162
            .iter()
539
27162
            .next()
540
27162
            .ok_or(error!("DomainInt[1] contains an empty object"))?;
541
27162
        match range.0.as_str() {
542
27162
            "RangeBounded" => {
543
25382
                let arr = range
544
25382
                    .1
545
25382
                    .as_array()
546
25382
                    .ok_or(error!("RangeBounded is not an array".to_owned()))?;
547
25382
                let mut nums = Vec::new();
548
50764
                for item in arr.iter() {
549
50764
                    let num = parse_expression_to_int_val(item, &scope)?;
550
50764
                    nums.push(num);
551
                }
552
25382
                let lower = nums
553
25382
                    .first()
554
25382
                    .cloned()
555
25382
                    .ok_or(error!("RangeBounded lower bound missing"))?;
556
25382
                let upper = nums
557
25382
                    .get(1)
558
25382
                    .cloned()
559
25382
                    .ok_or(error!("RangeBounded upper bound missing"))?;
560
25382
                ranges.push(Range::Bounded(lower, upper));
561
            }
562
1780
            "RangeSingle" => {
563
1780
                let num = parse_expression_to_int_val(range.1, &scope)?;
564
1780
                ranges.push(Range::Single(num));
565
            }
566
            _ => return throw_error!("DomainInt[1] contains an unknown object"),
567
        }
568
    }
569
26110
    Ok(Domain::int(ranges))
570
26110
}
571

            
572
53508
fn parse_expression_to_int_val(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<IntVal> {
573
53508
    parser_trace!("trying to parse domain value as expression: {}", obj);
574
53508
    let expr = parse_expression(obj, scope)?;
575

            
576
53508
    if let Some(Literal::Int(i)) = expr.clone().into_literal() {
577
52032
        return Ok(IntVal::Const(i));
578
1476
    }
579

            
580
916
    if let Expression::Atomic(_, Atom::Reference(reference)) = &expr
581
916
        && let Some(reference_val) = IntVal::new_ref(reference)
582
    {
583
916
        return Ok(reference_val);
584
560
    }
585

            
586
560
    IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
587
53508
}
588

            
589
type BinOp = fn(Metadata, Moo<Expression>, Moo<Expression>) -> Expression;
590
type UnaryOp = fn(Metadata, Moo<Expression>) -> Expression;
591

            
592
49968
fn binary_operator(op_name: &str) -> Option<BinOp> {
593
49968
    match op_name {
594
49968
        "MkOpIn" => Some(Expression::In),
595
49608
        "MkOpUnion" => Some(Expression::Union),
596
49468
        "MkOpIntersect" => Some(Expression::Intersect),
597
49328
        "MkOpSupset" => Some(Expression::Supset),
598
49168
        "MkOpSupsetEq" => Some(Expression::SupsetEq),
599
49008
        "MkOpSubset" => Some(Expression::Subset),
600
48808
        "MkOpSubsetEq" => Some(Expression::SubsetEq),
601
48636
        "MkOpEq" => Some(Expression::Eq),
602
35676
        "MkOpNeq" => Some(Expression::Neq),
603
32972
        "MkOpGeq" => Some(Expression::Geq),
604
31252
        "MkOpLeq" => Some(Expression::Leq),
605
27916
        "MkOpGt" => Some(Expression::Gt),
606
26432
        "MkOpLt" => Some(Expression::Lt),
607
24104
        "MkOpLexLt" => Some(Expression::LexLt),
608
23784
        "MkOpLexGt" => Some(Expression::LexGt),
609
23784
        "MkOpLexLeq" => Some(Expression::LexLeq),
610
23304
        "MkOpLexGeq" => Some(Expression::LexGeq),
611
23304
        "MkOpDiv" => Some(Expression::UnsafeDiv),
612
20984
        "MkOpMod" => Some(Expression::UnsafeMod),
613
19984
        "MkOpMinus" => Some(Expression::Minus),
614
18340
        "MkOpImply" => Some(Expression::Imply),
615
16528
        "MkOpIff" => Some(Expression::Iff),
616
16328
        "MkOpPow" => Some(Expression::UnsafePow),
617
15064
        "MkOpImage" => Some(Expression::Image),
618
14984
        "MkOpImageSet" => Some(Expression::ImageSet),
619
14904
        "MkOpPreImage" => Some(Expression::PreImage),
620
14824
        "MkOpInverse" => Some(Expression::Inverse),
621
14744
        "MkOpRestrict" => Some(Expression::Restrict),
622
14664
        _ => None,
623
    }
624
49968
}
625

            
626
29328
fn unary_operator(op_name: &str) -> Option<UnaryOp> {
627
29328
    match op_name {
628
29328
        "MkOpNot" => Some(Expression::Not),
629
27408
        "MkOpNegate" => Some(Expression::Neg),
630
18648
        "MkOpTwoBars" => Some(Expression::Abs),
631
18048
        "MkOpAnd" => Some(Expression::And),
632
14104
        "MkOpSum" => Some(Expression::Sum),
633
8568
        "MkOpProduct" => Some(Expression::Product),
634
7128
        "MkOpOr" => Some(Expression::Or),
635
4360
        "MkOpMin" => Some(Expression::Min),
636
3320
        "MkOpMax" => Some(Expression::Max),
637
2320
        "MkOpAllDiff" => Some(Expression::AllDiff),
638
320
        "MkOpToInt" => Some(Expression::ToInt),
639
160
        "MkOpDefined" => Some(Expression::Defined),
640
80
        "MkOpRange" => Some(Expression::Range),
641
        _ => None,
642
    }
643
29328
}
644

            
645
149836
pub fn parse_expression(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<Expression> {
646
149836
    let fail = |stage: &str| -> Error {
647
520
        Error::Parse(format!(
648
520
            "Could not parse expression at stage `{stage}` for json `{obj}`"
649
520
        ))
650
520
    };
651

            
652
360
    match obj {
653
149636
        Value::Object(op) if op.contains_key("Op") => {
654
38400
            let op_obj = op
655
38400
                .get("Op")
656
38400
                .and_then(Value::as_object)
657
38400
                .ok_or_else(|| fail("Op.as_object"))?;
658
38400
            let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
659

            
660
38400
            if op_obj.contains_key("MkOpFlatten") {
661
200
                parse_flatten_op(op_obj, scope)
662
38200
            } else if op_obj.contains_key("MkOpTable") {
663
60
                parse_table_op(op_obj, scope)
664
38140
            } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
665
5824
                parse_indexing_slicing_op(op_obj, scope)
666
32316
            } else if binary_operator(op_name).is_some() {
667
17652
                parse_bin_op(op_obj, scope)
668
14664
            } else if unary_operator(op_name).is_some() {
669
14664
                parse_unary_op(op_obj, scope)
670
            } else {
671
                Err(fail("Op.unknown"))
672
            }
673
        }
674
111236
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
675
            parse_comprehension(comprehension, scope.clone(), None)
676
        }
677
111236
        Value::Object(refe) if refe.contains_key("Reference") => {
678
31270
            let ref_arr = refe["Reference"]
679
31270
                .as_array()
680
31270
                .ok_or_else(|| fail("Reference.as_array"))?;
681
31270
            let ref_obj = ref_arr
682
31270
                .first()
683
31270
                .and_then(|x| x.as_object())
684
31270
                .ok_or_else(|| fail("Reference[0].as_object"))?;
685
31270
            let name = ref_obj
686
31270
                .get("Name")
687
31270
                .and_then(|x| x.as_str())
688
31270
                .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
689
31270
            let user_name = Name::User(Ustr::from(name));
690

            
691
31270
            let declaration: DeclarationPtr = scope
692
31270
                .read()
693
31270
                .lookup(&user_name)
694
31270
                .ok_or_else(|| fail("Reference.lookup"))?;
695

            
696
31270
            Ok(Expression::Atomic(
697
31270
                Metadata::new(),
698
31270
                Atom::Reference(crate::ast::Reference::new(declaration)),
699
31270
            ))
700
        }
701
79966
        Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
702
6180
            let abstract_literal = abslit["AbstractLiteral"]
703
6180
                .as_object()
704
6180
                .ok_or_else(|| fail("AbstractLiteral.as_object"))?;
705

            
706
6180
            if abstract_literal.contains_key("AbsLitSet") {
707
40
                parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
708
6140
            } else if abstract_literal.contains_key("AbsLitFunction") {
709
40
                parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
710
6100
            } else if abstract_literal.contains_key("AbsLitMSet") {
711
                parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
712
            } else {
713
6100
                parse_abstract_matrix_as_expr(obj, scope)
714
            }
715
        }
716

            
717
73786
        Value::Object(constant) if constant.contains_key("Constant") => {
718
66046
            parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
719
        }
720

            
721
7740
        Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
722
340
            parse_abstract_matrix_as_expr(obj, scope)
723
        }
724

            
725
7400
        Value::Object(constant) if constant.contains_key("ConstantInt") => {
726
7040
            parse_constant(constant, scope)
727
        }
728
360
        Value::Object(constant) if constant.contains_key("ConstantBool") => {
729
40
            parse_constant(constant, scope)
730
        }
731

            
732
520
        _ => Err(fail("no_match")),
733
    }
734
149836
}
735

            
736
1200
fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
737
1200
    let values = abs_set
738
1200
        .as_array()
739
1200
        .ok_or(error!("AbsLitSet is not an array"))?;
740
1200
    let expressions = values
741
1200
        .iter()
742
3040
        .map(|values| parse_expression(values, scope))
743
1200
        .collect::<Result<Vec<_>>>()?;
744

            
745
1200
    Ok(Expression::AbstractLiteral(
746
1200
        Metadata::new(),
747
1200
        AbstractLiteral::Set(expressions),
748
1200
    ))
749
1200
}
750

            
751
40
fn parse_abs_mset(abs_mset: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
752
40
    let values = abs_mset
753
40
        .as_array()
754
40
        .ok_or(error!("AbsLitMSet is not an array"))?;
755
40
    let expressions = values
756
40
        .iter()
757
120
        .map(|values| parse_expression(values, scope))
758
40
        .collect::<Result<Vec<_>>>()?;
759

            
760
40
    Ok(Expression::AbstractLiteral(
761
40
        Metadata::new(),
762
40
        AbstractLiteral::MSet(expressions),
763
40
    ))
764
40
}
765

            
766
80
fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
767
80
    let values = abs_tuple
768
80
        .as_array()
769
80
        .ok_or(error!("AbsLitTuple is not an array"))?;
770
80
    let expressions = values
771
80
        .iter()
772
200
        .map(|values| parse_expression(values, scope))
773
80
        .collect::<Result<Vec<_>>>()?;
774

            
775
80
    Ok(Expression::AbstractLiteral(
776
80
        Metadata::new(),
777
80
        AbstractLiteral::Tuple(expressions),
778
80
    ))
779
80
}
780

            
781
//parses an abstract record as an expression
782
20
fn parse_abs_record(abs_record: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
783
20
    let entries = abs_record
784
20
        .as_array()
785
20
        .ok_or(error!("AbsLitRecord is not an array"))?;
786
20
    let mut rec = vec![];
787

            
788
40
    for entry in entries {
789
40
        let entry = entry
790
40
            .as_array()
791
40
            .ok_or(error!("AbsLitRecord entry is not an array"))?;
792
40
        let name = entry[0]
793
40
            .as_object()
794
40
            .ok_or(error!("AbsLitRecord field name is not an object"))?["Name"]
795
40
            .as_str()
796
40
            .ok_or(error!("AbsLitRecord field name is not a string"))?;
797

            
798
40
        let value = parse_expression(&entry[1], scope)?;
799

            
800
40
        let name = Name::User(Ustr::from(name));
801
40
        let rec_entry = RecordValue {
802
40
            name: name.clone(),
803
40
            value,
804
40
        };
805
40
        rec.push(rec_entry);
806
    }
807

            
808
20
    Ok(Expression::AbstractLiteral(
809
20
        Metadata::new(),
810
20
        AbstractLiteral::Record(rec),
811
20
    ))
812
20
}
813

            
814
//parses an abstract function as an expression
815
120
fn parse_abs_function(abs_function: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
816
120
    let entries = abs_function
817
120
        .as_array()
818
120
        .ok_or(error!("AbsLitFunction is not an array"))?;
819
120
    let mut assignments = vec![];
820

            
821
240
    for entry in entries {
822
240
        let entry = entry
823
240
            .as_array()
824
240
            .ok_or(error!("Explicit function assignment is not an array"))?;
825
240
        let expression = entry
826
240
            .iter()
827
480
            .map(|values| parse_expression(values, scope))
828
240
            .collect::<Result<Vec<_>>>()?;
829
240
        let domain_value = expression
830
240
            .first()
831
240
            .ok_or(error!("Invalid function domain"))?;
832
240
        let codomain_value = expression
833
240
            .get(1)
834
240
            .ok_or(error!("Invalid function codomain"))?;
835
240
        let tuple = (domain_value.clone(), codomain_value.clone());
836
240
        assignments.push(tuple);
837
    }
838
120
    Ok(Expression::AbstractLiteral(
839
120
        Metadata::new(),
840
120
        AbstractLiteral::Function(assignments),
841
120
    ))
842
120
}
843

            
844
2084
fn parse_comprehension(
845
2084
    comprehension: &serde_json::Map<String, Value>,
846
2084
    scope: SymbolTablePtr,
847
2084
    comprehension_kind: Option<ACOperatorKind>,
848
2084
) -> Result<Expression> {
849
2084
    let fail = |stage: &str| -> Error {
850
        Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
851
    };
852

            
853
2084
    let value = &comprehension["Comprehension"];
854
2084
    let mut comprehension = ComprehensionBuilder::new(scope.clone());
855
2084
    let generator_symboltable = comprehension.generator_symboltable();
856
2084
    let return_expr_symboltable = comprehension.return_expr_symboltable();
857

            
858
2084
    let generators_and_guards_array = value
859
2084
        .pointer("/1")
860
2084
        .and_then(Value::as_array)
861
2084
        .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
862
2084
    let generators_and_guards = generators_and_guards_array.iter();
863

            
864
2612
    for gen_or_guard in generators_and_guards {
865
2612
        let gen_or_guard_obj = gen_or_guard
866
2612
            .as_object()
867
2612
            .ok_or_else(|| fail("generator_or_guard.as_object"))?;
868
2612
        let (name, inner) = gen_or_guard_obj
869
2612
            .iter()
870
2612
            .next()
871
2612
            .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
872
2612
        comprehension = match name.as_str() {
873
2612
            "Generator" => {
874
                // TODO: more things than GenDomainNoRepr and Single names here?
875
2312
                let generator_obj = inner
876
2312
                    .as_object()
877
2312
                    .ok_or_else(|| fail("Generator.inner.as_object"))?;
878
2312
                let (name, gen_inner) = generator_obj
879
2312
                    .iter()
880
2312
                    .next()
881
2312
                    .ok_or_else(|| fail("Generator.inner.iter().next"))?;
882
2312
                match name.as_str() {
883
2312
                    "GenDomainNoRepr" => {
884
2292
                        let name = gen_inner
885
2292
                            .pointer("/0/Single/Name")
886
2292
                            .and_then(Value::as_str)
887
2292
                            .ok_or_else(|| {
888
                                fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
889
                            })?;
890
2292
                        let domain_obj = gen_inner
891
2292
                            .pointer("/1")
892
2292
                            .and_then(Value::as_object)
893
2292
                            .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
894
2292
                        let (domain_name, domain_value) = domain_obj
895
2292
                            .iter()
896
2292
                            .next()
897
2292
                            .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
898
2292
                        let domain = parse_domain(
899
2292
                            domain_name,
900
2292
                            domain_value,
901
2292
                            &mut generator_symboltable.write(),
902
                        )?;
903
2292
                        comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
904
                    }
905
                    // TODO: this is temporary until comprehensions support "in expr" generators
906
                    // currently only supports a single generator of this type
907
20
                    "GenInExpr" => return parse_in_expr_comprehension(scope, value, gen_inner),
908
                    _ => {
909
                        bug!("unknown generator type inside comprehension {name}");
910
                    }
911
                }
912
            }
913

            
914
300
            "Condition" => {
915
300
                let expr = parse_expression(inner, &generator_symboltable)
916
300
                    .map_err(|_| fail("Condition.parse_expression"))?;
917
300
                comprehension.guard(expr)
918
            }
919

            
920
            x => {
921
                bug!("unknown field inside comprehension {x}");
922
            }
923
        }
924
    }
925

            
926
2064
    let return_expr_value = value
927
2064
        .pointer("/0")
928
2064
        .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
929
2064
    let expr = parse_expression(return_expr_value, &return_expr_symboltable)
930
2064
        .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
931

            
932
2064
    Ok(Expression::Comprehension(
933
2064
        Metadata::new(),
934
2064
        Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
935
2064
    ))
936
2084
}
937

            
938
20
fn parse_in_expr_comprehension(
939
20
    scope: SymbolTablePtr,
940
20
    comprehension_value: &Value,
941
20
    gen_inner: &Value,
942
20
) -> Result<Expression> {
943
20
    let fail = |stage: &str| -> Error {
944
        Error::Parse(format!(
945
            "Could not parse GenInExpr comprehension at stage `{stage}`"
946
        ))
947
    };
948

            
949
20
    let name = gen_inner
950
20
        .pointer("/0/Single/Name")
951
20
        .and_then(Value::as_str)
952
20
        .ok_or_else(|| fail("GenInExpr.pointer(/0/Single/Name).as_str"))?;
953
20
    let generator_expr = gen_inner
954
20
        .pointer("/1")
955
20
        .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
956
20
    let expr =
957
20
        parse_expression(generator_expr, &scope).map_err(|_| fail("GenInExpr.parse_expression"))?;
958

            
959
20
    let comprehension =
960
20
        AbstractComprehensionBuilder::new(&scope).new_expression_generator(expr, name.into());
961
20
    let return_expr_value = comprehension_value
962
20
        .pointer("/0")
963
20
        .ok_or_else(|| fail("comprehension_value.pointer(/0)"))?;
964
20
    let expr = parse_expression(return_expr_value, &comprehension.return_expr_symbols())
965
20
        .map_err(|_| fail("GenInExpr.return_expr.parse_expression"))?;
966

            
967
20
    Ok(Expression::AbstractComprehension(
968
20
        Metadata::new(),
969
20
        Moo::new(comprehension.with_return_value(expr)),
970
20
    ))
971
20
}
972

            
973
17652
fn parse_bin_op(
974
17652
    bin_op: &serde_json::Map<String, Value>,
975
17652
    scope: &SymbolTablePtr,
976
17652
) -> Result<Expression> {
977
    // we know there is a single key value pair in this object
978
    // extract the value, ignore the key
979
17652
    let (key, value) = bin_op
980
17652
        .into_iter()
981
17652
        .next()
982
17652
        .ok_or(error!("Binary op object is empty"))?;
983

            
984
17652
    let constructor = binary_operator(key.as_str())
985
17652
        .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
986

            
987
17652
    match &value {
988
17652
        Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
989
17652
            let arg1 = parse_expression(&bin_op_args[0], scope)?;
990
17652
            let arg2 = parse_expression(&bin_op_args[1], scope)?;
991
17652
            Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
992
        }
993
        _ => Err(error!("Binary operator arguments are not a 2-array")),
994
    }
995
17652
}
996

            
997
60
fn parse_table_op(
998
60
    op: &serde_json::Map<String, Value>,
999
60
    scope: &SymbolTablePtr,
60
) -> Result<Expression> {
60
    let args = op
60
        .get("MkOpTable")
60
        .ok_or(error!("MkOpTable missing"))?
60
        .as_array()
60
        .ok_or(error!("MkOpTable is not an array"))?;
60
    if args.len() != 2 {
        return Err(error!("MkOpTable arguments are not a 2-array"));
60
    }
60
    let tuple_expr = parse_expression(&args[0], scope)?;
60
    let allowed_rows_expr = parse_expression(&args[1], scope)?;
60
    let (tuple_elems, _) = tuple_expr
60
        .clone()
60
        .unwrap_matrix_unchecked()
60
        .ok_or(error!("MkOpTable first argument is not a matrix"))?;
60
    let (allowed_rows, _) = allowed_rows_expr
60
        .clone()
60
        .unwrap_matrix_unchecked()
60
        .ok_or(error!("MkOpTable second argument is not a matrix"))?;
160
    for row_expr in allowed_rows {
160
        let (row_elems, _) = row_expr
160
            .unwrap_matrix_unchecked()
160
            .ok_or(error!("MkOpTable row is not a matrix"))?;
160
        if row_elems.len() != tuple_elems.len() {
            return Err(error!("MkOpTable row width does not match tuple width"));
160
        }
    }
60
    Ok(Expression::Table(
60
        Metadata::new(),
60
        Moo::new(tuple_expr),
60
        Moo::new(allowed_rows_expr),
60
    ))
60
}
5824
fn parse_indexing_slicing_op(
5824
    op: &serde_json::Map<String, Value>,
5824
    scope: &SymbolTablePtr,
5824
) -> Result<Expression> {
    // we know there is a single key value pair in this object
    // extract the value, ignore the key
5824
    let (key, value) = op
5824
        .into_iter()
5824
        .next()
5824
        .ok_or(error!("Indexing/Slicing op object is empty"))?;
    // we know that this is meant to be a mkopindexing, so anything that goes wrong from here is a
    // bug!
    // Conjure does a[1,2,3] as MkOpIndexing(MkOpIndexing(MkOpIndexing(a,3),2),1).
    //
    // And  a[1,..,3] as MkOpIndexing(MkOpSlicing(MkOpIndexing(a,3)),1).
    //
    // However, we want this in a flattened form: Index(a, [1,2,3])
    let mut target: Expression;
5824
    let mut indices: Vec<Option<Expression>> = vec![];
    // true if this has no slicing, false otherwise.
5824
    let mut all_known = true;
5824
    match key.as_str() {
5824
        "MkOpIndexing" => {
5104
            match &value {
5104
                Value::Array(op_args) if op_args.len() == 2 => {
5104
                    target = parse_expression(&op_args[0], scope)?;
5104
                    indices.push(Some(parse_expression(&op_args[1], scope)?));
                }
                _ => return Err(error!("Unknown object inside MkOpIndexing")),
            };
        }
720
        "MkOpSlicing" => {
720
            all_known = false;
720
            match &value {
720
                Value::Array(op_args) if op_args.len() == 3 => {
720
                    target = parse_expression(&op_args[0], scope)?;
720
                    indices.push(None);
                }
                _ => return Err(error!("Unknown object inside MkOpSlicing")),
            };
        }
        _ => return Err(error!("Unknown indexing/slicing operator")),
    }
    loop {
7524
        match &mut target {
1460
            Expression::UnsafeIndex(_, new_target, new_indices) => {
1460
                indices.extend(new_indices.iter().cloned().rev().map(Some));
1460
                target = Moo::unwrap_or_clone(new_target.clone());
1460
            }
240
            Expression::UnsafeSlice(_, new_target, new_indices) => {
240
                all_known = false;
240
                indices.extend(new_indices.iter().cloned().rev());
240
                target = Moo::unwrap_or_clone(new_target.clone());
240
            }
            _ => {
                // not a slice or an index, we have reached the target.
5824
                break;
            }
        }
    }
5824
    indices.reverse();
5824
    if all_known {
        Ok(Expression::UnsafeIndex(
4864
            Metadata::new(),
4864
            Moo::new(target),
4864
            indices
4864
                .into_iter()
4864
                .collect::<Option<Vec<_>>>()
4864
                .ok_or(error!("Missing index in fully-known indexing operation"))?,
        ))
    } else {
960
        Ok(Expression::UnsafeSlice(
960
            Metadata::new(),
960
            Moo::new(target),
960
            indices,
960
        ))
    }
5824
}
200
fn parse_flatten_op(
200
    op: &serde_json::Map<String, Value>,
200
    scope: &SymbolTablePtr,
200
) -> Result<Expression> {
200
    let args = op
200
        .get("MkOpFlatten")
200
        .ok_or(error!("MkOpFlatten missing"))?
200
        .as_array()
200
        .ok_or(error!("MkOpFlatten is not an array"))?;
200
    let first = args
200
        .first()
200
        .ok_or(error!("MkOpFlatten missing first argument"))?;
200
    let second = args
200
        .get(1)
200
        .ok_or(error!("MkOpFlatten missing second argument"))?;
200
    let n = parse_expression(first, scope).ok();
200
    let matrix = parse_expression(second, scope)?;
200
    if let Some(n) = n {
        Ok(Expression::Flatten(
            Metadata::new(),
            Some(Moo::new(n)),
            Moo::new(matrix),
        ))
    } else {
200
        Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
    }
200
}
14664
fn parse_unary_op(
14664
    un_op: &serde_json::Map<String, Value>,
14664
    scope: &SymbolTablePtr,
14664
) -> Result<Expression> {
14664
    let fail = |stage: &str| -> Error {
        Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
    };
14664
    let (key, value) = un_op
14664
        .iter()
14664
        .next()
14664
        .ok_or_else(|| fail("un_op.iter().next"))?;
14664
    let constructor = unary_operator(key.as_str()).ok_or_else(|| fail("unary_operator"))?;
    // unops are the main things that contain comprehensions
    //
    // if the current expr is a quantifier like and/or/sum and it contains a comprehension, let the comprehension know what it is inside.
14664
    let arg = match value {
14664
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
2084
            let comprehension_kind = match key.as_str() {
2084
                "MkOpOr" => Some(ACOperatorKind::Or),
1624
                "MkOpAnd" => Some(ACOperatorKind::And),
400
                "MkOpSum" => Some(ACOperatorKind::Sum),
100
                "MkOpProduct" => Some(ACOperatorKind::Product),
100
                _ => None,
            };
2084
            parse_comprehension(comprehension, scope.clone(), comprehension_kind)
2084
                .map_err(|_| fail("value.Comprehension.parse_comprehension"))
        }
12580
        _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
    }
14664
    .map_err(|_| fail("arg"))?;
14664
    Ok(constructor(Metadata::new(), Moo::new(arg)))
14664
}
// Takes in { AbstractLiteral: .... }
7400
fn parse_abstract_matrix_as_expr(
7400
    value: &serde_json::Value,
7400
    scope: &SymbolTablePtr,
7400
) -> Result<Expression> {
7400
    parser_trace!("trying to parse an abstract literal matrix");
6920
    let (values, domain_name, domain_value) =
7400
        if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
6100
            parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
6100
            let (domain_name, domain_value) = abs_lit_matrix
6100
                .pointer("/0")
6100
                .and_then(Value::as_object)
6100
                .and_then(|x| x.iter().next())
6100
                .ok_or(error!("AbsLitMatrix missing domain"))?;
6100
            let values = abs_lit_matrix
6100
                .pointer("/1")
6100
                .ok_or(error!("AbsLitMatrix missing values"))?;
6100
            Some((values, domain_name, domain_value))
        }
        // the input of this expression is constant - e.g. or([]), or([false]), min([2]), etc.
480
        else if let Some(const_abs_lit_matrix) =
1300
            value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
        {
480
            parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
480
            let (domain_name, domain_value) = const_abs_lit_matrix
480
                .pointer("/0")
480
                .and_then(Value::as_object)
480
                .and_then(|x| x.iter().next())
480
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
480
            let values = const_abs_lit_matrix
480
                .pointer("/1")
480
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
480
            Some((values, domain_name, domain_value))
820
        } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
340
            parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
340
            let (domain_name, domain_value) = const_abs_lit_matrix
340
                .pointer("/0")
340
                .and_then(Value::as_object)
340
                .and_then(|x| x.iter().next())
340
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
340
            let values = const_abs_lit_matrix
340
                .pointer("/1")
340
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
340
            Some((values, domain_name, domain_value))
        } else {
480
            None
        }
7400
        .ok_or(error!("Could not parse abstract literal matrix"))?;
6920
    parser_trace!(".. found in domain and values in JSON:");
6920
    parser_trace!(".. .. index domain name {domain_name}");
6920
    parser_trace!(".. .. values {value}");
6920
    let args_parsed = values
6920
        .as_array()
6920
        .ok_or(error!("Matrix values are not an array"))?
6920
        .iter()
14884
        .map(|x| parse_expression(x, scope))
6920
        .collect::<Result<Vec<Expression>>>()?;
6920
    if !args_parsed.is_empty() {
6900
        parser_trace!(
            ".. successfully parsed values as expressions: {}, ... ",
16
            args_parsed[0]
        );
    } else {
20
        parser_trace!(".. successfully parsed empty values ",);
    }
6920
    let mut symbols = scope.write();
6920
    match parse_domain(domain_name, domain_value, &mut symbols) {
6920
        Ok(domain) => {
6920
            parser_trace!("... sucessfully parsed domain as {domain}");
6920
            Ok(into_matrix_expr![args_parsed;domain])
        }
        Err(_) => {
            parser_trace!("... failed to parse domain, creating a matrix without one.");
            Ok(into_matrix_expr![args_parsed])
        }
    }
7400
}
73126
fn parse_constant(
73126
    constant: &serde_json::Map<String, Value>,
73126
    scope: &SymbolTablePtr,
73126
) -> Result<Expression> {
73126
    match &constant.get("Constant") {
66046
        Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
63606
            let int_32: i32 = match int["ConstantInt"]
63606
                .as_array()
63606
                .ok_or(error!("ConstantInt is not an array"))?[1]
63606
                .as_i64()
63606
                .ok_or(error!("ConstantInt does not contain int"))?
63606
                .try_into()
            {
63606
                Ok(x) => x,
                Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
            };
63606
            Ok(Expression::Atomic(
63606
                Metadata::new(),
63606
                Atom::Literal(Literal::Int(int_32)),
63606
            ))
        }
2440
        Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
580
            let b: bool = b["ConstantBool"]
580
                .as_bool()
580
                .ok_or(error!("ConstantBool does not contain bool"))?;
580
            Ok(Expression::Atomic(
580
                Metadata::new(),
580
                Atom::Literal(Literal::Bool(b)),
580
            ))
        }
1860
        Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
1860
            if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
1860
                if let Some(arr) = obj.get("AbsLitSet") {
1160
                    return parse_abs_lit(arr, scope);
700
                } else if let Some(arr) = obj.get("AbsLitMSet") {
40
                    return parse_abs_mset(arr, scope);
660
                } else if let Some(arr) = obj.get("AbsLitMatrix") {
480
                    return parse_abstract_matrix_as_expr(arr, scope);
180
                } else if let Some(arr) = obj.get("AbsLitTuple") {
80
                    return parse_abs_tuple(arr, scope);
100
                } else if let Some(arr) = obj.get("AbsLitRecord") {
20
                    return parse_abs_record(arr, scope);
80
                } else if let Some(arr) = obj.get("AbsLitFunction") {
80
                    return parse_abs_function(arr, scope);
                }
            }
            Err(error!("Unhandled ConstantAbstract literal type"))
        }
        // sometimes (e.g. constant matrices) we can have a ConstantInt / Constant bool that is
        // not wrapped in Constant
        None => {
7080
            let int_expr = constant
7080
                .get("ConstantInt")
7080
                .and_then(|x| x.as_array())
7080
                .and_then(|x| x[1].as_i64())
7080
                .and_then(|x| x.try_into().ok())
7080
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
7080
            if let Some(expr) = int_expr {
7040
                return Ok(expr);
40
            }
40
            let bool_expr = constant
40
                .get("ConstantBool")
40
                .and_then(|x| x.as_bool())
40
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
40
            if let Some(expr) = bool_expr {
40
                return Ok(expr);
            }
            Err(error!(format!("Unhandled parse_constant {constant:#?}")))
        }
        otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
    }
73126
}