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

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

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

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

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

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

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

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

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

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

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

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

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

            
172
34823
fn parse_domain(
173
34823
    domain_name: &str,
174
34538
    domain_value: &JsonValue,
175
34823
    symbols: &mut SymbolTable,
176
34823
) -> Result<DomainPtr> {
177
34823
    match domain_name {
178
34823
        "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
179
8829
        "DomainBool" => Ok(Domain::bool()),
180
4124
        "DomainReference" => {
181
2340
            let name = Name::user(
182
640
                domain_value
183
33306
                    .as_array()
184
33306
                    .ok_or(error!("DomainReference is not an array"))?[0]
185
33306
                    .as_object()
186
33306
                    .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
187
33306
                    .as_str()
188
33306
                    .ok_or(error!("DomainReference[0].Name is not a string"))?,
189
32666
            );
190
8722
            let ptr = symbols
191
4519
                .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
608
        }
197
4092
        "DomainSet" => {
198
868
            let dom = domain_value.get(2).and_then(|v| v.as_object());
199
868
            let domain_obj = dom.ok_or(error!("DomainSet is missing domain object"))?;
200
260
            let domain = domain_obj
201
868
                .iter()
202
868
                .next()
203
868
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
204
868
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
205
868
            let size = domain_value
206
868
                .get(1)
207
260
                .and_then(|v| v.as_object())
208
3531
                .ok_or(error!("Set size attributes is not an object"))?;
209
489
            let size = parse_size_attr(size, symbols)?;
210
489
            let attr: SetAttr<IntVal> = SetAttr { size };
211
489
            Ok(Domain::set(attr, domain))
212
229
        }
213
3453
        "DomainMSet" => {
214
589
            let dom = domain_value
215
589
                .get(2)
216
589
                .and_then(|v| v.as_object())
217
589
                .expect("domain object exists");
218
589
            let domain = dom
219
589
                .iter()
220
589
                .next()
221
589
                .ok_or(Error::Parse("DomainMSet is an empty object".to_owned()))?;
222
589
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
223

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

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

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

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

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

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

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

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

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

            
272
4257
            index_domains.push(parse_domain(
273
4257
                index_domain_name,
274
4257
                index_domain_value,
275
4257
                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
4257
            let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
284
4617
            while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
285
2433
                index_domains.append(&mut indices);
286
2433
                value_domain = new_value_domain.clone()
287
            }
288

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

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

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

            
317
286
            let mut record_entries = vec![];
318
266

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

            
327
40
                let name = Name::User(Ustr::from(name));
328
                // then collect the domain of the record field
329
40
                let domain = item[1]
330
78
                    .as_object()
331
40
                    .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
38

            
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
38
            }
342
38

            
343
            // add record fields to symbol table
344
78
            for decl in record_entries
345
58
                .iter()
346
20
                .cloned()
347
58
                .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
38
                ))?;
352
            }
353

            
354
20
            Ok(Domain::record(record_entries))
355
38
        }
356
539
        "DomainFunction" => {
357
539
            let domain = domain_value
358
539
                .get(2)
359
520
                .and_then(|v| v.as_object())
360
558
                .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
539
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
366

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

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

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

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

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

            
433
1140
    let attr_obj = attr_map
434
1140
        .iter()
435
33806
        .next()
436
1140
        .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
437
2186
    match attr_obj.0.as_str() {
438
2186
        "SizeAttr_None" => Ok(Range::Unbounded),
439
1626
        "SizeAttr_MinSize" => {
440
1306
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
441
1306
            Ok(Range::UnboundedR(size))
442
1046
        }
443
320
        "SizeAttr_MaxSize" => {
444
1142
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
445
1142
            Ok(Range::UnboundedL(size))
446
1046
        }
447
1270
        "SizeAttr_MinMaxSize" => {
448
1150
            let min_max = attr_obj
449
1150
                .1
450
637
                .as_array()
451
351
                .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
452
351
            let min = min_max
453
104
                .first()
454
390
                .ok_or(error!("SizeAttr Min is not present"))?;
455
188
            let min_int = parse_expression_to_int_val(min, &scope)?;
456
188
            let max = min_max
457
104
                .get(1)
458
306
                .ok_or(error!("SizeAttr Max is not present"))?;
459
192
            let max_int = parse_expression_to_int_val(max, &scope)?;
460
192
            Ok(Range::Bounded(min_int, max_int))
461
88
        }
462
208
        "SizeAttr_Size" => {
463
208
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
464
208
            Ok(Range::Single(size))
465
88
        }
466
88
        _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
467
88
    }
468
1228
}
469
88

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

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

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

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

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

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

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

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

            
581
50687
fn binary_operator(op_name: &str) -> Option<BinOp> {
582
49824
    match op_name {
583
50687
        "MkOpIn" => Some(Expression::In),
584
49996
        "MkOpUnion" => Some(Expression::Union),
585
49324
        "MkOpIntersect" => Some(Expression::Intersect),
586
49716
        "MkOpSupset" => Some(Expression::Supset),
587
99470
        "MkOpSupsetEq" => Some(Expression::SupsetEq),
588
48864
        "MkOpSubset" => Some(Expression::Subset),
589
48664
        "MkOpSubsetEq" => Some(Expression::SubsetEq),
590
48492
        "MkOpEq" => Some(Expression::Eq),
591
35676
        "MkOpNeq" => Some(Expression::Neq),
592
80120
        "MkOpGeq" => Some(Expression::Geq),
593
78400
        "MkOpLeq" => Some(Expression::Leq),
594
75064
        "MkOpGt" => Some(Expression::Gt),
595
73276
        "MkOpLt" => Some(Expression::Lt),
596
70824
        "MkOpLexLt" => Some(Expression::LexLt),
597
70380
        "MkOpLexGt" => Some(Expression::LexGt),
598
70228
        "MkOpLexLeq" => Some(Expression::LexLeq),
599
69596
        "MkOpLexGeq" => Some(Expression::LexGeq),
600
69406
        "MkOpDiv" => Some(Expression::UnsafeDiv),
601
66928
        "MkOpMod" => Some(Expression::UnsafeMod),
602
53786
        "MkOpMinus" => Some(Expression::Minus),
603
49584
        "MkOpImply" => Some(Expression::Imply),
604
46138
        "MkOpIff" => Some(Expression::Iff),
605
42776
        "MkOpPow" => Some(Expression::UnsafePow),
606
40104
        "MkOpImage" => Some(Expression::Image),
607
37816
        "MkOpImageSet" => Some(Expression::ImageSet),
608
37432
        "MkOpPreImage" => Some(Expression::PreImage),
609
37352
        "MkOpInverse" => Some(Expression::Inverse),
610
36816
        "MkOpRestrict" => Some(Expression::Restrict),
611
36736
        _ => None,
612
19868
    }
613
68742
}
614
17358

            
615
44970
fn unary_operator(op_name: &str) -> Option<UnaryOp> {
616
44780
    match op_name {
617
43590
        "MkOpNot" => Some(Expression::Not),
618
41594
        "MkOpNegate" => Some(Expression::Neg),
619
32758
        "MkOpTwoBars" => Some(Expression::Abs),
620
32082
        "MkOpAnd" => Some(Expression::And),
621
28062
        "MkOpSum" => Some(Expression::Sum),
622
22488
        "MkOpProduct" => Some(Expression::Product),
623
7128
        "MkOpOr" => Some(Expression::Or),
624
51508
        "MkOpMin" => Some(Expression::Min),
625
3320
        "MkOpMax" => Some(Expression::Max),
626
30160
        "MkOpAllDiff" => Some(Expression::AllDiff),
627
28160
        "MkOpToInt" => Some(Expression::ToInt),
628
28000
        "MkOpDefined" => Some(Expression::Defined),
629
26096
        "MkOpRange" => Some(Expression::Range),
630
17694
        _ => None,
631
17124
    }
632
42716
}
633
8136

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

            
641
360
    match obj {
642
149210
        Value::Object(op) if op.contains_key("Op") => {
643
66168
            let op_obj = op
644
38328
                .get("Op")
645
179464
                .and_then(Value::as_object)
646
179464
                .ok_or_else(|| fail("Op.as_object"))?;
647
38803
            let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
648
475

            
649
38803
            if op_obj.contains_key("MkOpFlatten") {
650
675
                parse_flatten_op(op_obj, scope)
651
38128
            } else if op_obj.contains_key("MkOpTable") {
652
383
                parse_table_op(op_obj, scope)
653
179014
            } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
654
42127
                parse_indexing_slicing_op(op_obj, scope)
655
68547
            } else if binary_operator(op_name).is_some() {
656
53883
                parse_bin_op(op_obj, scope)
657
50967
            } else if unary_operator(op_name).is_some() {
658
50967
                parse_unary_op(op_obj, scope)
659
            } else {
660
36303
                Err(fail("Op.unknown"))
661
190
            }
662
36113
        }
663
110939
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
664
36056
            parse_comprehension(comprehension, scope.clone(), None)
665
5522
        }
666
141416
        Value::Object(refe) if refe.contains_key("Reference") => {
667
47740
            let ref_arr = refe["Reference"]
668
45046
                .as_array()
669
45046
                .ok_or_else(|| fail("Reference.as_array"))?;
670
31126
            let ref_obj = ref_arr
671
31126
                .first()
672
31126
                .and_then(|x| x.as_object())
673
31126
                .ok_or_else(|| fail("Reference[0].as_object"))?;
674
135769
            let name = ref_obj
675
31126
                .get("Name")
676
31126
                .and_then(|x| x.as_str())
677
135769
                .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
678
60547
            let user_name = Name::User(Ustr::from(name));
679
29421

            
680
60547
            let declaration: DeclarationPtr = scope
681
60547
                .read()
682
60547
                .lookup(&user_name)
683
60547
                .ok_or_else(|| fail("Reference.lookup"))?;
684
29421

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

            
695
6180
            if abstract_literal.contains_key("AbsLitSet") {
696
29461
                parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
697
35561
            } else if abstract_literal.contains_key("AbsLitFunction") {
698
29461
                parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
699
35521
            } else if abstract_literal.contains_key("AbsLitMSet") {
700
                parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
701
75222
            } else {
702
11962
                parse_abstract_matrix_as_expr(obj, scope)
703
5862
            }
704
5862
        }
705

            
706
79438
        Value::Object(constant) if constant.contains_key("Constant") => {
707
65874
            parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
708
5824
        }
709
38

            
710
13526
        Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
711
340
            parse_abstract_matrix_as_expr(obj, scope)
712
        }
713
5786

            
714
7400
        Value::Object(constant) if constant.contains_key("ConstantInt") => {
715
7040
            parse_constant(constant, scope)
716
        }
717
69720
        Value::Object(constant) if constant.contains_key("ConstantBool") => {
718
62275
            parse_constant(constant, scope)
719
        }
720

            
721
7645
        _ => Err(fail("no_match")),
722
323
    }
723
149410
}
724

            
725
8002
fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
726
7679
    let values = abs_set
727
1200
        .as_array()
728
1523
        .ok_or(error!("AbsLitSet is not an array"))?;
729
1238
    let expressions = values
730
1200
        .iter()
731
3040
        .map(|values| parse_expression(values, scope))
732
1675
        .collect::<Result<Vec<_>>>()?;
733

            
734
142336
    Ok(Expression::AbstractLiteral(
735
1200
        Metadata::new(),
736
2340
        AbstractLiteral::Set(expressions),
737
2340
    ))
738
2340
}
739
1140

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

            
749
1180
    Ok(Expression::AbstractLiteral(
750
40
        Metadata::new(),
751
59
        AbstractLiteral::MSet(expressions),
752
59
    ))
753
59
}
754
19

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

            
764
99
    Ok(Expression::AbstractLiteral(
765
80
        Metadata::new(),
766
156
        AbstractLiteral::Tuple(expressions),
767
156
    ))
768
156
}
769
76

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

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

            
787
40
        let value = parse_expression(&entry[1], scope)?;
788
38

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

            
797
20
    Ok(Expression::AbstractLiteral(
798
58
        Metadata::new(),
799
20
        AbstractLiteral::Record(rec),
800
58
    ))
801
58
}
802
38

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

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

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

            
842
2160
    let value = &comprehension["Comprehension"];
843
2084
    let mut comprehension = ComprehensionBuilder::new(scope.clone());
844
4062
    let generator_symboltable = comprehension.generator_symboltable();
845
4062
    let return_expr_symboltable = comprehension.return_expr_symboltable();
846
1978

            
847
4062
    let generators_and_guards_array = value
848
4062
        .pointer("/1")
849
4062
        .and_then(Value::as_array)
850
2084
        .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
851
2084
    let generators_and_guards = generators_and_guards_array.iter();
852

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

            
903
2472
            "Condition" => {
904
300
                let expr = parse_expression(inner, &generator_symboltable)
905
300
                    .map_err(|_| fail("Condition.parse_expression"))?;
906
300
                comprehension.guard(expr)
907
19
            }
908

            
909
            x => {
910
                bug!("unknown field inside comprehension {x}");
911
            }
912
        }
913
    }
914
285

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

            
921
2064
    Ok(Expression::Comprehension(
922
2064
        Metadata::new(),
923
2064
        Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
924
2064
    ))
925
2084
}
926
1959

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

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

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

            
956
39
    Ok(Expression::AbstractComprehension(
957
39
        Metadata::new(),
958
20
        Moo::new(comprehension.with_return_value(expr)),
959
39
    ))
960
39
}
961
19

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

            
973
34194
    let constructor = binary_operator(key.as_str())
974
34194
        .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
975
16614

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

            
986
60
fn parse_table_op(
987
16674
    op: &serde_json::Map<String, Value>,
988
16674
    scope: &SymbolTablePtr,
989
16674
) -> Result<Expression> {
990
16674
    let args = op
991
16674
        .get("MkOpTable")
992
60
        .ok_or(error!("MkOpTable missing"))?
993
60
        .as_array()
994
60
        .ok_or(error!("MkOpTable is not an array"))?;
995
16614

            
996
60
    if args.len() != 2 {
997
57
        return Err(error!("MkOpTable arguments are not a 2-array"));
998
117
    }
999
57

            
117
    let tuple_expr = parse_expression(&args[0], scope)?;
117
    let allowed_rows_expr = parse_expression(&args[1], scope)?;
57

            
117
    let (tuple_elems, _) = tuple_expr
117
        .clone()
117
        .unwrap_matrix_unchecked()
60
        .ok_or(error!("MkOpTable first argument is not a matrix"))?;
117
    let (allowed_rows, _) = allowed_rows_expr
60
        .clone()
117
        .unwrap_matrix_unchecked()
60
        .ok_or(error!("MkOpTable second argument is not a matrix"))?;
57

            
217
    for row_expr in allowed_rows {
160
        let (row_elems, _) = row_expr
217
            .unwrap_matrix_unchecked()
217
            .ok_or(error!("MkOpTable row is not a matrix"))?;
57

            
217
        if row_elems.len() != tuple_elems.len() {
57
            return Err(error!("MkOpTable row width does not match tuple width"));
217
        }
57
    }
57

            
60
    Ok(Expression::Table(
212
        Metadata::new(),
212
        Moo::new(tuple_expr),
212
        Moo::new(allowed_rows_expr),
212
    ))
60
}
152

            
5824
fn parse_indexing_slicing_op(
5976
    op: &serde_json::Map<String, Value>,
5824
    scope: &SymbolTablePtr,
5824
) -> Result<Expression> {
    // we know there is a single key value pair in this object
    // extract the value, ignore the key
5881
    let (key, value) = op
5881
        .into_iter()
5881
        .next()
5881
        .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!
5522

            
    // 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])
5522
    let mut target: Expression;
11346
    let mut indices: Vec<Option<Expression>> = vec![];
    // true if this has no slicing, false otherwise.
5824
    let mut all_known = true;
5824
    match key.as_str() {
5824
        "MkOpIndexing" => {
5104
            match &value {
5104
                Value::Array(op_args) if op_args.len() == 2 => {
5104
                    target = parse_expression(&op_args[0], scope)?;
5104
                    indices.push(Some(parse_expression(&op_args[1], scope)?));
5522
                }
                _ => return Err(error!("Unknown object inside MkOpIndexing")),
            };
5522
        }
6242
        "MkOpSlicing" => {
6242
            all_known = false;
5558
            match &value {
5558
                Value::Array(op_args) if op_args.len() == 3 => {
5558
                    target = parse_expression(&op_args[0], scope)?;
5558
                    indices.push(None);
                }
                _ => return Err(error!("Unknown object inside MkOpSlicing")),
            };
        }
684
        _ => return Err(error!("Unknown indexing/slicing operator")),
684
    }
684

            
684
    loop {
8208
        match &mut target {
2144
            Expression::UnsafeIndex(_, new_target, new_indices) => {
1460
                indices.extend(new_indices.iter().cloned().rev().map(Some));
1460
                target = Moo::unwrap_or_clone(new_target.clone());
1460
            }
240
            Expression::UnsafeSlice(_, new_target, new_indices) => {
240
                all_known = false;
240
                indices.extend(new_indices.iter().cloned().rev());
240
                target = Moo::unwrap_or_clone(new_target.clone());
240
            }
7137

            
1387
            _ => {
                // not a slice or an index, we have reached the target.
7211
                break;
1387
            }
        }
228
    }
228

            
6052
    indices.reverse();
228

            
6052
    if all_known {
        Ok(Expression::UnsafeIndex(
4864
            Metadata::new(),
4864
            Moo::new(target),
10386
            indices
4864
                .into_iter()
4864
                .collect::<Option<Vec<_>>>()
4864
                .ok_or(error!("Missing index in fully-known indexing operation"))?,
        ))
5522
    } else {
960
        Ok(Expression::UnsafeSlice(
6482
            Metadata::new(),
960
            Moo::new(target),
5570
            indices,
5570
        ))
4610
    }
10434
}
4610

            
4810
fn parse_flatten_op(
200
    op: &serde_json::Map<String, Value>,
200
    scope: &SymbolTablePtr,
1112
) -> Result<Expression> {
1112
    let args = op
1112
        .get("MkOpFlatten")
1112
        .ok_or(error!("MkOpFlatten missing"))?
1112
        .as_array()
200
        .ok_or(error!("MkOpFlatten is not an array"))?;
5522

            
200
    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)?;
190

            
390
    if let Some(n) = n {
        Ok(Expression::Flatten(
190
            Metadata::new(),
190
            Some(Moo::new(n)),
190
            Moo::new(matrix),
190
        ))
190
    } else {
390
        Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
190
    }
390
}
14854
fn parse_unary_op(
14664
    un_op: &serde_json::Map<String, Value>,
14664
    scope: &SymbolTablePtr,
14664
) -> Result<Expression> {
14664
    let fail = |stage: &str| -> Error {
        Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
    };
190

            
14664
    let (key, value) = un_op
14854
        .iter()
14664
        .next()
28584
        .ok_or_else(|| fail("un_op.iter().next"))?;
28584
    let constructor = unary_operator(key.as_str()).ok_or_else(|| fail("unary_operator"))?;
13920

            
    // unops are the main things that contain comprehensions
    //
    // if the current expr is a quantifier like and/or/sum and it contains a comprehension, let the comprehension know what it is inside.
14664
    let arg = match value {
14664
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
16004
            let comprehension_kind = match key.as_str() {
16004
                "MkOpOr" => Some(ACOperatorKind::Or),
15544
                "MkOpAnd" => Some(ACOperatorKind::And),
14320
                "MkOpSum" => Some(ACOperatorKind::Sum),
14020
                "MkOpProduct" => Some(ACOperatorKind::Product),
100
                _ => None,
            };
2084
            parse_comprehension(comprehension, scope.clone(), comprehension_kind)
2084
                .map_err(|_| fail("value.Comprehension.parse_comprehension"))
13920
        }
26500
        _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
1978
    }
16642
    .map_err(|_| fail("arg"))?;
1541

            
15044
    Ok(constructor(Metadata::new(), Moo::new(arg)))
14759
}
95

            
// Takes in { AbstractLiteral: .... }
9378
fn parse_abstract_matrix_as_expr(
9378
    value: &serde_json::Value,
7400
    scope: &SymbolTablePtr,
19342
) -> Result<Expression> {
7400
    parser_trace!("trying to parse an abstract literal matrix");
20840
    let (values, domain_name, domain_value) =
7400
        if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
20020
            parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
20020
            let (domain_name, domain_value) = abs_lit_matrix
6100
                .pointer("/0")
6100
                .and_then(Value::as_object)
13121
                .and_then(|x| x.iter().next())
13121
                .ok_or(error!("AbsLitMatrix missing domain"))?;
13121
            let values = abs_lit_matrix
13121
                .pointer("/1")
13121
                .ok_or(error!("AbsLitMatrix missing values"))?;
6565

            
13121
            Some((values, domain_name, domain_value))
5786
        }
        // the input of this expression is constant - e.g. or([]), or([false]), min([2]), etc.
6266
        else if let Some(const_abs_lit_matrix) =
7086
            value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
5786
        {
6266
            parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
6266
            let (domain_name, domain_value) = const_abs_lit_matrix
6266
                .pointer("/0")
6266
                .and_then(Value::as_object)
480
                .and_then(|x| x.iter().next())
6266
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
480
            let values = const_abs_lit_matrix
480
                .pointer("/1")
936
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
1235

            
480
            Some((values, domain_name, domain_value))
1276
        } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
796
            parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
796
            let (domain_name, domain_value) = const_abs_lit_matrix
796
                .pointer("/0")
796
                .and_then(Value::as_object)
796
                .and_then(|x| x.iter().next())
796
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
796
            let values = const_abs_lit_matrix
796
                .pointer("/1")
340
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
796
            Some((values, domain_name, domain_value))
779
        } else {
803
            None
323
        }
7723
        .ok_or(error!("Could not parse abstract literal matrix"))?;
323

            
7243
    parser_trace!(".. found in domain and values in JSON:");
7243
    parser_trace!(".. .. index domain name {domain_name}");
7243
    parser_trace!(".. .. values {value}");
323

            
7243
    let args_parsed = values
7243
        .as_array()
6920
        .ok_or(error!("Matrix values are not an array"))?
7376
        .iter()
14884
        .map(|x| parse_expression(x, scope))
13941
        .collect::<Result<Vec<Expression>>>()?;
13485
    if !args_parsed.is_empty() {
13465
        parser_trace!(
6565
            ".. successfully parsed values as expressions: {}, ... ",
16
            args_parsed[0]
6565
        );
6565
    } else {
6585
        parser_trace!(".. successfully parsed empty values ",);
6565
    }
14120

            
13485
    let mut symbols = scope.write();
6920
    match parse_domain(domain_name, domain_value, &mut symbols) {
13485
        Ok(domain) => {
13466
            parser_trace!("... sucessfully parsed domain as {domain}");
6920
            Ok(into_matrix_expr![args_parsed;domain])
8
        }
        Err(_) => {
            parser_trace!("... failed to parse domain, creating a matrix without one.");
19
            Ok(into_matrix_expr![args_parsed])
        }
    }
13965
}
6565

            
79481
fn parse_constant(
79481
    constant: &serde_json::Map<String, Value>,
79481
    scope: &SymbolTablePtr,
72916
) -> Result<Expression> {
72916
    match &constant.get("Constant") {
65836
        Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
63396
            let int_32: i32 = match int["ConstantInt"]
63396
                .as_array()
63396
                .ok_or(error!("ConstantInt is not an array"))?[1]
70417
                .as_i64()
63396
                .ok_or(error!("ConstantInt does not contain int"))?
132148
                .try_into()
68752
            {
132148
                Ok(x) => x,
68752
                Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
68752
            };
62235

            
123370
            Ok(Expression::Atomic(
123370
                Metadata::new(),
123370
                Atom::Literal(Literal::Int(int_32)),
123370
            ))
59974
        }
59974

            
2440
        Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
60554
            let b: bool = b["ConstantBool"]
580
                .as_bool()
580
                .ok_or(error!("ConstantBool does not contain bool"))?;
580
            Ok(Expression::Atomic(
60554
                Metadata::new(),
60554
                Atom::Literal(Literal::Bool(b)),
60554
            ))
59974
        }
1860
        Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
4121
            if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
2411
                if let Some(arr) = obj.get("AbsLitSet") {
1711
                    return parse_abs_lit(arr, scope);
1251
                } else if let Some(arr) = obj.get("AbsLitMSet") {
591
                    return parse_abs_mset(arr, scope);
1211
                } else if let Some(arr) = obj.get("AbsLitMatrix") {
1031
                    return parse_abstract_matrix_as_expr(arr, scope);
731
                } else if let Some(arr) = obj.get("AbsLitTuple") {
80
                    return parse_abs_tuple(arr, scope);
100
                } else if let Some(arr) = obj.get("AbsLitRecord") {
1730
                    return parse_abs_record(arr, scope);
1790
                } else if let Some(arr) = obj.get("AbsLitFunction") {
1790
                    return parse_abs_function(arr, scope);
1102
                }
608
            }
19
            Err(error!("Unhandled ConstantAbstract literal type"))
589
        }
456

            
        // sometimes (e.g. constant matrices) we can have a ConstantInt / Constant bool that is
        // not wrapped in Constant
57
        None => {
7099
            let int_expr = constant
7118
                .get("ConstantInt")
7118
                .and_then(|x| x.as_array())
7080
                .and_then(|x| x[1].as_i64())
7080
                .and_then(|x| x.try_into().ok())
7080
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
7080
            if let Some(expr) = int_expr {
7040
                return Ok(expr);
40
            }
6557
            let bool_expr = constant
6557
                .get("ConstantBool")
6557
                .and_then(|x| x.as_bool())
6557
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
6517

            
6557
            if let Some(expr) = bool_expr {
40
                return Ok(expr);
6517
            }
6479

            
38
            Err(error!(format!("Unhandled parse_constant {constant:#?}")))
        }
38
        otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
38
    }
72954
}