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

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

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

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

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

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

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

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

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

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

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

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

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

            
122
41680
    let name = Name::User(Ustr::from(name));
123

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

            
131
41680
    let domain = parse_domain(domain.0, domain.1, symtab)?;
132

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

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

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

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

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

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

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

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

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

            
254
482
            let attr: MSetAttr<IntVal> = MSetAttr { size, occurrence };
255
482
            Ok(Domain::mset(attr, domain))
256
        }
257
7038
        "DomainPartition" => {
258
368
            let dom = domain_value
259
368
                .get(2)
260
368
                .and_then(|v| v.as_object())
261
368
                .expect("domain object exists");
262
368
            let domain = dom.iter().next().ok_or(Error::Parse(
263
368
                "DomainPartition is an empty object".to_owned(),
264
368
            ))?;
265
368
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
266

            
267
368
            let attributes = domain_value
268
368
                .get(1)
269
368
                .and_then(|v| v.as_object())
270
368
                .ok_or(error!("Partition attributes is not an object"))?;
271

            
272
368
            let mut num_parts = Range::Unbounded;
273
368
            let mut part_len = Range::Unbounded;
274
368
            let mut is_regular = false;
275

            
276
368
            if let Some(val) = attributes.get("partsNum") {
277
368
                let attr_map = val.as_object().expect("numParts should be an object");
278
368
                num_parts = parse_size_attr(attr_map, symbols)?;
279
            }
280
368
            if let Some(val) = attributes.get("partsSize") {
281
368
                let attr_map = val.as_object().expect("partsSize should be an object");
282
368
                part_len = parse_size_attr(attr_map, symbols)?;
283
            }
284
368
            if let Some(val) = attributes.get("isRegular").and_then(|v| v.as_bool()) {
285
368
                is_regular = val;
286
368
            }
287

            
288
368
            let attr: PartitionAttr<IntVal> = PartitionAttr {
289
368
                num_parts,
290
368
                part_len,
291
368
                is_regular,
292
368
            };
293
368
            Ok(Domain::partition(attr, domain))
294
        }
295
6670
        "DomainMatrix" => {
296
4206
            let domain_value = domain_value
297
4206
                .as_array()
298
4206
                .ok_or(error!("Domain matrix is not an array"))?;
299

            
300
4206
            let indexed_by_domain = domain_value[0].clone();
301
4206
            let (index_domain_name, index_domain_value) = indexed_by_domain
302
4206
                .as_object()
303
4206
                .ok_or(error!("DomainMatrix[0] is not an object"))?
304
4206
                .iter()
305
4206
                .next()
306
4206
                .ok_or(error!(""))?;
307

            
308
4206
            let (value_domain_name, value_domain_value) = domain_value[1]
309
4206
                .as_object()
310
4206
                .ok_or(error!(""))?
311
4206
                .iter()
312
4206
                .next()
313
4206
                .ok_or(error!(""))?;
314

            
315
            // Conjure stores a 2-d matrix as a matrix of a matrix.
316
            //
317
            // Therefore, the index is always a Domain.
318

            
319
4206
            let mut index_domains: Vec<DomainPtr> = vec![];
320

            
321
4206
            index_domains.push(parse_domain(
322
4206
                index_domain_name,
323
4206
                index_domain_value,
324
4206
                symbols,
325
            )?);
326

            
327
            // We want to store 2-d matrices as a matrix with two index domains, not a matrix in a
328
            // matrix.
329
            //
330
            // Walk through the value domain until it is not a DomainMatrix, adding the index to
331
            // our list of indices.
332
4206
            let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
333
4896
            while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
334
690
                index_domains.append(&mut indices);
335
690
                value_domain = new_value_domain.clone()
336
            }
337

            
338
4206
            Ok(Domain::matrix(value_domain, index_domains))
339
        }
340

            
341
2464
        "DomainSequence" => {
342
340
            let dom = domain_value
343
340
                .get(2)
344
340
                .and_then(|v| v.as_object())
345
340
                .expect("domain object exists");
346
340
            let domain = dom
347
340
                .iter()
348
340
                .next()
349
340
                .ok_or(Error::Parse("DomainSequence is an empty object".to_owned()))?;
350
340
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
351

            
352
            // Parse Attributes
353
340
            let attributes = domain_value
354
340
                .get(1)
355
340
                .and_then(|v| v.as_array())
356
340
                .ok_or(error!("Sequence attributes is not a json array"))?;
357

            
358
340
            let size = attributes
359
340
                .first()
360
340
                .and_then(|v| v.as_object())
361
340
                .ok_or(error!("Sequence size attributes is not an object"))?;
362
340
            let size = parse_size_attr(size, symbols)?;
363

            
364
340
            let jectivity = attributes
365
340
                .get(1)
366
340
                .and_then(|v| v.as_str())
367
340
                .ok_or(error!("jectivity is not a string"))?;
368
340
            let jectivity = match jectivity {
369
340
                "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
370
140
                "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
371
100
                "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
372
60
                "JectivityAttr_None" => Some(JectivityAttr::None),
373
                _ => None,
374
            };
375
340
            let jectivity =
376
340
                jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
377

            
378
340
            let attr: SequenceAttr<IntVal> = SequenceAttr { size, jectivity };
379
340
            match attr.size {
380
20
                Range::Unbounded | Range::UnboundedR(_) => Err(Error::Parse(
381
20
                    "Sequence must have size or maxSize attribute".to_string(),
382
20
                )),
383
320
                _ => Ok(Domain::sequence(attr, domain)),
384
            }
385
        }
386

            
387
2124
        "DomainTuple" => {
388
600
            let domain_value = domain_value
389
600
                .as_array()
390
600
                .ok_or(error!("Domain tuple is not an array"))?;
391

            
392
            //iterate through the array and parse each domain
393
600
            let domain = domain_value
394
600
                .iter()
395
1240
                .map(|x| {
396
1240
                    let domain = x
397
1240
                        .as_object()
398
1240
                        .ok_or(error!("DomainTuple[0] is not an object"))?
399
1240
                        .iter()
400
1240
                        .next()
401
1240
                        .ok_or(error!("DomainTuple[0] is an empty object"))?;
402
1240
                    parse_domain(domain.0, domain.1, symbols)
403
1240
                })
404
600
                .collect::<Result<Vec<DomainPtr>>>()?;
405

            
406
600
            Ok(Domain::tuple(domain))
407
        }
408
1524
        "DomainRecord" | "DomainVariant" => {
409
            // Records and Variants can be parsed the same way for the most part
410
320
            let is_record = domain_name == "DomainRecord";
411
            // Get the actual string for error message purposes
412
320
            let domain_string = match is_record {
413
120
                true => "Record",
414
200
                false => "Variant",
415
            };
416
320
            let domain_value = domain_value.as_array().ok_or(error!(&format!(
417
320
                "Domain {domain_string} is not a json array"
418
320
            )))?;
419

            
420
320
            let mut entries = vec![];
421

            
422
720
            for item in domain_value {
423
                //collect the name of the field
424
720
                let name = item[0]
425
720
                    .as_object()
426
720
                    .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
427
720
                    .as_str()
428
720
                    .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
429

            
430
720
                let name = Name::User(Ustr::from(name));
431
                // then collect the domain of the field
432
720
                let domain = item[1]
433
720
                    .as_object()
434
720
                    .ok_or(error!("FindOrGiven[2] is not an object"))?
435
720
                    .iter()
436
720
                    .next()
437
720
                    .ok_or(error!("FindOrGiven[2] is an empty object"))?;
438

            
439
720
                let domain = parse_domain(domain.0, domain.1, symbols)?;
440

            
441
720
                let rec = FieldEntry { name, domain };
442

            
443
720
                entries.push(rec);
444
            }
445

            
446
            // add fields to symbol table
447
720
            for decl in entries
448
320
                .iter()
449
320
                .cloned()
450
320
                .map(DeclarationPtr::new_record_field)
451
            {
452
720
                symbols.insert(decl).ok_or(error!(
453
                    "record field should not already be in the symbol table"
454
                ))?;
455
            }
456
320
            if is_record {
457
120
                Ok(Domain::record(entries))
458
            } else {
459
200
                Ok(Domain::variant(entries))
460
            }
461
        }
462
1204
        "DomainFunction" => {
463
718
            let domain = domain_value
464
718
                .get(2)
465
718
                .and_then(|v| v.as_object())
466
718
                .ok_or(error!("Function domain is not an object"))?;
467
718
            let domain = domain
468
718
                .iter()
469
718
                .next()
470
718
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
471
718
            let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
472

            
473
718
            let codomain = domain_value
474
718
                .get(3)
475
718
                .and_then(|v| v.as_object())
476
718
                .ok_or(error!("Function codomain is not an object"))?;
477
718
            let codomain = codomain
478
718
                .iter()
479
718
                .next()
480
718
                .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
481
718
            let codomain = parse_domain(codomain.0.as_str(), codomain.1, symbols)?;
482

            
483
            // Attribute parsing
484
718
            let attributes = domain_value
485
718
                .get(1)
486
718
                .and_then(|v| v.as_array())
487
718
                .ok_or(error!("Function attributes is not a json array"))?;
488
718
            let size = attributes
489
718
                .first()
490
718
                .and_then(|v| v.as_object())
491
718
                .ok_or(error!("Function size attributes is not an object"))?;
492
718
            let size = parse_size_attr(size, symbols)?;
493
718
            let partiality = attributes
494
718
                .get(1)
495
718
                .and_then(|v| v.as_str())
496
718
                .ok_or(error!("Function partiality is not a string"))?;
497
718
            let partiality = match partiality {
498
718
                "PartialityAttr_Partial" => Some(PartialityAttr::Partial),
499
86
                "PartialityAttr_Total" => Some(PartialityAttr::Total),
500
                _ => None,
501
            };
502
718
            let partiality =
503
718
                partiality.ok_or(Error::Parse("Partiality is an unknown type".to_owned()))?;
504
718
            let jectivity = attributes
505
718
                .get(2)
506
718
                .and_then(|v| v.as_str())
507
718
                .ok_or(error!("Function jectivity is not a string"))?;
508
718
            let jectivity = match jectivity {
509
718
                "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
510
614
                "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
511
562
                "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
512
514
                "JectivityAttr_None" => Some(JectivityAttr::None),
513
                _ => None,
514
            };
515
718
            let jectivity =
516
718
                jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
517

            
518
718
            let attr: FuncAttr<IntVal> = FuncAttr {
519
718
                size,
520
718
                partiality,
521
718
                jectivity,
522
718
            };
523

            
524
718
            Ok(Domain::function(attr, domain, codomain))
525
        }
526

            
527
486
        "DomainRelation" => {
528
486
            let domains = domain_value
529
486
                .get(2)
530
486
                .and_then(|v| v.as_array())
531
486
                .ok_or(Error::Parse(
532
486
                    "Relation domains are not a json array".to_owned(),
533
486
                ))?;
534
486
            let domains = domains
535
486
                .iter()
536
1096
                .map(|x| {
537
1096
                    let domain = x
538
1096
                        .as_object()
539
1096
                        .ok_or(Error::Parse("Relation domain is not an object".to_owned()))?
540
1096
                        .iter()
541
1096
                        .next()
542
1096
                        .ok_or(Error::Parse(
543
1096
                            "Relation domain is an empty object".to_owned(),
544
1096
                        ))?;
545
1096
                    parse_domain(domain.0, domain.1, symbols)
546
1096
                })
547
486
                .collect::<Result<Vec<DomainPtr>>>()?;
548

            
549
            // Attribute parsing
550
486
            let attributes = domain_value
551
486
                .get(1)
552
486
                .and_then(|v| v.as_array())
553
486
                .ok_or(Error::Parse(
554
486
                    "Relation attributes are not a json array".to_owned(),
555
486
                ))?;
556
486
            let size = attributes
557
486
                .first()
558
486
                .and_then(|v| v.as_object())
559
486
                .ok_or(Error::Parse(
560
486
                    "Relation size attributes are not an object".to_owned(),
561
486
                ))?;
562
486
            let size = parse_size_attr(size, symbols)?;
563
486
            let binary = attributes
564
486
                .get(1)
565
486
                .and_then(|v| v.as_array())
566
486
                .ok_or(Error::Parse(
567
486
                    "Relation binary attributes are not a json array".to_owned(),
568
486
                ))?;
569
486
            let binary = binary
570
486
                .iter()
571
526
                .map(|x| {
572
520
                    let attr = x.as_str().ok_or(Error::Parse(
573
520
                        "Relation binary attribute is not a string".to_owned(),
574
520
                    ))?;
575
520
                    match attr {
576
520
                        "BinRelAttr_Reflexive" => Ok(BinaryAttr::Reflexive),
577
480
                        "BinRelAttr_Irreflexive" => Ok(BinaryAttr::Irreflexive),
578
440
                        "BinRelAttr_Coreflexive" => Ok(BinaryAttr::Coreflexive),
579
400
                        "BinRelAttr_Symmetric" => Ok(BinaryAttr::Symmetric),
580
360
                        "BinRelAttr_AntiSymmetric" => Ok(BinaryAttr::AntiSymmetric),
581
320
                        "BinRelAttr_ASymmetric" => Ok(BinaryAttr::ASymmetric),
582
280
                        "BinRelAttr_Transitive" => Ok(BinaryAttr::Transitive),
583
240
                        "BinRelAttr_Total" => Ok(BinaryAttr::Total),
584
200
                        "BinRelAttr_Connex" => Ok(BinaryAttr::Connex),
585
160
                        "BinRelAttr_Euclidean" => Ok(BinaryAttr::Euclidean),
586
120
                        "BinRelAttr_Serial" => Ok(BinaryAttr::Serial),
587
80
                        "BinRelAttr_Equivalence" => Ok(BinaryAttr::Equivalence),
588
40
                        "BinRelAttr_PartialOrder" => Ok(BinaryAttr::PartialOrder),
589
                        _ => Err(Error::Parse(
590
                            "Relation binary attribute is invalid".to_owned(),
591
                        )),
592
                    }
593
520
                })
594
486
                .collect::<Result<Vec<BinaryAttr>>>()?;
595

            
596
486
            let attr: RelAttr<IntVal> = RelAttr { size, binary };
597

            
598
486
            Ok(Domain::relation(attr, domains))
599
        }
600
        _ => Err(Error::Parse(
601
            "FindOrGiven[2] is an unknown object".to_owned(), // consider covered
602
        )),
603
    }
604
77140
}
605

            
606
3410
fn parse_size_attr(
607
3410
    attr_map: &JsonMap<String, JsonValue>,
608
3410
    symbols: &mut SymbolTable,
609
3410
) -> Result<Range<IntVal>> {
610
3410
    let scope = SymbolTablePtr::new();
611
3410
    *scope.write() = symbols.clone();
612

            
613
3410
    let attr_obj = attr_map
614
3410
        .iter()
615
3410
        .next()
616
3410
        .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
617
3410
    match attr_obj.0.as_str() {
618
3410
        "SizeAttr_None" => Ok(Range::Unbounded),
619
1556
        "SizeAttr_MinSize" => {
620
516
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
621
516
            Ok(Range::UnboundedR(size))
622
        }
623
1040
        "SizeAttr_MaxSize" => {
624
304
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
625
304
            Ok(Range::UnboundedL(size))
626
        }
627
736
        "SizeAttr_MinMaxSize" => {
628
274
            let min_max = attr_obj
629
274
                .1
630
274
                .as_array()
631
274
                .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
632
274
            let min = min_max
633
274
                .first()
634
274
                .ok_or(error!("SizeAttr Min is not present"))?;
635
274
            let min_int = parse_expression_to_int_val(min, &scope)?;
636
274
            let max = min_max
637
274
                .get(1)
638
274
                .ok_or(error!("SizeAttr Max is not present"))?;
639
274
            let max_int = parse_expression_to_int_val(max, &scope)?;
640
274
            Ok(Range::Bounded(min_int, max_int))
641
        }
642
462
        "SizeAttr_Size" => {
643
462
            let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
644
462
            Ok(Range::Single(size))
645
        }
646
        _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
647
    }
648
3410
}
649

            
650
482
fn parse_occur_attr(
651
482
    attr_map: &JsonMap<String, JsonValue>,
652
482
    symbols: &mut SymbolTable,
653
482
) -> Result<Range<IntVal>> {
654
482
    let scope = SymbolTablePtr::new();
655
482
    *scope.write() = symbols.clone();
656
482
    let attr_obj = attr_map
657
482
        .iter()
658
482
        .next()
659
482
        .ok_or(Error::Parse("OccurAttr is an empty object".to_owned()))?;
660
482
    match attr_obj.0.as_str() {
661
482
        "OccurAttr_None" => Ok(Range::Unbounded),
662
322
        "OccurAttr_MinOccur" => {
663
40
            let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
664
40
            Ok(Range::UnboundedR(size_int))
665
        }
666
282
        "OccurAttr_MaxOccur" => {
667
202
            let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
668
202
            Ok(Range::UnboundedL(size_int))
669
        }
670
80
        "OccurAttr_MinMaxOccur" => {
671
80
            let min_max = attr_obj
672
80
                .1
673
80
                .as_array()
674
80
                .ok_or(error!("OccurAttr MinMaxOccur is not a json array"))?;
675
80
            let min = min_max
676
80
                .first()
677
80
                .ok_or(error!("OccurAttr Min is not present"))?;
678
80
            let min_int = parse_expression_to_int_val(min, &scope)?;
679
80
            let max = min_max
680
80
                .get(1)
681
80
                .ok_or(error!("OccurAttr Max is not present"))?;
682
80
            let max_int = parse_expression_to_int_val(max, &scope)?;
683
80
            Ok(Range::Bounded(min_int, max_int))
684
        }
685
        "OccurAttr_Size" => {
686
            let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
687
            Ok(Range::Single(size_int))
688
        }
689
        _ => Err(Error::Parse("OccurAttr is an unknown type".to_owned())),
690
    }
691
482
}
692

            
693
58684
fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<DomainPtr> {
694
58684
    let scope = SymbolTablePtr::new();
695
58684
    *scope.write() = symbols.clone();
696

            
697
58684
    let mut ranges = Vec::new();
698
58684
    let arr = v
699
58684
        .as_array()
700
58684
        .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
701
58684
        .as_array()
702
58684
        .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
703
60884
    for range in arr {
704
60812
        let range = range
705
60812
            .as_object()
706
60812
            .ok_or(error!("DomainInt[1] contains a non-object"))?
707
60812
            .iter()
708
60812
            .next()
709
60812
            .ok_or(error!("DomainInt[1] contains an empty object"))?;
710
60812
        match range.0.as_str() {
711
60812
            "RangeBounded" => {
712
57086
                let arr = range
713
57086
                    .1
714
57086
                    .as_array()
715
57086
                    .ok_or(error!("RangeBounded is not an array".to_owned()))?;
716
57086
                let mut nums = Vec::new();
717
114172
                for item in arr.iter() {
718
114172
                    let num = parse_expression_to_int_val(item, &scope)?;
719
114172
                    nums.push(num);
720
                }
721
57086
                let lower = nums
722
57086
                    .first()
723
57086
                    .cloned()
724
57086
                    .ok_or(error!("RangeBounded lower bound missing"))?;
725
57086
                let upper = nums
726
57086
                    .get(1)
727
57086
                    .cloned()
728
57086
                    .ok_or(error!("RangeBounded upper bound missing"))?;
729
57086
                ranges.push(Range::Bounded(lower, upper));
730
            }
731
3726
            "RangeSingle" => {
732
3706
                let num = parse_expression_to_int_val(range.1, &scope)?;
733
3706
                ranges.push(Range::Single(num));
734
            }
735
20
            _ => return throw_error!("DomainInt[1] contains an unknown object"),
736
        }
737
    }
738
58664
    Ok(Domain::int(ranges))
739
58684
}
740

            
741
120110
fn parse_expression_to_int_val(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<IntVal> {
742
120110
    parser_trace!("trying to parse domain value as expression: {}", obj);
743
120110
    let expr = parse_expression(obj, scope)?;
744

            
745
120110
    if let Some(Literal::Int(i)) = expr.clone().into_literal() {
746
117086
        return Ok(IntVal::Const(i));
747
3024
    }
748

            
749
1836
    if let Expression::Atomic(_, Atom::Reference(reference)) = &expr
750
1836
        && let Some(reference_val) = IntVal::new_ref(reference)
751
    {
752
1836
        return Ok(reference_val);
753
1188
    }
754

            
755
1188
    IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
756
120110
}
757

            
758
type BinOp = fn(Metadata, Moo<Expression>, Moo<Expression>) -> Expression;
759
type UnaryOp = fn(Metadata, Moo<Expression>) -> Expression;
760

            
761
108522
fn binary_operator(op_name: &str) -> Option<BinOp> {
762
108522
    match op_name {
763
108522
        "MkOpIn" => Some(Expression::In),
764
107882
        "MkOpUnion" => Some(Expression::Union),
765
107602
        "MkOpIntersect" => Some(Expression::Intersect),
766
107342
        "MkOpSupset" => Some(Expression::Supset),
767
107022
        "MkOpSupsetEq" => Some(Expression::SupsetEq),
768
106702
        "MkOpSubset" => Some(Expression::Subset),
769
106302
        "MkOpSubsetEq" => Some(Expression::SubsetEq),
770
105946
        "MkOpEq" => Some(Expression::Eq),
771
76606
        "MkOpNeq" => Some(Expression::Neq),
772
71206
        "MkOpGeq" => Some(Expression::Geq),
773
67166
        "MkOpLeq" => Some(Expression::Leq),
774
59854
        "MkOpGt" => Some(Expression::Gt),
775
57042
        "MkOpLt" => Some(Expression::Lt),
776
52550
        "MkOpLexLt" => Some(Expression::LexLt),
777
51906
        "MkOpLexGt" => Some(Expression::LexGt),
778
51906
        "MkOpLexLeq" => Some(Expression::LexLeq),
779
51026
        "MkOpLexGeq" => Some(Expression::LexGeq),
780
51026
        "MkOpDiv" => Some(Expression::UnsafeDiv),
781
46306
        "MkOpMod" => Some(Expression::UnsafeMod),
782
44306
        "MkOpMinus" => Some(Expression::Minus),
783
40694
        "MkOpImply" => Some(Expression::Imply),
784
36790
        "MkOpIff" => Some(Expression::Iff),
785
36382
        "MkOpPow" => Some(Expression::UnsafePow),
786
33862
        "MkOpImage" => Some(Expression::Image),
787
33782
        "MkOpImageSet" => Some(Expression::ImageSet),
788
33702
        "MkOpPreImage" => Some(Expression::PreImage),
789
33578
        "MkOpInverse" => Some(Expression::Inverse),
790
33498
        "MkOpRestrict" => Some(Expression::Restrict),
791
33402
        "MkOpApart" => Some(Expression::Apart),
792
33322
        "MkOpTogether" => Some(Expression::Together),
793
33242
        "MkOpParty" => Some(Expression::Party),
794
33158
        "MkOpActive" => Some(Expression::Active),
795
33078
        "MkOpSubstring" => Some(Expression::Substring),
796
32918
        "MkOpSubsequence" => Some(Expression::Subsequence),
797
32918
        _ => None,
798
    }
799
108522
}
800

            
801
65836
fn unary_operator(op_name: &str, inner: Option<&Expression>) -> Option<UnaryOp> {
802
65836
    match op_name {
803
65836
        "MkOpNot" => Some(Expression::Not),
804
62056
        "MkOpNegate" => Some(Expression::Neg),
805
41596
        "MkOpTwoBars" => {
806
1856
            if let Some(inner) = inner {
807
928
                match inner.return_type() {
808
760
                    ReturnType::Int => Some(Expression::Abs),
809
                    ReturnType::Matrix(_)
810
                    | ReturnType::Set(_)
811
                    | ReturnType::MSet(_)
812
                    | ReturnType::Relation(_)
813
168
                    | ReturnType::Function(_, _) => Some(Expression::Card),
814
                    _ => None,
815
                }
816
            } else {
817
                // Internal expression cannot be known yet, so we just have to assume
818
928
                Some(Expression::Abs)
819
            }
820
        }
821
39740
        "MkOpAnd" => Some(Expression::And),
822
32188
        "MkOpSum" => Some(Expression::Sum),
823
17912
        "MkOpProduct" => Some(Expression::Product),
824
15028
        "MkOpOr" => Some(Expression::Or),
825
9180
        "MkOpMin" => Some(Expression::Min),
826
6940
        "MkOpMax" => Some(Expression::Max),
827
4920
        "MkOpAllDiff" => Some(Expression::AllDiff),
828
1028
        "MkOpToInt" => Some(Expression::ToInt),
829
652
        "MkOpDefined" => Some(Expression::Defined),
830
540
        "MkOpRange" => Some(Expression::Range),
831
416
        "MkOpFactorial" => Some(Expression::Factorial),
832
416
        "MkOpToMSet" => Some(Expression::ToMSet),
833
256
        "MkOpToRelation" => Some(Expression::ToRelation),
834
176
        "MkOpParticipants" => Some(Expression::Participants),
835
88
        "MkOpParts" => Some(Expression::Parts),
836
        _ => None,
837
    }
838
65836
}
839

            
840
327354
pub fn parse_expression(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<Expression> {
841
327354
    let fail = |stage: &str| -> Error {
842
1118
        Error::Parse(format!(
843
1118
            "Could not parse expression at stage `{stage}` for json `{obj}`"
844
1118
        ))
845
1118
    };
846

            
847
930
    match obj {
848
326886
        Value::Object(op) if op.contains_key("Op") => {
849
82584
            let op_obj = op
850
82584
                .get("Op")
851
82584
                .and_then(Value::as_object)
852
82584
                .ok_or_else(|| fail("Op.as_object"))?;
853
82584
            let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
854

            
855
82584
            if op_obj.contains_key("MkOpFlatten") {
856
384
                parse_flatten_op(op_obj, scope)
857
82200
            } else if op_obj.contains_key("MkOpTable") {
858
120
                parse_table_op(op_obj, scope)
859
82080
            } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
860
11198
                parse_indexing_slicing_op(op_obj, scope)
861
70882
            } else if op_obj.contains_key("MkOpRelationProj") {
862
42
                parse_relation_projection(op_obj, scope)
863
70840
            } else if op_obj.contains_key("MkOpToSet") {
864
120
                parse_to_set(op_obj, scope)
865
70720
            } else if binary_operator(op_name).is_some() {
866
37802
                parse_bin_op(op_obj, scope)
867
32918
            } else if unary_operator(op_name, None).is_some() {
868
32918
                parse_unary_op(op_obj, scope)
869
            } else {
870
                Err(fail("Op.unknown"))
871
            }
872
        }
873
244302
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
874
8
            parse_comprehension(comprehension, scope.clone(), None)
875
        }
876
244294
        Value::Object(refe) if refe.contains_key("Reference") => {
877
66952
            let ref_arr = refe["Reference"]
878
66952
                .as_array()
879
66952
                .ok_or_else(|| fail("Reference.as_array"))?;
880
66952
            let ref_obj = ref_arr
881
66952
                .first()
882
66952
                .and_then(|x| x.as_object())
883
66952
                .ok_or_else(|| fail("Reference[0].as_object"))?;
884
66952
            let name = ref_obj
885
66952
                .get("Name")
886
66952
                .and_then(|x| x.as_str())
887
66952
                .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
888
66952
            let user_name = Name::User(Ustr::from(name));
889

            
890
66952
            let declaration: DeclarationPtr = scope
891
66952
                .read()
892
66952
                .lookup(&user_name)
893
66952
                .ok_or_else(|| fail("Reference.lookup"))?;
894

            
895
66952
            Ok(Expression::Atomic(
896
66952
                Metadata::new(),
897
66952
                Atom::Reference(crate::ast::Reference::new(declaration)),
898
66952
            ))
899
        }
900
        // In the case where refering to fields. This not behind a reference
901
177342
        Value::Object(refe) if refe.contains_key("Name") => {
902
40
            let name = refe
903
40
                .get("Name")
904
40
                .and_then(|x| x.as_str())
905
40
                .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
906
40
            let user_name = Name::User(Ustr::from(name));
907

            
908
40
            let declaration: DeclarationPtr = scope
909
40
                .read()
910
40
                .lookup(&user_name)
911
40
                .ok_or_else(|| fail("Reference.lookup"))?;
912

            
913
40
            Ok(Expression::Atomic(
914
40
                Metadata::new(),
915
40
                Atom::Reference(crate::ast::Reference::new(declaration)),
916
40
            ))
917
        }
918
177302
        Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
919
13962
            let abstract_literal = abslit["AbstractLiteral"]
920
13962
                .as_object()
921
13962
                .ok_or_else(|| fail("AbstractLiteral.as_object"))?;
922

            
923
13962
            if abstract_literal.contains_key("AbsLitSet") {
924
80
                parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
925
13882
            } else if abstract_literal.contains_key("AbsLitFunction") {
926
40
                parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
927
13842
            } else if abstract_literal.contains_key("AbsLitMSet") {
928
                parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
929
13842
            } else if abstract_literal.contains_key("AbsLitVariant") {
930
40
                parse_abs_variant(&abslit["AbstractLiteral"]["AbsLitVariant"], scope)
931
13802
            } else if abstract_literal.contains_key("AbsLitRelation") {
932
                parse_abs_relation(&abslit["AbstractLiteral"]["AbsLitRelation"], scope)
933
13802
            } else if abstract_literal.contains_key("AbstractLiteralPartition") {
934
                parse_abs_partition(&abslit["AbstractLiteral"]["AbsLitPartition"], scope)
935
13802
            } else if abstract_literal.contains_key("AbsLitSequence") {
936
                parse_abs_sequence(&abslit["AbstractLiteral"]["AbsLitSequence"], scope)
937
            } else {
938
13802
                parse_abstract_matrix_as_expr(obj, scope)
939
            }
940
        }
941

            
942
163340
        Value::Object(constant) if constant.contains_key("Constant") => {
943
146530
            parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
944
        }
945

            
946
16810
        Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
947
750
            parse_abstract_matrix_as_expr(obj, scope)
948
        }
949

            
950
16060
        Value::Object(constant) if constant.contains_key("ConstantInt") => {
951
15130
            parse_constant(constant, scope)
952
        }
953
930
        Value::Object(constant) if constant.contains_key("ConstantBool") => {
954
280
            parse_constant(constant, scope)
955
        }
956

            
957
1118
        _ => Err(fail("no_match")),
958
    }
959
327354
}
960

            
961
2368
fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
962
2368
    let values = abs_set
963
2368
        .as_array()
964
2368
        .ok_or(error!("AbsLitSet is not an array"))?;
965
2368
    let expressions = values
966
2368
        .iter()
967
6012
        .map(|values| parse_expression(values, scope))
968
2368
        .collect::<Result<Vec<_>>>()?;
969

            
970
2368
    Ok(Expression::AbstractLiteral(
971
2368
        Metadata::new(),
972
2368
        AbstractLiteral::Set(expressions),
973
2368
    ))
974
2368
}
975

            
976
40
fn parse_abs_mset(abs_mset: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
977
40
    let values = abs_mset
978
40
        .as_array()
979
40
        .ok_or(error!("AbsLitMSet is not an array"))?;
980
40
    let expressions = values
981
40
        .iter()
982
120
        .map(|values| parse_expression(values, scope))
983
40
        .collect::<Result<Vec<_>>>()?;
984

            
985
40
    Ok(Expression::AbstractLiteral(
986
40
        Metadata::new(),
987
40
        AbstractLiteral::MSet(expressions),
988
40
    ))
989
40
}
990

            
991
40
fn parse_abs_partition(abs_partition: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
992
40
    let parts = abs_partition
993
40
        .as_array()
994
40
        .ok_or(error!("AbsLitPartition is not an array"))?;
995

            
996
40
    let mut partition: Vec<Vec<_>> = Vec::new();
997

            
998
120
    for part in parts {
999
120
        let vals = part
120
            .as_array()
120
            .ok_or(error!("Part in AbsLitPartition is not an array"))?;
120
        let exprs = vals
120
            .iter()
160
            .map(|values| parse_expression(values, scope))
120
            .collect::<Result<Vec<_>>>()?;
120
        partition.push(exprs);
    }
40
    Ok(Expression::AbstractLiteral(
40
        Metadata::new(),
40
        AbstractLiteral::Partition(partition),
40
    ))
40
}
120
fn parse_abs_sequence(abs_seq: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
120
    let values = abs_seq
120
        .as_array()
120
        .ok_or(error!("AbsLitSequence is not an array"))?;
120
    let expressions = values
120
        .iter()
400
        .map(|values| parse_expression(values, scope))
120
        .collect::<Result<Vec<_>>>()?;
120
    Ok(Expression::AbstractLiteral(
120
        Metadata::new(),
120
        AbstractLiteral::Sequence(expressions),
120
    ))
120
}
240
fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
240
    let values = abs_tuple
240
        .as_array()
240
        .ok_or(error!("AbsLitTuple is not an array"))?;
240
    let expressions = values
240
        .iter()
560
        .map(|values| parse_expression(values, scope))
240
        .collect::<Result<Vec<_>>>()?;
240
    Ok(Expression::AbstractLiteral(
240
        Metadata::new(),
240
        AbstractLiteral::Tuple(expressions),
240
    ))
240
}
//parses an abstract record as an expression
80
fn parse_abs_record(abs_record: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
80
    let entries = abs_record
80
        .as_array()
80
        .ok_or(error!("AbsLitRecord is not an array"))?;
80
    let mut rec = vec![];
160
    for entry in entries {
160
        let entry = entry
160
            .as_array()
160
            .ok_or(error!("AbsLitRecord entry is not an array"))?;
160
        let name = entry[0]
160
            .as_object()
160
            .ok_or(error!("AbsLitRecord field name is not an object"))?["Name"]
160
            .as_str()
160
            .ok_or(error!("AbsLitRecord field name is not a string"))?;
160
        let value = parse_expression(&entry[1], scope)?;
160
        let name = Name::User(Ustr::from(name));
160
        let rec_entry = FieldValue {
160
            name: name.clone(),
160
            value,
160
        };
160
        rec.push(rec_entry);
    }
80
    Ok(Expression::AbstractLiteral(
80
        Metadata::new(),
80
        AbstractLiteral::Record(rec),
80
    ))
80
}
//parses an abstract variant as an expression
40
fn parse_abs_variant(abs_variant: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
40
    let entry = abs_variant
40
        .as_array()
40
        .ok_or(error!("AbsLitVariant is not an array"))?;
40
    let name = entry[1]
40
        .as_object()
40
        .ok_or(error!("AbsLitVariant field name is not an object"))?["Name"]
40
        .as_str()
40
        .ok_or(error!("AbsLitVariant field name is not a string"))?;
40
    let value = parse_expression(&entry[2], scope)?;
40
    let name = Name::User(Ustr::from(name));
40
    let rec_entry = FieldValue { name, value };
40
    Ok(Expression::AbstractLiteral(
40
        Metadata::new(),
40
        AbstractLiteral::Variant(Moo::new(rec_entry)),
40
    ))
40
}
//parses an abstract function as an expression
120
fn parse_abs_function(abs_function: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
120
    let entries = abs_function
120
        .as_array()
120
        .ok_or(error!("AbsLitFunction is not an array"))?;
120
    let mut assignments = vec![];
240
    for entry in entries {
240
        let entry = entry
240
            .as_array()
240
            .ok_or(error!("Explicit function assignment is not an array"))?;
240
        let expression = entry
240
            .iter()
480
            .map(|values| parse_expression(values, scope))
240
            .collect::<Result<Vec<_>>>()?;
240
        let domain_value = expression
240
            .first()
240
            .ok_or(error!("Invalid function domain"))?;
240
        let codomain_value = expression
240
            .get(1)
240
            .ok_or(error!("Invalid function codomain"))?;
240
        let tuple = (domain_value.clone(), codomain_value.clone());
240
        assignments.push(tuple);
    }
120
    Ok(Expression::AbstractLiteral(
120
        Metadata::new(),
120
        AbstractLiteral::Function(assignments),
120
    ))
120
}
//parses an abstract relation as an expression
80
fn parse_abs_relation(abs_relation: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
80
    let entries = abs_relation
80
        .as_array()
80
        .ok_or(error!("AbsLitRelation is not an array"))?;
80
    let mut assignments = vec![];
200
    for entry in entries {
200
        let entry = entry
200
            .as_array()
200
            .ok_or(error!("Explicit relation assignment is not an array"))?;
200
        let expression = entry
200
            .iter()
480
            .map(|values| parse_expression(values, scope))
200
            .collect::<Result<Vec<_>>>()?;
200
        assignments.push(expression);
    }
80
    Ok(Expression::AbstractLiteral(
80
        Metadata::new(),
80
        AbstractLiteral::Relation(assignments),
80
    ))
80
}
4220
fn parse_comprehension(
4220
    comprehension: &serde_json::Map<String, Value>,
4220
    scope: SymbolTablePtr,
4220
    comprehension_kind: Option<ACOperatorKind>,
4220
) -> Result<Expression> {
4220
    let fail = |stage: &str| -> Error {
        Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
    };
4220
    let value = &comprehension["Comprehension"];
4220
    let mut comprehension = ComprehensionBuilder::new(scope.clone());
4220
    let generator_symboltable = comprehension.generator_symboltable();
4220
    let return_expr_symboltable = comprehension.return_expr_symboltable();
4220
    let generators_and_guards_array = value
4220
        .pointer("/1")
4220
        .and_then(Value::as_array)
4220
        .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
4220
    let generators_and_guards = generators_and_guards_array.iter();
5134
    for gen_or_guard in generators_and_guards {
5134
        let gen_or_guard_obj = gen_or_guard
5134
            .as_object()
5134
            .ok_or_else(|| fail("generator_or_guard.as_object"))?;
5134
        let (name, inner) = gen_or_guard_obj
5134
            .iter()
5134
            .next()
5134
            .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
5134
        comprehension = match name.as_str() {
5134
            "Generator" => {
                // TODO: more things than GenDomainNoRepr and Single names here?
4594
                let generator_obj = inner
4594
                    .as_object()
4594
                    .ok_or_else(|| fail("Generator.inner.as_object"))?;
4594
                let (name, gen_inner) = generator_obj
4594
                    .iter()
4594
                    .next()
4594
                    .ok_or_else(|| fail("Generator.inner.iter().next"))?;
4594
                match name.as_str() {
4594
                    "GenDomainNoRepr" => {
4536
                        let name = gen_inner
4536
                            .pointer("/0/Single/Name")
4536
                            .and_then(Value::as_str)
4536
                            .ok_or_else(|| {
                                fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
                            })?;
4536
                        let domain_obj = gen_inner
4536
                            .pointer("/1")
4536
                            .and_then(Value::as_object)
4536
                            .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
4536
                        let (domain_name, domain_value) = domain_obj
4536
                            .iter()
4536
                            .next()
4536
                            .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
4536
                        let domain = parse_domain(
4536
                            domain_name,
4536
                            domain_value,
4536
                            &mut generator_symboltable.write(),
                        )?;
4536
                        comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
                    }
58
                    "GenInExpr" => {
58
                        let name = gen_inner
58
                            .pointer("/0/Single/Name")
58
                            .and_then(Value::as_str)
58
                            .ok_or_else(|| {
                                fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
                            })?;
58
                        let generator_expr = gen_inner
58
                            .pointer("/1")
58
                            .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
58
                        let expr = parse_expression(generator_expr, &scope)
58
                            .map_err(|_| fail("GenInExpr.parse_expression"))?;
58
                        comprehension.expression_generator(name.into(), expr)
                    }
                    _ => {
                        bug!("unknown generator type inside comprehension {name}");
                    }
                }
            }
540
            "Condition" => {
540
                let expr = parse_expression(inner, &generator_symboltable)
540
                    .map_err(|_| fail("Condition.parse_expression"))?;
540
                comprehension.guard(expr)
            }
            x => {
                bug!("unknown field inside comprehension {x}");
            }
        }
    }
4220
    let return_expr_value = value
4220
        .pointer("/0")
4220
        .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
4220
    let expr = parse_expression(return_expr_value, &return_expr_symboltable)
4220
        .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
4220
    Ok(Expression::Comprehension(
4220
        Metadata::new(),
4220
        Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
4220
    ))
4220
}
37802
fn parse_bin_op(
37802
    bin_op: &serde_json::Map<String, Value>,
37802
    scope: &SymbolTablePtr,
37802
) -> Result<Expression> {
    // we know there is a single key value pair in this object
    // extract the value, ignore the key
37802
    let (key, value) = bin_op
37802
        .into_iter()
37802
        .next()
37802
        .ok_or(error!("Binary op object is empty"))?;
37802
    let constructor = binary_operator(key.as_str())
37802
        .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
37802
    match &value {
37802
        Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
37802
            let arg1 = parse_expression(&bin_op_args[0], scope)?;
37802
            let arg2 = parse_expression(&bin_op_args[1], scope)?;
37802
            Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
        }
        _ => Err(error!("Binary operator arguments are not a 2-array")),
    }
37802
}
120
fn parse_table_op(
120
    op: &serde_json::Map<String, Value>,
120
    scope: &SymbolTablePtr,
120
) -> Result<Expression> {
120
    let args = op
120
        .get("MkOpTable")
120
        .ok_or(error!("MkOpTable missing"))?
120
        .as_array()
120
        .ok_or(error!("MkOpTable is not an array"))?;
120
    if args.len() != 2 {
        return Err(error!("MkOpTable arguments are not a 2-array"));
120
    }
120
    let tuple_expr = parse_expression(&args[0], scope)?;
120
    let allowed_rows_expr = parse_expression(&args[1], scope)?;
120
    let (tuple_elems, _) = tuple_expr
120
        .clone()
120
        .unwrap_matrix_unchecked()
120
        .ok_or(error!("MkOpTable first argument is not a matrix"))?;
120
    let (allowed_rows, _) = allowed_rows_expr
120
        .clone()
120
        .unwrap_matrix_unchecked()
120
        .ok_or(error!("MkOpTable second argument is not a matrix"))?;
320
    for row_expr in allowed_rows {
320
        let (row_elems, _) = row_expr
320
            .unwrap_matrix_unchecked()
320
            .ok_or(error!("MkOpTable row is not a matrix"))?;
320
        if row_elems.len() != tuple_elems.len() {
            return Err(error!("MkOpTable row width does not match tuple width"));
320
        }
    }
120
    Ok(Expression::Table(
120
        Metadata::new(),
120
        Moo::new(tuple_expr),
120
        Moo::new(allowed_rows_expr),
120
    ))
120
}
11198
fn parse_indexing_slicing_op(
11198
    op: &serde_json::Map<String, Value>,
11198
    scope: &SymbolTablePtr,
11198
) -> Result<Expression> {
    // we know there is a single key value pair in this object
    // extract the value, ignore the key
11198
    let (key, value) = op
11198
        .into_iter()
11198
        .next()
11198
        .ok_or(error!("Indexing/Slicing op object is empty"))?;
    // we know that this is meant to be a mkopindexing, so anything that goes wrong from here is a
    // bug!
    // Conjure does a[1,2,3] as MkOpIndexing(MkOpIndexing(MkOpIndexing(a,3),2),1).
    //
    // And  a[1,..,3] as MkOpIndexing(MkOpSlicing(MkOpIndexing(a,3)),1).
    //
    // However, we want this in a flattened form: Index(a, [1,2,3])
    let mut target: Expression;
11198
    let mut indices: Vec<Option<Expression>> = vec![];
    // true if this has no slicing, false otherwise.
11198
    let mut all_known = true;
11198
    match key.as_str() {
11198
        "MkOpIndexing" => {
9838
            match &value {
9838
                Value::Array(op_args) if op_args.len() == 2 => {
9838
                    target = parse_expression(&op_args[0], scope)?;
9838
                    indices.push(Some(parse_expression(&op_args[1], scope)?));
                }
                _ => return Err(error!("Unknown object inside MkOpIndexing")),
            };
        }
1360
        "MkOpSlicing" => {
1360
            all_known = false;
1360
            match &value {
1360
                Value::Array(op_args) if op_args.len() == 3 => {
1360
                    target = parse_expression(&op_args[0], scope)?;
1360
                    indices.push(None);
                }
                _ => return Err(error!("Unknown object inside MkOpSlicing")),
            };
        }
        _ => return Err(error!("Unknown indexing/slicing operator")),
    }
    loop {
14480
        match &mut target {
2802
            Expression::UnsafeIndex(_, new_target, new_indices) => {
2802
                indices.extend(new_indices.iter().cloned().rev().map(Some));
2802
                target = Moo::unwrap_or_clone(new_target.clone());
2802
            }
480
            Expression::UnsafeSlice(_, new_target, new_indices) => {
480
                all_known = false;
480
                indices.extend(new_indices.iter().cloned().rev());
480
                target = Moo::unwrap_or_clone(new_target.clone());
480
            }
            _ => {
                // not a slice or an index, we have reached the target.
11198
                break;
            }
        }
    }
11198
    indices.reverse();
11198
    if all_known {
        Ok(Expression::UnsafeIndex(
9358
            Metadata::new(),
9358
            Moo::new(target),
9358
            indices
9358
                .into_iter()
9358
                .collect::<Option<Vec<_>>>()
9358
                .ok_or(error!("Missing index in fully-known indexing operation"))?,
        ))
    } else {
1840
        Ok(Expression::UnsafeSlice(
1840
            Metadata::new(),
1840
            Moo::new(target),
1840
            indices,
1840
        ))
    }
11198
}
// Parses relation projection, to get a Vec<Option<Expression>> for the projections
42
fn parse_relation_projection(
42
    op: &serde_json::Map<String, Value>,
42
    scope: &SymbolTablePtr,
42
) -> Result<Expression> {
42
    let args = op
42
        .get("MkOpRelationProj")
42
        .ok_or(error!("MkOpRelationProj missing"))?
42
        .as_array()
42
        .ok_or(error!("MkOpRelationProj is not an array"))?;
42
    let first = args
42
        .first()
42
        .ok_or(error!("MkOpRelationProj missing first argument"))?;
42
    let second = args
42
        .get(1)
42
        .ok_or(error!("MkOpRelationProj missing second argument"))?
42
        .as_array()
42
        .ok_or(error!("MkOpRelationProj second argument is not an array"))?;
42
    let relation = parse_expression(first, scope).ok();
    // We build a vec of option expressions.
    // In the case where a relation domain is not being projected it is None, otherwise it is Some with the expression
    // We parse the 'null' as an error, which is mapped to None after parse_expression()
42
    let projections = second
42
        .iter()
126
        .map(|expr| parse_expression(expr, scope).ok())
42
        .collect();
42
    if let Some(relation) = relation {
42
        Ok(Expression::RelationProj(
42
            Metadata::new(),
42
            Moo::new(relation),
42
            projections,
42
        ))
    } else {
        Err(error!("MkOpRelationProj does not contain relation"))
    }
42
}
// The ToSet operator is not truely a unary operator.
// The internal expression is 2nd in the array, with 'false' as the first element
// Therefore it needs separate parsing
120
fn parse_to_set(op: &serde_json::Map<String, Value>, scope: &SymbolTablePtr) -> Result<Expression> {
120
    let args = op
120
        .get("MkOpToSet")
120
        .ok_or(error!("MkOpToSet missing"))?
120
        .as_array()
120
        .ok_or(error!("MkOpToSet is not an array"))?;
120
    let second = args
120
        .get(1)
120
        .ok_or(error!("MkOpToSet missing second argument"))?;
120
    let inner = parse_expression(second, scope)?;
120
    Ok(Expression::ToSet(Metadata::new(), Moo::new(inner)))
120
}
384
fn parse_flatten_op(
384
    op: &serde_json::Map<String, Value>,
384
    scope: &SymbolTablePtr,
384
) -> Result<Expression> {
384
    let args = op
384
        .get("MkOpFlatten")
384
        .ok_or(error!("MkOpFlatten missing"))?
384
        .as_array()
384
        .ok_or(error!("MkOpFlatten is not an array"))?;
384
    let first = args
384
        .first()
384
        .ok_or(error!("MkOpFlatten missing first argument"))?;
384
    let second = args
384
        .get(1)
384
        .ok_or(error!("MkOpFlatten missing second argument"))?;
384
    let n = parse_expression(first, scope).ok();
384
    let matrix = parse_expression(second, scope)?;
384
    if let Some(n) = n {
        Ok(Expression::Flatten(
            Metadata::new(),
            Some(Moo::new(n)),
            Moo::new(matrix),
        ))
    } else {
384
        Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
    }
384
}
32918
fn parse_unary_op(
32918
    un_op: &serde_json::Map<String, Value>,
32918
    scope: &SymbolTablePtr,
32918
) -> Result<Expression> {
32918
    let fail = |stage: &str| -> Error {
        Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
    };
32918
    let (key, value) = un_op
32918
        .iter()
32918
        .next()
32918
        .ok_or_else(|| fail("un_op.iter().next"))?;
    // 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.
32918
    let arg = match value {
32918
        Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
4212
            let comprehension_kind = match key.as_str() {
4212
                "MkOpOr" => Some(ACOperatorKind::Or),
3028
                "MkOpAnd" => Some(ACOperatorKind::And),
770
                "MkOpSum" => Some(ACOperatorKind::Sum),
210
                "MkOpProduct" => Some(ACOperatorKind::Product),
210
                _ => None,
            };
4212
            parse_comprehension(comprehension, scope.clone(), comprehension_kind)
4212
                .map_err(|_| fail("value.Comprehension.parse_comprehension"))
        }
28706
        _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
    }
32918
    .map_err(|_| fail("arg"))?;
32918
    let constructor =
32918
        unary_operator(key.as_str(), Some(&arg)).ok_or_else(|| fail("unary_operator"))?;
32918
    Ok(constructor(Metadata::new(), Moo::new(arg)))
32918
}
// Takes in { AbstractLiteral: .... }
16512
fn parse_abstract_matrix_as_expr(
16512
    value: &serde_json::Value,
16512
    scope: &SymbolTablePtr,
16512
) -> Result<Expression> {
16512
    parser_trace!("trying to parse an abstract literal matrix");
15532
    let (values, domain_name, domain_value) =
16512
        if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
13802
            parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
13802
            let (domain_name, domain_value) = abs_lit_matrix
13802
                .pointer("/0")
13802
                .and_then(Value::as_object)
13802
                .and_then(|x| x.iter().next())
13802
                .ok_or(error!("AbsLitMatrix missing domain"))?;
13802
            let values = abs_lit_matrix
13802
                .pointer("/1")
13802
                .ok_or(error!("AbsLitMatrix missing values"))?;
13802
            Some((values, domain_name, domain_value))
        }
        // the input of this expression is constant - e.g. or([]), or([false]), min([2]), etc.
980
        else if let Some(const_abs_lit_matrix) =
2710
            value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
        {
980
            parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
980
            let (domain_name, domain_value) = const_abs_lit_matrix
980
                .pointer("/0")
980
                .and_then(Value::as_object)
980
                .and_then(|x| x.iter().next())
980
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
980
            let values = const_abs_lit_matrix
980
                .pointer("/1")
980
                .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
980
            Some((values, domain_name, domain_value))
1730
        } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
750
            parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
750
            let (domain_name, domain_value) = const_abs_lit_matrix
750
                .pointer("/0")
750
                .and_then(Value::as_object)
750
                .and_then(|x| x.iter().next())
750
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
750
            let values = const_abs_lit_matrix
750
                .pointer("/1")
750
                .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
750
            Some((values, domain_name, domain_value))
        } else {
980
            None
        }
16512
        .ok_or(error!("Could not parse abstract literal matrix"))?;
15532
    parser_trace!(".. found in domain and values in JSON:");
15532
    parser_trace!(".. .. index domain name {domain_name}");
15532
    parser_trace!(".. .. values {value}");
15532
    let args_parsed = values
15532
        .as_array()
15532
        .ok_or(error!("Matrix values are not an array"))?
15532
        .iter()
33354
        .map(|x| parse_expression(x, scope))
15532
        .collect::<Result<Vec<Expression>>>()?;
15532
    if !args_parsed.is_empty() {
15492
        parser_trace!(
            ".. successfully parsed values as expressions: {}, ... ",
64
            args_parsed[0]
        );
    } else {
40
        parser_trace!(".. successfully parsed empty values ",);
    }
15532
    let mut symbols = scope.write();
15532
    match parse_domain(domain_name, domain_value, &mut symbols) {
15532
        Ok(domain) => {
15532
            parser_trace!("... sucessfully parsed domain as {domain}");
15532
            Ok(into_matrix_expr![args_parsed;domain])
        }
        Err(_) => {
            parser_trace!("... failed to parse domain, creating a matrix without one.");
            Ok(into_matrix_expr![args_parsed])
        }
    }
16512
}
161940
fn parse_constant(
161940
    constant: &serde_json::Map<String, Value>,
161940
    scope: &SymbolTablePtr,
161940
) -> Result<Expression> {
161940
    match &constant.get("Constant") {
146530
        Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
141640
            let int_32: i32 = match int["ConstantInt"]
141640
                .as_array()
141640
                .ok_or(error!("ConstantInt is not an array"))?[1]
141640
                .as_i64()
141640
                .ok_or(error!("ConstantInt does not contain int"))?
141640
                .try_into()
            {
141640
                Ok(x) => x,
                Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
            };
141640
            Ok(Expression::Atomic(
141640
                Metadata::new(),
141640
                Atom::Literal(Literal::Int(int_32)),
141640
            ))
        }
4890
        Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
942
            let b: bool = b["ConstantBool"]
942
                .as_bool()
942
                .ok_or(error!("ConstantBool does not contain bool"))?;
942
            Ok(Expression::Atomic(
942
                Metadata::new(),
942
                Atom::Literal(Literal::Bool(b)),
942
            ))
        }
3948
        Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
3948
            if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
3948
                if let Some(arr) = obj.get("AbsLitSet") {
2288
                    return parse_abs_lit(arr, scope);
1660
                } else if let Some(arr) = obj.get("AbsLitMSet") {
40
                    return parse_abs_mset(arr, scope);
1620
                } else if let Some(arr) = obj.get("AbsLitMatrix") {
980
                    return parse_abstract_matrix_as_expr(arr, scope);
640
                } else if let Some(arr) = obj.get("AbsLitTuple") {
240
                    return parse_abs_tuple(arr, scope);
400
                } else if let Some(arr) = obj.get("AbsLitRecord") {
80
                    return parse_abs_record(arr, scope);
320
                } else if let Some(arr) = obj.get("AbsLitPartition") {
40
                    return parse_abs_partition(arr, scope);
280
                } else if let Some(arr) = obj.get("AbsLitFunction") {
80
                    return parse_abs_function(arr, scope);
200
                } else if let Some(arr) = obj.get("AbsLitVariant") {
                    return parse_abs_variant(arr, scope);
200
                } else if let Some(arr) = obj.get("AbsLitRelation") {
80
                    return parse_abs_relation(arr, scope);
120
                } else if let Some(arr) = obj.get("AbsLitSequence") {
120
                    return parse_abs_sequence(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 => {
15410
            let int_expr = constant
15410
                .get("ConstantInt")
15410
                .and_then(|x| x.as_array())
15410
                .and_then(|x| x[1].as_i64())
15410
                .and_then(|x| x.try_into().ok())
15410
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
15410
            if let Some(expr) = int_expr {
15130
                return Ok(expr);
280
            }
280
            let bool_expr = constant
280
                .get("ConstantBool")
280
                .and_then(|x| x.as_bool())
280
                .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
280
            if let Some(expr) = bool_expr {
280
                return Ok(expr);
            }
            Err(error!(format!("Unhandled parse_constant {constant:#?}")))
        }
        otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
    }
161940
}