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::ac_operators::ACOperatorKind;
12
use crate::ast::comprehension::ComprehensionBuilder;
13
use crate::ast::records::RecordValue;
14
use crate::ast::{
15
    AbstractLiteral, Atom, DeclarationPtr, Domain, Expression, FuncAttr, IntVal, JectivityAttr,
16
    Literal, MSetAttr, Name, PartialityAttr, Range, RecordEntry, SetAttr, SymbolTable,
17
    SymbolTablePtr,
18
};
19
use crate::ast::{DomainPtr, Metadata};
20
use crate::context::Context;
21
use crate::error::{Error, Result};
22
use crate::{Model, bug, error, into_matrix_expr, throw_error};
23

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

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

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

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

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

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

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

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

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

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

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

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

            
120
38922
    let name = Name::User(Ustr::from(name));
121

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

            
129
38922
    let domain = parse_domain(domain.0, domain.1, symtab)?;
130

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
280
4206
            let mut index_domains: Vec<DomainPtr> = vec![];
281

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

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

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

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

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

            
327
40
            let mut record_entries = vec![];
328

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

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

            
346
80
                let domain = parse_domain(domain.0, domain.1, symbols)?;
347

            
348
80
                let rec = RecordEntry { name, domain };
349

            
350
80
                record_entries.push(rec);
351
            }
352

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

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

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

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

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

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

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

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

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

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

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

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

            
575
111166
    if let Some(Literal::Int(i)) = expr.clone().into_literal() {
576
108342
        return Ok(IntVal::Const(i));
577
2824
    }
578

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

            
585
1188
    IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
586
111166
}
587

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

            
591
104632
fn binary_operator(op_name: &str) -> Option<BinOp> {
592
104632
    match op_name {
593
104632
        "MkOpIn" => Some(Expression::In),
594
103992
        "MkOpUnion" => Some(Expression::Union),
595
103712
        "MkOpIntersect" => Some(Expression::Intersect),
596
103452
        "MkOpSupset" => Some(Expression::Supset),
597
103132
        "MkOpSupsetEq" => Some(Expression::SupsetEq),
598
102812
        "MkOpSubset" => Some(Expression::Subset),
599
102412
        "MkOpSubsetEq" => Some(Expression::SubsetEq),
600
102056
        "MkOpEq" => Some(Expression::Eq),
601
75136
        "MkOpNeq" => Some(Expression::Neq),
602
69736
        "MkOpGeq" => Some(Expression::Geq),
603
65696
        "MkOpLeq" => Some(Expression::Leq),
604
58384
        "MkOpGt" => Some(Expression::Gt),
605
55572
        "MkOpLt" => Some(Expression::Lt),
606
51080
        "MkOpLexLt" => Some(Expression::LexLt),
607
50436
        "MkOpLexGt" => Some(Expression::LexGt),
608
50436
        "MkOpLexLeq" => Some(Expression::LexLeq),
609
49556
        "MkOpLexGeq" => Some(Expression::LexGeq),
610
49556
        "MkOpDiv" => Some(Expression::UnsafeDiv),
611
44836
        "MkOpMod" => Some(Expression::UnsafeMod),
612
42836
        "MkOpMinus" => Some(Expression::Minus),
613
39232
        "MkOpImply" => Some(Expression::Imply),
614
35328
        "MkOpIff" => Some(Expression::Iff),
615
34920
        "MkOpPow" => Some(Expression::UnsafePow),
616
32400
        "MkOpImage" => Some(Expression::Image),
617
32320
        "MkOpImageSet" => Some(Expression::ImageSet),
618
32240
        "MkOpPreImage" => Some(Expression::PreImage),
619
32160
        "MkOpInverse" => Some(Expression::Inverse),
620
32080
        "MkOpRestrict" => Some(Expression::Restrict),
621
32000
        _ => None,
622
    }
623
104632
}
624

            
625
64000
fn unary_operator(op_name: &str) -> Option<UnaryOp> {
626
64000
    match op_name {
627
64000
        "MkOpNot" => Some(Expression::Not),
628
60220
        "MkOpNegate" => Some(Expression::Neg),
629
40360
        "MkOpTwoBars" => Some(Expression::Abs),
630
39240
        "MkOpAnd" => Some(Expression::And),
631
31688
        "MkOpSum" => Some(Expression::Sum),
632
17420
        "MkOpProduct" => Some(Expression::Product),
633
14536
        "MkOpOr" => Some(Expression::Or),
634
8688
        "MkOpMin" => Some(Expression::Min),
635
6448
        "MkOpMax" => Some(Expression::Max),
636
4428
        "MkOpAllDiff" => Some(Expression::AllDiff),
637
536
        "MkOpToInt" => Some(Expression::ToInt),
638
160
        "MkOpDefined" => Some(Expression::Defined),
639
80
        "MkOpRange" => Some(Expression::Range),
640
        "MkOpFactorial" => Some(Expression::Factorial),
641
        _ => None,
642
    }
643
64000
}
644

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

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

            
660
79978
            if op_obj.contains_key("MkOpFlatten") {
661
384
                parse_flatten_op(op_obj, scope)
662
79594
            } else if op_obj.contains_key("MkOpTable") {
663
120
                parse_table_op(op_obj, scope)
664
79474
            } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
665
11158
                parse_indexing_slicing_op(op_obj, scope)
666
68316
            } else if binary_operator(op_name).is_some() {
667
36316
                parse_bin_op(op_obj, scope)
668
32000
            } else if unary_operator(op_name).is_some() {
669
32000
                parse_unary_op(op_obj, scope)
670
            } else {
671
                Err(fail("Op.unknown"))
672
            }
673
        }
674
230248
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
675
8
            parse_comprehension(comprehension, scope.clone(), None)
676
        }
677
230240
        Value::Object(refe) if refe.contains_key("Reference") => {
678
64480
            let ref_arr = refe["Reference"]
679
64480
                .as_array()
680
64480
                .ok_or_else(|| fail("Reference.as_array"))?;
681
64480
            let ref_obj = ref_arr
682
64480
                .first()
683
64480
                .and_then(|x| x.as_object())
684
64480
                .ok_or_else(|| fail("Reference[0].as_object"))?;
685
64480
            let name = ref_obj
686
64480
                .get("Name")
687
64480
                .and_then(|x| x.as_str())
688
64480
                .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
689
64480
            let user_name = Name::User(Ustr::from(name));
690

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

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

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

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

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

            
725
14532
        Value::Object(constant) if constant.contains_key("ConstantInt") => {
726
13890
            parse_constant(constant, scope)
727
        }
728
642
        Value::Object(constant) if constant.contains_key("ConstantBool") => {
729
80
            parse_constant(constant, scope)
730
        }
731

            
732
946
        _ => Err(fail("no_match")),
733
    }
734
310610
}
735

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

            
745
2288
    Ok(Expression::AbstractLiteral(
746
2288
        Metadata::new(),
747
2288
        AbstractLiteral::Set(expressions),
748
2288
    ))
749
2288
}
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
160
fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
767
160
    let values = abs_tuple
768
160
        .as_array()
769
160
        .ok_or(error!("AbsLitTuple is not an array"))?;
770
160
    let expressions = values
771
160
        .iter()
772
400
        .map(|values| parse_expression(values, scope))
773
160
        .collect::<Result<Vec<_>>>()?;
774

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

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

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

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

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

            
808
40
    Ok(Expression::AbstractLiteral(
809
40
        Metadata::new(),
810
40
        AbstractLiteral::Record(rec),
811
40
    ))
812
40
}
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
4216
fn parse_comprehension(
845
4216
    comprehension: &serde_json::Map<String, Value>,
846
4216
    scope: SymbolTablePtr,
847
4216
    comprehension_kind: Option<ACOperatorKind>,
848
4216
) -> Result<Expression> {
849
4216
    let fail = |stage: &str| -> Error {
850
        Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
851
    };
852

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

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

            
864
5130
    for gen_or_guard in generators_and_guards {
865
5130
        let gen_or_guard_obj = gen_or_guard
866
5130
            .as_object()
867
5130
            .ok_or_else(|| fail("generator_or_guard.as_object"))?;
868
5130
        let (name, inner) = gen_or_guard_obj
869
5130
            .iter()
870
5130
            .next()
871
5130
            .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
872
5130
        comprehension = match name.as_str() {
873
5130
            "Generator" => {
874
                // TODO: more things than GenDomainNoRepr and Single names here?
875
4590
                let generator_obj = inner
876
4590
                    .as_object()
877
4590
                    .ok_or_else(|| fail("Generator.inner.as_object"))?;
878
4590
                let (name, gen_inner) = generator_obj
879
4590
                    .iter()
880
4590
                    .next()
881
4590
                    .ok_or_else(|| fail("Generator.inner.iter().next"))?;
882
4590
                match name.as_str() {
883
4590
                    "GenDomainNoRepr" => {
884
4536
                        let name = gen_inner
885
4536
                            .pointer("/0/Single/Name")
886
4536
                            .and_then(Value::as_str)
887
4536
                            .ok_or_else(|| {
888
                                fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
889
                            })?;
890
4536
                        let domain_obj = gen_inner
891
4536
                            .pointer("/1")
892
4536
                            .and_then(Value::as_object)
893
4536
                            .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
894
4536
                        let (domain_name, domain_value) = domain_obj
895
4536
                            .iter()
896
4536
                            .next()
897
4536
                            .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
898
4536
                        let domain = parse_domain(
899
4536
                            domain_name,
900
4536
                            domain_value,
901
4536
                            &mut generator_symboltable.write(),
902
                        )?;
903
4536
                        comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
904
                    }
905
54
                    "GenInExpr" => {
906
54
                        let name = gen_inner
907
54
                            .pointer("/0/Single/Name")
908
54
                            .and_then(Value::as_str)
909
54
                            .ok_or_else(|| {
910
                                fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
911
                            })?;
912
54
                        let generator_expr = gen_inner
913
54
                            .pointer("/1")
914
54
                            .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
915
54
                        let expr = parse_expression(generator_expr, &scope)
916
54
                            .map_err(|_| fail("GenInExpr.parse_expression"))?;
917
54
                        comprehension.expression_generator(name.into(), expr)
918
                    }
919
                    _ => {
920
                        bug!("unknown generator type inside comprehension {name}");
921
                    }
922
                }
923
            }
924

            
925
540
            "Condition" => {
926
540
                let expr = parse_expression(inner, &generator_symboltable)
927
540
                    .map_err(|_| fail("Condition.parse_expression"))?;
928
540
                comprehension.guard(expr)
929
            }
930

            
931
            x => {
932
                bug!("unknown field inside comprehension {x}");
933
            }
934
        }
935
    }
936

            
937
4216
    let return_expr_value = value
938
4216
        .pointer("/0")
939
4216
        .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
940
4216
    let expr = parse_expression(return_expr_value, &return_expr_symboltable)
941
4216
        .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
942

            
943
4216
    Ok(Expression::Comprehension(
944
4216
        Metadata::new(),
945
4216
        Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
946
4216
    ))
947
4216
}
948

            
949
36316
fn parse_bin_op(
950
36316
    bin_op: &serde_json::Map<String, Value>,
951
36316
    scope: &SymbolTablePtr,
952
36316
) -> Result<Expression> {
953
    // we know there is a single key value pair in this object
954
    // extract the value, ignore the key
955
36316
    let (key, value) = bin_op
956
36316
        .into_iter()
957
36316
        .next()
958
36316
        .ok_or(error!("Binary op object is empty"))?;
959

            
960
36316
    let constructor = binary_operator(key.as_str())
961
36316
        .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
962

            
963
36316
    match &value {
964
36316
        Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
965
36316
            let arg1 = parse_expression(&bin_op_args[0], scope)?;
966
36316
            let arg2 = parse_expression(&bin_op_args[1], scope)?;
967
36316
            Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
968
        }
969
        _ => Err(error!("Binary operator arguments are not a 2-array")),
970
    }
971
36316
}
972

            
973
120
fn parse_table_op(
974
120
    op: &serde_json::Map<String, Value>,
975
120
    scope: &SymbolTablePtr,
976
120
) -> Result<Expression> {
977
120
    let args = op
978
120
        .get("MkOpTable")
979
120
        .ok_or(error!("MkOpTable missing"))?
980
120
        .as_array()
981
120
        .ok_or(error!("MkOpTable is not an array"))?;
982

            
983
120
    if args.len() != 2 {
984
        return Err(error!("MkOpTable arguments are not a 2-array"));
985
120
    }
986

            
987
120
    let tuple_expr = parse_expression(&args[0], scope)?;
988
120
    let allowed_rows_expr = parse_expression(&args[1], scope)?;
989

            
990
120
    let (tuple_elems, _) = tuple_expr
991
120
        .clone()
992
120
        .unwrap_matrix_unchecked()
993
120
        .ok_or(error!("MkOpTable first argument is not a matrix"))?;
994
120
    let (allowed_rows, _) = allowed_rows_expr
995
120
        .clone()
996
120
        .unwrap_matrix_unchecked()
997
120
        .ok_or(error!("MkOpTable second argument is not a matrix"))?;
998

            
999
320
    for row_expr in allowed_rows {
320
        let (row_elems, _) = row_expr
320
            .unwrap_matrix_unchecked()
320
            .ok_or(error!("MkOpTable row is not a matrix"))?;
320
        if row_elems.len() != tuple_elems.len() {
            return Err(error!("MkOpTable row width does not match tuple width"));
320
        }
    }
120
    Ok(Expression::Table(
120
        Metadata::new(),
120
        Moo::new(tuple_expr),
120
        Moo::new(allowed_rows_expr),
120
    ))
120
}
11158
fn parse_indexing_slicing_op(
11158
    op: &serde_json::Map<String, Value>,
11158
    scope: &SymbolTablePtr,
11158
) -> Result<Expression> {
    // we know there is a single key value pair in this object
    // extract the value, ignore the key
11158
    let (key, value) = op
11158
        .into_iter()
11158
        .next()
11158
        .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;
11158
    let mut indices: Vec<Option<Expression>> = vec![];
    // true if this has no slicing, false otherwise.
11158
    let mut all_known = true;
11158
    match key.as_str() {
11158
        "MkOpIndexing" => {
9798
            match &value {
9798
                Value::Array(op_args) if op_args.len() == 2 => {
9798
                    target = parse_expression(&op_args[0], scope)?;
9798
                    indices.push(Some(parse_expression(&op_args[1], scope)?));
                }
                _ => return Err(error!("Unknown object inside MkOpIndexing")),
            };
        }
1360
        "MkOpSlicing" => {
1360
            all_known = false;
1360
            match &value {
1360
                Value::Array(op_args) if op_args.len() == 3 => {
1360
                    target = parse_expression(&op_args[0], scope)?;
1360
                    indices.push(None);
                }
                _ => return Err(error!("Unknown object inside MkOpSlicing")),
            };
        }
        _ => return Err(error!("Unknown indexing/slicing operator")),
    }
    loop {
14440
        match &mut target {
2802
            Expression::UnsafeIndex(_, new_target, new_indices) => {
2802
                indices.extend(new_indices.iter().cloned().rev().map(Some));
2802
                target = Moo::unwrap_or_clone(new_target.clone());
2802
            }
480
            Expression::UnsafeSlice(_, new_target, new_indices) => {
480
                all_known = false;
480
                indices.extend(new_indices.iter().cloned().rev());
480
                target = Moo::unwrap_or_clone(new_target.clone());
480
            }
            _ => {
                // not a slice or an index, we have reached the target.
11158
                break;
            }
        }
    }
11158
    indices.reverse();
11158
    if all_known {
        Ok(Expression::UnsafeIndex(
9318
            Metadata::new(),
9318
            Moo::new(target),
9318
            indices
9318
                .into_iter()
9318
                .collect::<Option<Vec<_>>>()
9318
                .ok_or(error!("Missing index in fully-known indexing operation"))?,
        ))
    } else {
1840
        Ok(Expression::UnsafeSlice(
1840
            Metadata::new(),
1840
            Moo::new(target),
1840
            indices,
1840
        ))
    }
11158
}
384
fn parse_flatten_op(
384
    op: &serde_json::Map<String, Value>,
384
    scope: &SymbolTablePtr,
384
) -> Result<Expression> {
384
    let args = op
384
        .get("MkOpFlatten")
384
        .ok_or(error!("MkOpFlatten missing"))?
384
        .as_array()
384
        .ok_or(error!("MkOpFlatten is not an array"))?;
384
    let first = args
384
        .first()
384
        .ok_or(error!("MkOpFlatten missing first argument"))?;
384
    let second = args
384
        .get(1)
384
        .ok_or(error!("MkOpFlatten missing second argument"))?;
384
    let n = parse_expression(first, scope).ok();
384
    let matrix = parse_expression(second, scope)?;
384
    if let Some(n) = n {
        Ok(Expression::Flatten(
            Metadata::new(),
            Some(Moo::new(n)),
            Moo::new(matrix),
        ))
    } else {
384
        Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
    }
384
}
32000
fn parse_unary_op(
32000
    un_op: &serde_json::Map<String, Value>,
32000
    scope: &SymbolTablePtr,
32000
) -> Result<Expression> {
32000
    let fail = |stage: &str| -> Error {
        Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
    };
32000
    let (key, value) = un_op
32000
        .iter()
32000
        .next()
32000
        .ok_or_else(|| fail("un_op.iter().next"))?;
32000
    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.
32000
    let arg = match value {
32000
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
4208
            let comprehension_kind = match key.as_str() {
4208
                "MkOpOr" => Some(ACOperatorKind::Or),
3024
                "MkOpAnd" => Some(ACOperatorKind::And),
766
                "MkOpSum" => Some(ACOperatorKind::Sum),
210
                "MkOpProduct" => Some(ACOperatorKind::Product),
210
                _ => None,
            };
4208
            parse_comprehension(comprehension, scope.clone(), comprehension_kind)
4208
                .map_err(|_| fail("value.Comprehension.parse_comprehension"))
        }
27792
        _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
    }
32000
    .map_err(|_| fail("arg"))?;
32000
    Ok(constructor(Metadata::new(), Moo::new(arg)))
32000
}
// Takes in { AbstractLiteral: .... }
16512
fn parse_abstract_matrix_as_expr(
16512
    value: &serde_json::Value,
16512
    scope: &SymbolTablePtr,
16512
) -> Result<Expression> {
16512
    parser_trace!("trying to parse an abstract literal matrix");
15532
    let (values, domain_name, domain_value) =
16512
        if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
13802
            parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
13802
            let (domain_name, domain_value) = abs_lit_matrix
13802
                .pointer("/0")
13802
                .and_then(Value::as_object)
13802
                .and_then(|x| x.iter().next())
13802
                .ok_or(error!("AbsLitMatrix missing domain"))?;
13802
            let values = abs_lit_matrix
13802
                .pointer("/1")
13802
                .ok_or(error!("AbsLitMatrix missing values"))?;
13802
            Some((values, domain_name, domain_value))
        }
        // the input of this expression is constant - e.g. or([]), or([false]), min([2]), etc.
980
        else if let Some(const_abs_lit_matrix) =
2710
            value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
        {
980
            parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
980
            let (domain_name, domain_value) = const_abs_lit_matrix
980
                .pointer("/0")
980
                .and_then(Value::as_object)
980
                .and_then(|x| x.iter().next())
980
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
980
            let values = const_abs_lit_matrix
980
                .pointer("/1")
980
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
980
            Some((values, domain_name, domain_value))
1730
        } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
750
            parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
750
            let (domain_name, domain_value) = const_abs_lit_matrix
750
                .pointer("/0")
750
                .and_then(Value::as_object)
750
                .and_then(|x| x.iter().next())
750
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
750
            let values = const_abs_lit_matrix
750
                .pointer("/1")
750
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
750
            Some((values, domain_name, domain_value))
        } else {
980
            None
        }
16512
        .ok_or(error!("Could not parse abstract literal matrix"))?;
15532
    parser_trace!(".. found in domain and values in JSON:");
15532
    parser_trace!(".. .. index domain name {domain_name}");
15532
    parser_trace!(".. .. values {value}");
15532
    let args_parsed = values
15532
        .as_array()
15532
        .ok_or(error!("Matrix values are not an array"))?
15532
        .iter()
33354
        .map(|x| parse_expression(x, scope))
15532
        .collect::<Result<Vec<Expression>>>()?;
15532
    if !args_parsed.is_empty() {
15492
        parser_trace!(
            ".. successfully parsed values as expressions: {}, ... ",
64
            args_parsed[0]
        );
    } else {
40
        parser_trace!(".. successfully parsed empty values ",);
    }
15532
    let mut symbols = scope.write();
15532
    match parse_domain(domain_name, domain_value, &mut symbols) {
15532
        Ok(domain) => {
15532
            parser_trace!("... sucessfully parsed domain as {domain}");
15532
            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])
        }
    }
16512
}
150526
fn parse_constant(
150526
    constant: &serde_json::Map<String, Value>,
150526
    scope: &SymbolTablePtr,
150526
) -> Result<Expression> {
150526
    match &constant.get("Constant") {
136556
        Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
132106
            let int_32: i32 = match int["ConstantInt"]
132106
                .as_array()
132106
                .ok_or(error!("ConstantInt is not an array"))?[1]
132106
                .as_i64()
132106
                .ok_or(error!("ConstantInt does not contain int"))?
132106
                .try_into()
            {
132106
                Ok(x) => x,
                Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
            };
132106
            Ok(Expression::Atomic(
132106
                Metadata::new(),
132106
                Atom::Literal(Literal::Int(int_32)),
132106
            ))
        }
4450
        Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
942
            let b: bool = b["ConstantBool"]
942
                .as_bool()
942
                .ok_or(error!("ConstantBool does not contain bool"))?;
942
            Ok(Expression::Atomic(
942
                Metadata::new(),
942
                Atom::Literal(Literal::Bool(b)),
942
            ))
        }
3508
        Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
3508
            if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
3508
                if let Some(arr) = obj.get("AbsLitSet") {
2208
                    return parse_abs_lit(arr, scope);
1300
                } else if let Some(arr) = obj.get("AbsLitMSet") {
40
                    return parse_abs_mset(arr, scope);
1260
                } else if let Some(arr) = obj.get("AbsLitMatrix") {
980
                    return parse_abstract_matrix_as_expr(arr, scope);
280
                } else if let Some(arr) = obj.get("AbsLitTuple") {
160
                    return parse_abs_tuple(arr, scope);
120
                } else if let Some(arr) = obj.get("AbsLitRecord") {
40
                    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 => {
13970
            let int_expr = constant
13970
                .get("ConstantInt")
13970
                .and_then(|x| x.as_array())
13970
                .and_then(|x| x[1].as_i64())
13970
                .and_then(|x| x.try_into().ok())
13970
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
13970
            if let Some(expr) = int_expr {
13890
                return Ok(expr);
80
            }
80
            let bool_expr = constant
80
                .get("ConstantBool")
80
                .and_then(|x| x.as_bool())
80
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
80
            if let Some(expr) = bool_expr {
80
                return Ok(expr);
            }
            Err(error!(format!("Unhandled parse_constant {constant:#?}")))
        }
        otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
    }
150526
}