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

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

            
54
38502
        match entry.0.as_str() {
55
38502
            "Declaration" => {
56
26711
                let decl = entry
57
26711
                    .1
58
26711
                    .as_object()
59
26711
                    .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
26711
                let mut valid_decl: bool = false;
68
26711
                let scope = m.symbols_ptr_unchecked().clone();
69
26711
                let model = &mut m;
70
26711
                for (kind, value) in decl {
71
26711
                    match kind.as_str() {
72
26711
                        "FindOrGiven" => {
73
23353
                            parse_variable(value, &mut model.symbols_mut())?;
74
23353
                            valid_decl = true;
75
23353
                            break;
76
                        }
77
3358
                        "Letting" => {
78
3358
                            parse_letting(value, &scope)?;
79
3358
                            valid_decl = true;
80
3358
                            break;
81
                        }
82
                        _ => continue,
83
                    }
84
                }
85

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

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

            
108
23353
fn parse_variable(v: &JsonValue, symtab: &mut SymbolTable) -> Result<()> {
109
23353
    let arr = v.as_array().ok_or(error!("FindOrGiven is not an array"))?;
110
23353
    let name = arr[1]
111
23353
        .as_object()
112
23353
        .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
113
23353
        .as_str()
114
23353
        .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
115

            
116
23353
    let name = Name::User(Ustr::from(name));
117

            
118
23353
    let domain = arr[2]
119
23353
        .as_object()
120
23353
        .ok_or(error!("FindOrGiven[2] is not an object"))?
121
23353
        .iter()
122
23353
        .next()
123
23353
        .ok_or(error!("FindOrGiven[2] is an empty object"))?;
124

            
125
23353
    let domain = parse_domain(domain.0, domain.1, symtab)?;
126

            
127
23353
    symtab
128
23353
        .insert(DeclarationPtr::new_find(name.clone(), domain))
129
23353
        .ok_or(Error::Parse(format!(
130
23353
            "Could not add {name} to symbol table as it already exists"
131
23353
        )))
132
23353
}
133

            
134
3358
fn parse_letting(v: &JsonValue, scope: &SymbolTablePtr) -> Result<()> {
135
3358
    let arr = v.as_array().ok_or(error!("Letting is not an array"))?;
136
3358
    let name = arr[0]
137
3358
        .as_object()
138
3358
        .ok_or(error!("Letting[0] is not an object"))?["Name"]
139
3358
        .as_str()
140
3358
        .ok_or(error!("Letting[0].Name is not a string"))?;
141
3358
    let name = Name::User(Ustr::from(name));
142
    // value letting
143
3358
    if let Ok(value) = parse_expression(&arr[1], scope) {
144
2772
        let mut symtab = scope.write();
145
2772
        symtab
146
2772
            .insert(DeclarationPtr::new_value_letting(name.clone(), value))
147
2772
            .ok_or(Error::Parse(format!(
148
2772
                "Could not add {name} to symbol table as it already exists"
149
2772
            )))
150
    } else {
151
        // domain letting
152
586
        let domain = &arr[1]
153
586
            .as_object()
154
586
            .ok_or(error!("Letting[1] is not an object".to_owned()))?["Domain"]
155
586
            .as_object()
156
586
            .ok_or(error!("Letting[1].Domain is not an object"))?
157
586
            .iter()
158
586
            .next()
159
586
            .ok_or(error!("Letting[1].Domain is an empty object"))?;
160

            
161
586
        let mut symtab = scope.write();
162
586
        let domain = parse_domain(domain.0, domain.1, &mut symtab)?;
163

            
164
586
        symtab
165
586
            .insert(DeclarationPtr::new_domain_letting(name.clone(), domain))
166
586
            .ok_or(Error::Parse(format!(
167
586
                "Could not add {name} to symbol table as it already exists"
168
586
            )))
169
    }
170
3358
}
171

            
172
48353
fn parse_domain(
173
48353
    domain_name: &str,
174
48353
    domain_value: &JsonValue,
175
48353
    symbols: &mut SymbolTable,
176
48353
) -> Result<DomainPtr> {
177
48353
    match domain_name {
178
48353
        "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
179
12233
        "DomainBool" => Ok(Domain::bool()),
180
6850
        "DomainReference" => {
181
1248
            let name = Name::user(
182
1248
                domain_value
183
1248
                    .as_array()
184
1248
                    .ok_or(error!("DomainReference is not an array"))?[0]
185
1248
                    .as_object()
186
1248
                    .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
187
1248
                    .as_str()
188
1248
                    .ok_or(error!("DomainReference[0].Name is not a string"))?,
189
            );
190
1248
            let ptr = symbols
191
1248
                .lookup(&name)
192
1248
                .ok_or(error!(format!("Name {name} not found")))?;
193
1248
            let dom =
194
1248
                Domain::reference(ptr).ok_or(error!("Could not construct reference domain"))?;
195
1248
            Ok(dom)
196
        }
197
5602
        "DomainSet" => {
198
315
            let dom = domain_value.get(2).and_then(|v| v.as_object());
199
315
            let domain_obj = dom.ok_or(error!("DomainSet is missing domain object"))?;
200
315
            let domain = domain_obj
201
315
                .iter()
202
315
                .next()
203
315
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
204
315
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
205
315
            let size = domain_value
206
315
                .get(1)
207
315
                .and_then(|v| v.as_object())
208
315
                .ok_or(error!("Set size attributes is not an object"))?;
209
315
            let size = parse_size_attr(size, symbols)?;
210
315
            let attr: SetAttr<IntVal> = SetAttr { size };
211
315
            Ok(Domain::set(attr, domain))
212
        }
213
5287
        "DomainMSet" => {
214
360
            let dom = domain_value
215
360
                .get(2)
216
360
                .and_then(|v| v.as_object())
217
360
                .expect("domain object exists");
218
360
            let domain = dom
219
360
                .iter()
220
360
                .next()
221
360
                .ok_or(Error::Parse("DomainMSet is an empty object".to_owned()))?;
222
360
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
223

            
224
            // Parse Attributes
225
360
            let attributes = domain_value
226
360
                .get(1)
227
360
                .and_then(|v| v.as_array())
228
360
                .ok_or(error!("MSet attributes is not a json array"))?;
229

            
230
360
            let size = attributes
231
360
                .first()
232
360
                .and_then(|v| v.as_object())
233
360
                .ok_or(error!("MSet size attributes is not an object"))?;
234
360
            let size = parse_size_attr(size, symbols)?;
235

            
236
360
            let occurrence = attributes
237
360
                .get(1)
238
360
                .and_then(|v| v.as_object())
239
360
                .ok_or(error!("MSet occurrence attributes is not an object"))?;
240
360
            let occurrence = parse_occur_attr(occurrence, symbols)?;
241

            
242
360
            let attr: MSetAttr<IntVal> = MSetAttr { size, occurrence };
243
360
            Ok(Domain::mset(attr, domain))
244
        }
245

            
246
4927
        "DomainMatrix" => {
247
4095
            let domain_value = domain_value
248
4095
                .as_array()
249
4095
                .ok_or(error!("Domain matrix is not an array"))?;
250

            
251
4095
            let indexed_by_domain = domain_value[0].clone();
252
4095
            let (index_domain_name, index_domain_value) = indexed_by_domain
253
4095
                .as_object()
254
4095
                .ok_or(error!("DomainMatrix[0] is not an object"))?
255
4095
                .iter()
256
4095
                .next()
257
4095
                .ok_or(error!(""))?;
258

            
259
4095
            let (value_domain_name, value_domain_value) = domain_value[1]
260
4095
                .as_object()
261
4095
                .ok_or(error!(""))?
262
4095
                .iter()
263
4095
                .next()
264
4095
                .ok_or(error!(""))?;
265

            
266
            // Conjure stores a 2-d matrix as a matrix of a matrix.
267
            //
268
            // Therefore, the index is always a Domain.
269

            
270
4095
            let mut index_domains: Vec<DomainPtr> = vec![];
271

            
272
4095
            index_domains.push(parse_domain(
273
4095
                index_domain_name,
274
4095
                index_domain_value,
275
4095
                symbols,
276
            )?);
277

            
278
            // We want to store 2-d matrices as a matrix with two index domains, not a matrix in a
279
            // matrix.
280
            //
281
            // Walk through the value domain until it is not a DomainMatrix, adding the index to
282
            // our list of indices.
283
4095
            let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
284
4719
            while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
285
624
                index_domains.append(&mut indices);
286
624
                value_domain = new_value_domain.clone()
287
            }
288

            
289
4095
            Ok(Domain::matrix(value_domain, index_domains))
290
        }
291
832
        "DomainTuple" => {
292
273
            let domain_value = domain_value
293
273
                .as_array()
294
273
                .ok_or(error!("Domain tuple is not an array"))?;
295

            
296
            //iterate through the array and parse each domain
297
273
            let domain = domain_value
298
273
                .iter()
299
546
                .map(|x| {
300
546
                    let domain = x
301
546
                        .as_object()
302
546
                        .ok_or(error!("DomainTuple[0] is not an object"))?
303
546
                        .iter()
304
546
                        .next()
305
546
                        .ok_or(error!("DomainTuple[0] is an empty object"))?;
306
546
                    parse_domain(domain.0, domain.1, symbols)
307
546
                })
308
273
                .collect::<Result<Vec<DomainPtr>>>()?;
309

            
310
273
            Ok(Domain::tuple(domain))
311
        }
312
559
        "DomainRecord" => {
313
39
            let domain_value = domain_value
314
39
                .as_array()
315
39
                .ok_or(error!("Domain Record is not a json array"))?;
316

            
317
39
            let mut record_entries = vec![];
318

            
319
78
            for item in domain_value {
320
                //collect the name of the record field
321
78
                let name = item[0]
322
78
                    .as_object()
323
78
                    .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
324
78
                    .as_str()
325
78
                    .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
326

            
327
78
                let name = Name::User(Ustr::from(name));
328
                // then collect the domain of the record field
329
78
                let domain = item[1]
330
78
                    .as_object()
331
78
                    .ok_or(error!("FindOrGiven[2] is not an object"))?
332
78
                    .iter()
333
78
                    .next()
334
78
                    .ok_or(error!("FindOrGiven[2] is an empty object"))?;
335

            
336
78
                let domain = parse_domain(domain.0, domain.1, symbols)?;
337

            
338
78
                let rec = RecordEntry { name, domain };
339

            
340
78
                record_entries.push(rec);
341
            }
342

            
343
            // add record fields to symbol table
344
78
            for decl in record_entries
345
39
                .iter()
346
39
                .cloned()
347
39
                .map(DeclarationPtr::new_record_field)
348
            {
349
78
                symbols.insert(decl).ok_or(error!(
350
                    "record field should not already be in the symbol table"
351
                ))?;
352
            }
353

            
354
39
            Ok(Domain::record(record_entries))
355
        }
356
520
        "DomainFunction" => {
357
520
            let domain = domain_value
358
520
                .get(2)
359
520
                .and_then(|v| v.as_object())
360
520
                .ok_or(error!("Function domain is not an object"))?;
361
520
            let domain = domain
362
520
                .iter()
363
520
                .next()
364
520
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
365
520
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
366

            
367
520
            let codomain = domain_value
368
520
                .get(3)
369
520
                .and_then(|v| v.as_object())
370
520
                .ok_or(error!("Function codomain is not an object"))?;
371
520
            let codomain = codomain
372
520
                .iter()
373
520
                .next()
374
520
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
375
520
            let codomain = parse_domain(codomain.0.as_str(), codomain.1, symbols)?;
376

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

            
412
520
            let attr: FuncAttr<IntVal> = FuncAttr {
413
520
                size,
414
520
                partiality,
415
520
                jectivity,
416
520
            };
417

            
418
520
            Ok(Domain::function(attr, domain, codomain))
419
        }
420
        _ => Err(Error::Parse(
421
            "FindOrGiven[2] is an unknown object".to_owned(), // consider covered
422
        )),
423
    }
424
48353
}
425

            
426
1195
fn parse_size_attr(
427
1195
    attr_map: &JsonMap<String, JsonValue>,
428
1195
    symbols: &mut SymbolTable,
429
1195
) -> Result<Range<IntVal>> {
430
1195
    let scope = SymbolTablePtr::new();
431
1195
    *scope.write() = symbols.clone();
432

            
433
1195
    let attr_obj = attr_map
434
1195
        .iter()
435
1195
        .next()
436
1195
        .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
437
1195
    match attr_obj.0.as_str() {
438
1195
        "SizeAttr_None" => Ok(Range::Unbounded),
439
635
        "SizeAttr_MinSize" => {
440
355
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
441
355
            Ok(Range::UnboundedR(size))
442
        }
443
280
        "SizeAttr_MaxSize" => {
444
80
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
445
80
            Ok(Range::UnboundedL(size))
446
        }
447
200
        "SizeAttr_MinMaxSize" => {
448
80
            let min_max = attr_obj
449
80
                .1
450
80
                .as_array()
451
80
                .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
452
80
            let min = min_max
453
80
                .first()
454
80
                .ok_or(error!("SizeAttr Min is not present"))?;
455
80
            let min_int = parse_expression_to_int_val(min, &scope)?;
456
80
            let max = min_max
457
80
                .get(1)
458
80
                .ok_or(error!("SizeAttr Max is not present"))?;
459
80
            let max_int = parse_expression_to_int_val(max, &scope)?;
460
80
            Ok(Range::Bounded(min_int, max_int))
461
        }
462
120
        "SizeAttr_Size" => {
463
120
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
464
120
            Ok(Range::Single(size))
465
        }
466
        _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
467
    }
468
1195
}
469

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

            
513
36120
fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<DomainPtr> {
514
36120
    let scope = SymbolTablePtr::new();
515
36120
    *scope.write() = symbols.clone();
516

            
517
36120
    let mut ranges = Vec::new();
518
36120
    let arr = v
519
36120
        .as_array()
520
36120
        .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
521
36120
        .as_array()
522
36120
        .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
523
37447
    for range in arr {
524
37447
        let range = range
525
37447
            .as_object()
526
37447
            .ok_or(error!("DomainInt[1] contains a non-object"))?
527
37447
            .iter()
528
37447
            .next()
529
37447
            .ok_or(error!("DomainInt[1] contains an empty object"))?;
530
37447
        match range.0.as_str() {
531
37447
            "RangeBounded" => {
532
35183
                let arr = range
533
35183
                    .1
534
35183
                    .as_array()
535
35183
                    .ok_or(error!("RangeBounded is not an array".to_owned()))?;
536
35183
                let mut nums = Vec::new();
537
70366
                for item in arr.iter() {
538
70366
                    let num = parse_expression_to_int_val(item, &scope)?;
539
70366
                    nums.push(num);
540
                }
541
35183
                let lower = nums
542
35183
                    .first()
543
35183
                    .cloned()
544
35183
                    .ok_or(error!("RangeBounded lower bound missing"))?;
545
35183
                let upper = nums
546
35183
                    .get(1)
547
35183
                    .cloned()
548
35183
                    .ok_or(error!("RangeBounded upper bound missing"))?;
549
35183
                ranges.push(Range::Bounded(lower, upper));
550
            }
551
2264
            "RangeSingle" => {
552
2264
                let num = parse_expression_to_int_val(range.1, &scope)?;
553
2264
                ranges.push(Range::Single(num));
554
            }
555
            _ => return throw_error!("DomainInt[1] contains an unknown object"),
556
        }
557
    }
558
36120
    Ok(Domain::int(ranges))
559
36120
}
560

            
561
73625
fn parse_expression_to_int_val(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<IntVal> {
562
73625
    parser_trace!("trying to parse domain value as expression: {}", obj);
563
73625
    let expr = parse_expression(obj, scope)?;
564

            
565
73625
    if let Some(Literal::Int(i)) = expr.clone().into_literal() {
566
71090
        return Ok(IntVal::Const(i));
567
2535
    }
568

            
569
1599
    if let Expression::Atomic(_, Atom::Reference(reference)) = &expr
570
1599
        && let Some(reference_val) = IntVal::new_ref(reference)
571
    {
572
1599
        return Ok(reference_val);
573
936
    }
574

            
575
936
    IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
576
73625
}
577

            
578
type BinOp = fn(Metadata, Moo<Expression>, Moo<Expression>) -> Expression;
579
type UnaryOp = fn(Metadata, Moo<Expression>) -> Expression;
580

            
581
72745
fn binary_operator(op_name: &str) -> Option<BinOp> {
582
72745
    match op_name {
583
72745
        "MkOpIn" => Some(Expression::In),
584
72195
        "MkOpUnion" => Some(Expression::Union),
585
71961
        "MkOpIntersect" => Some(Expression::Intersect),
586
71727
        "MkOpSupset" => Some(Expression::Supset),
587
71415
        "MkOpSupsetEq" => Some(Expression::SupsetEq),
588
71103
        "MkOpSubset" => Some(Expression::Subset),
589
70713
        "MkOpSubsetEq" => Some(Expression::SubsetEq),
590
70401
        "MkOpEq" => Some(Expression::Eq),
591
48939
        "MkOpNeq" => Some(Expression::Neq),
592
46213
        "MkOpGeq" => Some(Expression::Geq),
593
44693
        "MkOpLeq" => Some(Expression::Leq),
594
40989
        "MkOpGt" => Some(Expression::Gt),
595
39621
        "MkOpLt" => Some(Expression::Lt),
596
36925
        "MkOpLexLt" => Some(Expression::LexLt),
597
36301
        "MkOpLexGt" => Some(Expression::LexGt),
598
36301
        "MkOpLexLeq" => Some(Expression::LexLeq),
599
35365
        "MkOpLexGeq" => Some(Expression::LexGeq),
600
35365
        "MkOpDiv" => Some(Expression::UnsafeDiv),
601
32167
        "MkOpMod" => Some(Expression::UnsafeMod),
602
30217
        "MkOpMinus" => Some(Expression::Minus),
603
27253
        "MkOpImply" => Some(Expression::Imply),
604
24445
        "MkOpIff" => Some(Expression::Iff),
605
24055
        "MkOpPow" => Some(Expression::UnsafePow),
606
21637
        "MkOpImage" => Some(Expression::Image),
607
21557
        "MkOpImageSet" => Some(Expression::ImageSet),
608
21477
        "MkOpPreImage" => Some(Expression::PreImage),
609
21397
        "MkOpInverse" => Some(Expression::Inverse),
610
21317
        "MkOpRestrict" => Some(Expression::Restrict),
611
21237
        _ => None,
612
    }
613
72745
}
614

            
615
42474
fn unary_operator(op_name: &str) -> Option<UnaryOp> {
616
42474
    match op_name {
617
42474
        "MkOpNot" => Some(Expression::Not),
618
39978
        "MkOpNegate" => Some(Expression::Neg),
619
28946
        "MkOpTwoBars" => Some(Expression::Abs),
620
28008
        "MkOpAnd" => Some(Expression::And),
621
21066
        "MkOpSum" => Some(Expression::Sum),
622
11236
        "MkOpProduct" => Some(Expression::Product),
623
8506
        "MkOpOr" => Some(Expression::Or),
624
5776
        "MkOpMin" => Some(Expression::Min),
625
4918
        "MkOpMax" => Some(Expression::Max),
626
4372
        "MkOpAllDiff" => Some(Expression::AllDiff),
627
472
        "MkOpToInt" => Some(Expression::ToInt),
628
160
        "MkOpDefined" => Some(Expression::Defined),
629
80
        "MkOpRange" => Some(Expression::Range),
630
        _ => None,
631
    }
632
42474
}
633

            
634
218947
pub fn parse_expression(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<Expression> {
635
218947
    let fail = |stage: &str| -> Error {
636
976
        Error::Parse(format!(
637
976
            "Could not parse expression at stage `{stage}` for json `{obj}`"
638
976
        ))
639
976
    };
640

            
641
664
    match obj {
642
218557
        Value::Object(op) if op.contains_key("Op") => {
643
58379
            let op_obj = op
644
58379
                .get("Op")
645
58379
                .and_then(Value::as_object)
646
58379
                .ok_or_else(|| fail("Op.as_object"))?;
647
58379
            let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
648

            
649
58379
            if op_obj.contains_key("MkOpFlatten") {
650
390
                parse_flatten_op(op_obj, scope)
651
57989
            } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
652
10998
                parse_indexing_slicing_op(op_obj, scope)
653
46991
            } else if binary_operator(op_name).is_some() {
654
25754
                parse_bin_op(op_obj, scope)
655
21237
            } else if unary_operator(op_name).is_some() {
656
21237
                parse_unary_op(op_obj, scope)
657
            } else {
658
                Err(fail("Op.unknown"))
659
            }
660
        }
661
160178
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
662
            parse_comprehension(comprehension, scope.clone(), None)
663
        }
664
160178
        Value::Object(refe) if refe.contains_key("Reference") => {
665
44905
            let ref_arr = refe["Reference"]
666
44905
                .as_array()
667
44905
                .ok_or_else(|| fail("Reference.as_array"))?;
668
44905
            let ref_obj = ref_arr
669
44905
                .first()
670
44905
                .and_then(|x| x.as_object())
671
44905
                .ok_or_else(|| fail("Reference[0].as_object"))?;
672
44905
            let name = ref_obj
673
44905
                .get("Name")
674
44905
                .and_then(|x| x.as_str())
675
44905
                .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
676
44905
            let user_name = Name::User(Ustr::from(name));
677

            
678
44905
            let declaration: DeclarationPtr = scope
679
44905
                .read()
680
44905
                .lookup(&user_name)
681
44905
                .ok_or_else(|| fail("Reference.lookup"))?;
682

            
683
44905
            Ok(Expression::Atomic(
684
44905
                Metadata::new(),
685
44905
                Atom::Reference(crate::ast::Reference::new(declaration)),
686
44905
            ))
687
        }
688
115273
        Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
689
8855
            let abstract_literal = abslit["AbstractLiteral"]
690
8855
                .as_object()
691
8855
                .ok_or_else(|| fail("AbstractLiteral.as_object"))?;
692

            
693
8855
            if abstract_literal.contains_key("AbsLitSet") {
694
78
                parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
695
8777
            } else if abstract_literal.contains_key("AbsLitFunction") {
696
40
                parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
697
8737
            } else if abstract_literal.contains_key("AbsLitMSet") {
698
                parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
699
            } else {
700
8737
                parse_abstract_matrix_as_expr(obj, scope)
701
            }
702
        }
703

            
704
106418
        Value::Object(constant) if constant.contains_key("Constant") => {
705
93998
            parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
706
        }
707

            
708
12420
        Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
709
351
            parse_abstract_matrix_as_expr(obj, scope)
710
        }
711

            
712
12069
        Value::Object(constant) if constant.contains_key("ConstantInt") => {
713
11405
            parse_constant(constant, scope)
714
        }
715
664
        Value::Object(constant) if constant.contains_key("ConstantBool") => {
716
78
            parse_constant(constant, scope)
717
        }
718

            
719
976
        _ => Err(fail("no_match")),
720
    }
721
218947
}
722

            
723
2226
fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
724
2226
    let values = abs_set
725
2226
        .as_array()
726
2226
        .ok_or(error!("AbsLitSet is not an array"))?;
727
2226
    let expressions = values
728
2226
        .iter()
729
5700
        .map(|values| parse_expression(values, scope))
730
2226
        .collect::<Result<Vec<_>>>()?;
731

            
732
2226
    Ok(Expression::AbstractLiteral(
733
2226
        Metadata::new(),
734
2226
        AbstractLiteral::Set(expressions),
735
2226
    ))
736
2226
}
737

            
738
40
fn parse_abs_mset(abs_mset: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
739
40
    let values = abs_mset
740
40
        .as_array()
741
40
        .ok_or(error!("AbsLitMSet is not an array"))?;
742
40
    let expressions = values
743
40
        .iter()
744
120
        .map(|values| parse_expression(values, scope))
745
40
        .collect::<Result<Vec<_>>>()?;
746

            
747
40
    Ok(Expression::AbstractLiteral(
748
40
        Metadata::new(),
749
40
        AbstractLiteral::MSet(expressions),
750
40
    ))
751
40
}
752

            
753
156
fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
754
156
    let values = abs_tuple
755
156
        .as_array()
756
156
        .ok_or(error!("AbsLitTuple is not an array"))?;
757
156
    let expressions = values
758
156
        .iter()
759
390
        .map(|values| parse_expression(values, scope))
760
156
        .collect::<Result<Vec<_>>>()?;
761

            
762
156
    Ok(Expression::AbstractLiteral(
763
156
        Metadata::new(),
764
156
        AbstractLiteral::Tuple(expressions),
765
156
    ))
766
156
}
767

            
768
//parses an abstract record as an expression
769
39
fn parse_abs_record(abs_record: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
770
39
    let entries = abs_record
771
39
        .as_array()
772
39
        .ok_or(error!("AbsLitRecord is not an array"))?;
773
39
    let mut rec = vec![];
774

            
775
78
    for entry in entries {
776
78
        let entry = entry
777
78
            .as_array()
778
78
            .ok_or(error!("AbsLitRecord entry is not an array"))?;
779
78
        let name = entry[0]
780
78
            .as_object()
781
78
            .ok_or(error!("AbsLitRecord field name is not an object"))?["Name"]
782
78
            .as_str()
783
78
            .ok_or(error!("AbsLitRecord field name is not a string"))?;
784

            
785
78
        let value = parse_expression(&entry[1], scope)?;
786

            
787
78
        let name = Name::User(Ustr::from(name));
788
78
        let rec_entry = RecordValue {
789
78
            name: name.clone(),
790
78
            value,
791
78
        };
792
78
        rec.push(rec_entry);
793
    }
794

            
795
39
    Ok(Expression::AbstractLiteral(
796
39
        Metadata::new(),
797
39
        AbstractLiteral::Record(rec),
798
39
    ))
799
39
}
800

            
801
//parses an abstract function as an expression
802
120
fn parse_abs_function(abs_function: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
803
120
    let entries = abs_function
804
120
        .as_array()
805
120
        .ok_or(error!("AbsLitFunction is not an array"))?;
806
120
    let mut assignments = vec![];
807

            
808
240
    for entry in entries {
809
240
        let entry = entry
810
240
            .as_array()
811
240
            .ok_or(error!("Explicit function assignment is not an array"))?;
812
240
        let expression = entry
813
240
            .iter()
814
480
            .map(|values| parse_expression(values, scope))
815
240
            .collect::<Result<Vec<_>>>()?;
816
240
        let domain_value = expression
817
240
            .first()
818
240
            .ok_or(error!("Invalid function domain"))?;
819
240
        let codomain_value = expression
820
240
            .get(1)
821
240
            .ok_or(error!("Invalid function codomain"))?;
822
240
        let tuple = (domain_value.clone(), codomain_value.clone());
823
240
        assignments.push(tuple);
824
    }
825
120
    Ok(Expression::AbstractLiteral(
826
120
        Metadata::new(),
827
120
        AbstractLiteral::Function(assignments),
828
120
    ))
829
120
}
830

            
831
3588
fn parse_comprehension(
832
3588
    comprehension: &serde_json::Map<String, Value>,
833
3588
    scope: SymbolTablePtr,
834
3588
    comprehension_kind: Option<ACOperatorKind>,
835
3588
) -> Result<Expression> {
836
3588
    let fail = |stage: &str| -> Error {
837
        Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
838
    };
839

            
840
3588
    let value = &comprehension["Comprehension"];
841
3588
    let mut comprehension = ComprehensionBuilder::new(scope.clone());
842
3588
    let generator_symboltable = comprehension.generator_symboltable();
843
3588
    let return_expr_symboltable = comprehension.return_expr_symboltable();
844

            
845
3588
    let generators_and_guards_array = value
846
3588
        .pointer("/1")
847
3588
        .and_then(Value::as_array)
848
3588
        .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
849
3588
    let generators_and_guards = generators_and_guards_array.iter();
850

            
851
4602
    for gen_or_guard in generators_and_guards {
852
4602
        let gen_or_guard_obj = gen_or_guard
853
4602
            .as_object()
854
4602
            .ok_or_else(|| fail("generator_or_guard.as_object"))?;
855
4602
        let (name, inner) = gen_or_guard_obj
856
4602
            .iter()
857
4602
            .next()
858
4602
            .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
859
4602
        comprehension = match name.as_str() {
860
4602
            "Generator" => {
861
                // TODO: more things than GenDomainNoRepr and Single names here?
862
4017
                let generator_obj = inner
863
4017
                    .as_object()
864
4017
                    .ok_or_else(|| fail("Generator.inner.as_object"))?;
865
4017
                let (name, gen_inner) = generator_obj
866
4017
                    .iter()
867
4017
                    .next()
868
4017
                    .ok_or_else(|| fail("Generator.inner.iter().next"))?;
869
4017
                match name.as_str() {
870
4017
                    "GenDomainNoRepr" => {
871
3978
                        let name = gen_inner
872
3978
                            .pointer("/0/Single/Name")
873
3978
                            .and_then(Value::as_str)
874
3978
                            .ok_or_else(|| {
875
                                fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
876
                            })?;
877
3978
                        let domain_obj = gen_inner
878
3978
                            .pointer("/1")
879
3978
                            .and_then(Value::as_object)
880
3978
                            .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
881
3978
                        let (domain_name, domain_value) = domain_obj
882
3978
                            .iter()
883
3978
                            .next()
884
3978
                            .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
885
3978
                        let domain = parse_domain(
886
3978
                            domain_name,
887
3978
                            domain_value,
888
3978
                            &mut generator_symboltable.write(),
889
                        )?;
890
3978
                        comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
891
                    }
892
                    // TODO: this is temporary until comprehensions support "in expr" generators
893
                    // currently only supports a single generator of this type
894
39
                    "GenInExpr" => return parse_in_expr_comprehension(scope, value, gen_inner),
895
                    _ => {
896
                        bug!("unknown generator type inside comprehension {name}");
897
                    }
898
                }
899
            }
900

            
901
585
            "Condition" => {
902
585
                let expr = parse_expression(inner, &generator_symboltable)
903
585
                    .map_err(|_| fail("Condition.parse_expression"))?;
904
585
                comprehension.guard(expr)
905
            }
906

            
907
            x => {
908
                bug!("unknown field inside comprehension {x}");
909
            }
910
        }
911
    }
912

            
913
3549
    let return_expr_value = value
914
3549
        .pointer("/0")
915
3549
        .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
916
3549
    let expr = parse_expression(return_expr_value, &return_expr_symboltable)
917
3549
        .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
918

            
919
3549
    Ok(Expression::Comprehension(
920
3549
        Metadata::new(),
921
3549
        Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
922
3549
    ))
923
3588
}
924

            
925
39
fn parse_in_expr_comprehension(
926
39
    scope: SymbolTablePtr,
927
39
    comprehension_value: &Value,
928
39
    gen_inner: &Value,
929
39
) -> Result<Expression> {
930
39
    let fail = |stage: &str| -> Error {
931
        Error::Parse(format!(
932
            "Could not parse GenInExpr comprehension at stage `{stage}`"
933
        ))
934
    };
935

            
936
39
    let name = gen_inner
937
39
        .pointer("/0/Single/Name")
938
39
        .and_then(Value::as_str)
939
39
        .ok_or_else(|| fail("GenInExpr.pointer(/0/Single/Name).as_str"))?;
940
39
    let generator_expr = gen_inner
941
39
        .pointer("/1")
942
39
        .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
943
39
    let expr =
944
39
        parse_expression(generator_expr, &scope).map_err(|_| fail("GenInExpr.parse_expression"))?;
945

            
946
39
    let comprehension =
947
39
        AbstractComprehensionBuilder::new(&scope).new_expression_generator(expr, name.into());
948
39
    let return_expr_value = comprehension_value
949
39
        .pointer("/0")
950
39
        .ok_or_else(|| fail("comprehension_value.pointer(/0)"))?;
951
39
    let expr = parse_expression(return_expr_value, &comprehension.return_expr_symbols())
952
39
        .map_err(|_| fail("GenInExpr.return_expr.parse_expression"))?;
953

            
954
39
    Ok(Expression::AbstractComprehension(
955
39
        Metadata::new(),
956
39
        Moo::new(comprehension.with_return_value(expr)),
957
39
    ))
958
39
}
959

            
960
25754
fn parse_bin_op(
961
25754
    bin_op: &serde_json::Map<String, Value>,
962
25754
    scope: &SymbolTablePtr,
963
25754
) -> Result<Expression> {
964
    // we know there is a single key value pair in this object
965
    // extract the value, ignore the key
966
25754
    let (key, value) = bin_op
967
25754
        .into_iter()
968
25754
        .next()
969
25754
        .ok_or(error!("Binary op object is empty"))?;
970

            
971
25754
    let constructor = binary_operator(key.as_str())
972
25754
        .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
973

            
974
25754
    match &value {
975
25754
        Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
976
25754
            let arg1 = parse_expression(&bin_op_args[0], scope)?;
977
25754
            let arg2 = parse_expression(&bin_op_args[1], scope)?;
978
25754
            Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
979
        }
980
        _ => Err(error!("Binary operator arguments are not a 2-array")),
981
    }
982
25754
}
983

            
984
10998
fn parse_indexing_slicing_op(
985
10998
    op: &serde_json::Map<String, Value>,
986
10998
    scope: &SymbolTablePtr,
987
10998
) -> Result<Expression> {
988
    // we know there is a single key value pair in this object
989
    // extract the value, ignore the key
990
10998
    let (key, value) = op
991
10998
        .into_iter()
992
10998
        .next()
993
10998
        .ok_or(error!("Indexing/Slicing op object is empty"))?;
994

            
995
    // we know that this is meant to be a mkopindexing, so anything that goes wrong from here is a
996
    // bug!
997

            
998
    // Conjure does a[1,2,3] as MkOpIndexing(MkOpIndexing(MkOpIndexing(a,3),2),1).
999
    //
    // 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;
10998
    let mut indices: Vec<Option<Expression>> = vec![];
    // true if this has no slicing, false otherwise.
10998
    let mut all_known = true;
10998
    match key.as_str() {
10998
        "MkOpIndexing" => {
9594
            match &value {
9594
                Value::Array(op_args) if op_args.len() == 2 => {
9594
                    target = parse_expression(&op_args[0], scope)?;
9594
                    indices.push(Some(parse_expression(&op_args[1], scope)?));
                }
                _ => return Err(error!("Unknown object inside MkOpIndexing")),
            };
        }
1404
        "MkOpSlicing" => {
1404
            all_known = false;
1404
            match &value {
1404
                Value::Array(op_args) if op_args.len() == 3 => {
1404
                    target = parse_expression(&op_args[0], scope)?;
1404
                    indices.push(None);
                }
                _ => return Err(error!("Unknown object inside MkOpSlicing")),
            };
        }
        _ => return Err(error!("Unknown indexing/slicing operator")),
    }
    loop {
14157
        match &mut target {
2691
            Expression::UnsafeIndex(_, new_target, new_indices) => {
2691
                indices.extend(new_indices.iter().cloned().rev().map(Some));
2691
                target = Moo::unwrap_or_clone(new_target.clone());
2691
            }
468
            Expression::UnsafeSlice(_, new_target, new_indices) => {
468
                all_known = false;
468
                indices.extend(new_indices.iter().cloned().rev());
468
                target = Moo::unwrap_or_clone(new_target.clone());
468
            }
            _ => {
                // not a slice or an index, we have reached the target.
10998
                break;
            }
        }
    }
10998
    indices.reverse();
10998
    if all_known {
        Ok(Expression::UnsafeIndex(
9126
            Metadata::new(),
9126
            Moo::new(target),
9126
            indices
9126
                .into_iter()
9126
                .collect::<Option<Vec<_>>>()
9126
                .ok_or(error!("Missing index in fully-known indexing operation"))?,
        ))
    } else {
1872
        Ok(Expression::UnsafeSlice(
1872
            Metadata::new(),
1872
            Moo::new(target),
1872
            indices,
1872
        ))
    }
10998
}
390
fn parse_flatten_op(
390
    op: &serde_json::Map<String, Value>,
390
    scope: &SymbolTablePtr,
390
) -> Result<Expression> {
390
    let args = op
390
        .get("MkOpFlatten")
390
        .ok_or(error!("MkOpFlatten missing"))?
390
        .as_array()
390
        .ok_or(error!("MkOpFlatten is not an array"))?;
390
    let first = args
390
        .first()
390
        .ok_or(error!("MkOpFlatten missing first argument"))?;
390
    let second = args
390
        .get(1)
390
        .ok_or(error!("MkOpFlatten missing second argument"))?;
390
    let n = parse_expression(first, scope).ok();
390
    let matrix = parse_expression(second, scope)?;
390
    if let Some(n) = n {
        Ok(Expression::Flatten(
            Metadata::new(),
            Some(Moo::new(n)),
            Moo::new(matrix),
        ))
    } else {
390
        Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
    }
390
}
21237
fn parse_unary_op(
21237
    un_op: &serde_json::Map<String, Value>,
21237
    scope: &SymbolTablePtr,
21237
) -> Result<Expression> {
21237
    let fail = |stage: &str| -> Error {
        Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
    };
21237
    let (key, value) = un_op
21237
        .iter()
21237
        .next()
21237
        .ok_or_else(|| fail("un_op.iter().next"))?;
21237
    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.
21237
    let arg = match value {
21237
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
3588
            let comprehension_kind = match key.as_str() {
3588
                "MkOpOr" => Some(ACOperatorKind::Or),
3159
                "MkOpAnd" => Some(ACOperatorKind::And),
780
                "MkOpSum" => Some(ACOperatorKind::Sum),
195
                "MkOpProduct" => Some(ACOperatorKind::Product),
195
                _ => None,
            };
3588
            parse_comprehension(comprehension, scope.clone(), comprehension_kind)
3588
                .map_err(|_| fail("value.Comprehension.parse_comprehension"))
        }
17649
        _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
    }
21237
    .map_err(|_| fail("arg"))?;
21237
    Ok(constructor(Metadata::new(), Moo::new(arg)))
21237
}
// Takes in { AbstractLiteral: .... }
10726
fn parse_abstract_matrix_as_expr(
10726
    value: &serde_json::Value,
10726
    scope: &SymbolTablePtr,
10726
) -> Result<Expression> {
10726
    parser_trace!("trying to parse an abstract literal matrix");
9907
    let (values, domain_name, domain_value) =
10726
        if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
8737
            parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
8737
            let (domain_name, domain_value) = abs_lit_matrix
8737
                .pointer("/0")
8737
                .and_then(Value::as_object)
8737
                .and_then(|x| x.iter().next())
8737
                .ok_or(error!("AbsLitMatrix missing domain"))?;
8737
            let values = abs_lit_matrix
8737
                .pointer("/1")
8737
                .ok_or(error!("AbsLitMatrix missing values"))?;
8737
            Some((values, domain_name, domain_value))
        }
        // the input of this expression is constant - e.g. or([]), or([false]), min([2]), etc.
819
        else if let Some(const_abs_lit_matrix) =
1989
            value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
        {
819
            parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
819
            let (domain_name, domain_value) = const_abs_lit_matrix
819
                .pointer("/0")
819
                .and_then(Value::as_object)
819
                .and_then(|x| x.iter().next())
819
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
819
            let values = const_abs_lit_matrix
819
                .pointer("/1")
819
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
819
            Some((values, domain_name, domain_value))
1170
        } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
351
            parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
351
            let (domain_name, domain_value) = const_abs_lit_matrix
351
                .pointer("/0")
351
                .and_then(Value::as_object)
351
                .and_then(|x| x.iter().next())
351
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
351
            let values = const_abs_lit_matrix
351
                .pointer("/1")
351
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
351
            Some((values, domain_name, domain_value))
        } else {
819
            None
        }
10726
        .ok_or(error!("Could not parse abstract literal matrix"))?;
9907
    parser_trace!(".. found in domain and values in JSON:");
9907
    parser_trace!(".. .. index domain name {domain_name}");
9907
    parser_trace!(".. .. values {value}");
9907
    let args_parsed = values
9907
        .as_array()
9907
        .ok_or(error!("Matrix values are not an array"))?
9907
        .iter()
21491
        .map(|x| parse_expression(x, scope))
9907
        .collect::<Result<Vec<Expression>>>()?;
9907
    if !args_parsed.is_empty() {
9868
        parser_trace!(
            ".. successfully parsed values as expressions: {}, ... ",
            args_parsed[0]
        );
    } else {
39
        parser_trace!(".. successfully parsed empty values ",);
    }
9907
    let mut symbols = scope.write();
9907
    match parse_domain(domain_name, domain_value, &mut symbols) {
9907
        Ok(domain) => {
9907
            parser_trace!("... sucessfully parsed domain as {domain}");
9907
            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])
        }
    }
10726
}
105481
fn parse_constant(
105481
    constant: &serde_json::Map<String, Value>,
105481
    scope: &SymbolTablePtr,
105481
) -> Result<Expression> {
105481
    match &constant.get("Constant") {
93998
        Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
89700
            let int_32: i32 = match int["ConstantInt"]
89700
                .as_array()
89700
                .ok_or(error!("ConstantInt is not an array"))?[1]
89700
                .as_i64()
89700
                .ok_or(error!("ConstantInt does not contain int"))?
89700
                .try_into()
            {
89700
                Ok(x) => x,
                Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
            };
89700
            Ok(Expression::Atomic(
89700
                Metadata::new(),
89700
                Atom::Literal(Literal::Int(int_32)),
89700
            ))
        }
4298
        Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
1016
            let b: bool = b["ConstantBool"]
1016
                .as_bool()
1016
                .ok_or(error!("ConstantBool does not contain bool"))?;
1016
            Ok(Expression::Atomic(
1016
                Metadata::new(),
1016
                Atom::Literal(Literal::Bool(b)),
1016
            ))
        }
3282
        Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
3282
            if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
3282
                if let Some(arr) = obj.get("AbsLitSet") {
2148
                    return parse_abs_lit(arr, scope);
1134
                } else if let Some(arr) = obj.get("AbsLitMSet") {
40
                    return parse_abs_mset(arr, scope);
1094
                } else if let Some(arr) = obj.get("AbsLitMatrix") {
819
                    return parse_abstract_matrix_as_expr(arr, scope);
275
                } else if let Some(arr) = obj.get("AbsLitTuple") {
156
                    return parse_abs_tuple(arr, scope);
119
                } else if let Some(arr) = obj.get("AbsLitRecord") {
39
                    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 => {
11483
            let int_expr = constant
11483
                .get("ConstantInt")
11483
                .and_then(|x| x.as_array())
11483
                .and_then(|x| x[1].as_i64())
11483
                .and_then(|x| x.try_into().ok())
11483
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
11483
            if let Some(expr) = int_expr {
11405
                return Ok(expr);
78
            }
78
            let bool_expr = constant
78
                .get("ConstantBool")
78
                .and_then(|x| x.as_bool())
78
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
78
            if let Some(expr) = bool_expr {
78
                return Ok(expr);
            }
            Err(error!(format!("Unhandled parse_constant {constant:#?}")))
        }
        otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
    }
105481
}