1#![allow(clippy::unwrap_used)]
2#![allow(clippy::expect_used)]
3use std::sync::{Arc, RwLock};
4use ustr::Ustr;
5
6use serde_json::Map as JsonMap;
7use serde_json::Value;
8use serde_json::Value as JsonValue;
9
10use crate::ast::Moo;
11use crate::ast::PartitionAttr;
12use crate::ast::Typeable;
13use crate::ast::ac_operators::ACOperatorKind;
14use crate::ast::comprehension::ComprehensionBuilder;
15use crate::ast::records::FieldValue;
16use 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};
21use crate::ast::{DomainPtr, Metadata};
22use crate::context::Context;
23use crate::error::{Error, Result};
24use crate::{Model, bug, error, into_matrix_expr, throw_error};
25
26#[allow(unused_macros)]
27macro_rules! parser_trace {
28 ($($arg:tt)+) => {
29 log::trace!(target:"jsonparser",$($arg)+)
30 };
31}
32
33#[allow(unused_macros)]
34macro_rules! parser_debug {
35 ($($arg:tt)+) => {
36 log::debug!(target:"jsonparser",$($arg)+)
37 };
38}
39
40pub fn model_from_json(str: &str, context: Arc<RwLock<Context<'static>>>) -> Result<Model> {
41 let mut m = Model::new(context);
42 let v: JsonValue = serde_json::from_str(str)?;
43 let statements = v["mStatements"]
44 .as_array()
45 .ok_or(error!("mStatements is not an array"))?;
46
47 for statement in statements {
48 let entry = statement
49 .as_object()
50 .ok_or(error!("mStatements contains a non-object"))?
51 .iter()
52 .next()
53 .ok_or(error!("mStatements contains an empty object"))?;
54
55 match entry.0.as_str() {
56 "Declaration" => {
57 let decl = entry
58 .1
59 .as_object()
60 .ok_or(error!("Declaration is not an object".to_owned()))?;
61
62 let mut valid_decl: bool = false;
69 let scope = m.symbols_ptr_unchecked().clone();
70 let model = &mut m;
71 for (kind, value) in decl {
72 match kind.as_str() {
73 "FindOrGiven" => {
74 parse_variable(value, &mut model.symbols_mut())?;
75 valid_decl = true;
76 break;
77 }
78 "Letting" => {
79 parse_letting(value, &scope)?;
80 valid_decl = true;
81 break;
82 }
83 _ => continue,
84 }
85 }
86
87 if !valid_decl {
88 throw_error!("Declaration is not a valid kind")?;
89 }
90 }
91 "SuchThat" => {
92 let constraints_arr = match entry.1.as_array() {
93 Some(x) => x,
94 None => bug!("SuchThat is not a vector"),
95 };
96
97 let constraints: Vec<Expression> = constraints_arr
98 .iter()
99 .map(|x| parse_expression(x, m.symbols_ptr_unchecked()))
100 .collect::<Result<Vec<_>>>()?;
101 m.add_constraints(constraints);
102 }
103 otherwise => bug!("Unhandled Statement {:#?}", otherwise),
104 }
105 }
106 Ok(m)
107}
108
109fn parse_variable(v: &JsonValue, symtab: &mut SymbolTable) -> Result<()> {
110 let arr = v.as_array().ok_or(error!("FindOrGiven is not an array"))?;
111
112 let variable_type = arr[0]
113 .as_str()
114 .ok_or(error!("FindOrGiven[0] is not a string"))?;
115
116 let name = arr[1]
117 .as_object()
118 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
119 .as_str()
120 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
121
122 let name = Name::User(Ustr::from(name));
123
124 let domain = arr[2]
125 .as_object()
126 .ok_or(error!("FindOrGiven[2] is not an object"))?
127 .iter()
128 .next()
129 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
130
131 let domain = parse_domain(domain.0, domain.1, symtab)?;
132
133 let decl = match variable_type {
134 "Find" => DeclarationPtr::new_find(name.clone(), domain),
135 "Given" => DeclarationPtr::new_given(name.clone(), domain),
136 _ => {
137 return Err(error!("FindOrGiven[0] is not 'Find' or 'Given'"));
138 }
139 };
140
141 symtab.insert(decl).ok_or(Error::Parse(format!(
142 "Could not add {name} to symbol table as it already exists"
143 )))
144}
145
146fn parse_letting(v: &JsonValue, scope: &SymbolTablePtr) -> Result<()> {
147 let arr = v.as_array().ok_or(error!("Letting is not an array"))?;
148 let name = arr[0]
149 .as_object()
150 .ok_or(error!("Letting[0] is not an object"))?["Name"]
151 .as_str()
152 .ok_or(error!("Letting[0].Name is not a string"))?;
153 let name = Name::User(Ustr::from(name));
154 if let Ok(value) = parse_expression(&arr[1], scope) {
156 let mut symtab = scope.write();
157 symtab
158 .insert(DeclarationPtr::new_value_letting(name.clone(), value))
159 .ok_or(Error::Parse(format!(
160 "Could not add {name} to symbol table as it already exists"
161 )))
162 } else {
163 let domain = &arr[1]
165 .as_object()
166 .ok_or(error!("Letting[1] is not an object".to_owned()))?["Domain"]
167 .as_object()
168 .ok_or(error!("Letting[1].Domain is not an object"))?
169 .iter()
170 .next()
171 .ok_or(error!("Letting[1].Domain is an empty object"))?;
172
173 let mut symtab = scope.write();
174 let domain = parse_domain(domain.0, domain.1, &mut symtab)?;
175
176 symtab
177 .insert(DeclarationPtr::new_domain_letting(name.clone(), domain))
178 .ok_or(Error::Parse(format!(
179 "Could not add {name} to symbol table as it already exists"
180 )))
181 }
182}
183
184fn parse_domain(
185 domain_name: &str,
186 domain_value: &JsonValue,
187 symbols: &mut SymbolTable,
188) -> Result<DomainPtr> {
189 match domain_name {
190 "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
191 "DomainBool" => Ok(Domain::bool()),
192 "DomainReference" => {
193 let name = Name::user(
194 domain_value
195 .as_array()
196 .ok_or(error!("DomainReference is not an array"))?[0]
197 .as_object()
198 .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
199 .as_str()
200 .ok_or(error!("DomainReference[0].Name is not a string"))?,
201 );
202 let ptr = symbols
203 .lookup(&name)
204 .ok_or(error!(format!("Name {name} not found")))?;
205 let dom =
206 Domain::reference(ptr).ok_or(error!("Could not construct reference domain"))?;
207 Ok(dom)
208 }
209 "DomainSet" => {
210 let dom = domain_value.get(2).and_then(|v| v.as_object());
211 let domain_obj = dom.ok_or(error!("DomainSet is missing domain object"))?;
212 let domain = domain_obj
213 .iter()
214 .next()
215 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
216 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
217 let size = domain_value
218 .get(1)
219 .and_then(|v| v.as_object())
220 .ok_or(error!("Set size attributes is not an object"))?;
221 let size = parse_size_attr(size, symbols)?;
222 let attr: SetAttr<IntVal> = SetAttr { size };
223 Ok(Domain::set(attr, domain))
224 }
225 "DomainMSet" => {
226 let dom = domain_value
227 .get(2)
228 .and_then(|v| v.as_object())
229 .expect("domain object exists");
230 let domain = dom
231 .iter()
232 .next()
233 .ok_or(Error::Parse("DomainMSet is an empty object".to_owned()))?;
234 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
235
236 let attributes = domain_value
238 .get(1)
239 .and_then(|v| v.as_array())
240 .ok_or(error!("MSet attributes is not a json array"))?;
241
242 let size = attributes
243 .first()
244 .and_then(|v| v.as_object())
245 .ok_or(error!("MSet size attributes is not an object"))?;
246 let size = parse_size_attr(size, symbols)?;
247
248 let occurrence = attributes
249 .get(1)
250 .and_then(|v| v.as_object())
251 .ok_or(error!("MSet occurrence attributes is not an object"))?;
252 let occurrence = parse_occur_attr(occurrence, symbols)?;
253
254 let attr: MSetAttr<IntVal> = MSetAttr { size, occurrence };
255 Ok(Domain::mset(attr, domain))
256 }
257 "DomainPartition" => {
258 let dom = domain_value
259 .get(2)
260 .and_then(|v| v.as_object())
261 .expect("domain object exists");
262 let domain = dom.iter().next().ok_or(Error::Parse(
263 "DomainPartition is an empty object".to_owned(),
264 ))?;
265 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
266
267 let attributes = domain_value
268 .get(1)
269 .and_then(|v| v.as_object())
270 .ok_or(error!("Partition attributes is not an object"))?;
271
272 let mut num_parts = Range::Unbounded;
273 let mut part_len = Range::Unbounded;
274 let mut is_regular = false;
275
276 if let Some(val) = attributes.get("partsNum") {
277 let attr_map = val.as_object().expect("numParts should be an object");
278 num_parts = parse_size_attr(attr_map, symbols)?;
279 }
280 if let Some(val) = attributes.get("partsSize") {
281 let attr_map = val.as_object().expect("partsSize should be an object");
282 part_len = parse_size_attr(attr_map, symbols)?;
283 }
284 if let Some(val) = attributes.get("isRegular").and_then(|v| v.as_bool()) {
285 is_regular = val;
286 }
287
288 let attr: PartitionAttr<IntVal> = PartitionAttr {
289 num_parts,
290 part_len,
291 is_regular,
292 };
293 Ok(Domain::partition(attr, domain))
294 }
295 "DomainMatrix" => {
296 let domain_value = domain_value
297 .as_array()
298 .ok_or(error!("Domain matrix is not an array"))?;
299
300 let indexed_by_domain = domain_value[0].clone();
301 let (index_domain_name, index_domain_value) = indexed_by_domain
302 .as_object()
303 .ok_or(error!("DomainMatrix[0] is not an object"))?
304 .iter()
305 .next()
306 .ok_or(error!(""))?;
307
308 let (value_domain_name, value_domain_value) = domain_value[1]
309 .as_object()
310 .ok_or(error!(""))?
311 .iter()
312 .next()
313 .ok_or(error!(""))?;
314
315 let mut index_domains: Vec<DomainPtr> = vec![];
320
321 index_domains.push(parse_domain(
322 index_domain_name,
323 index_domain_value,
324 symbols,
325 )?);
326
327 let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
333 while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
334 index_domains.append(&mut indices);
335 value_domain = new_value_domain.clone()
336 }
337
338 Ok(Domain::matrix(value_domain, index_domains))
339 }
340
341 "DomainSequence" => {
342 let dom = domain_value
343 .get(2)
344 .and_then(|v| v.as_object())
345 .expect("domain object exists");
346 let domain = dom
347 .iter()
348 .next()
349 .ok_or(Error::Parse("DomainSequence is an empty object".to_owned()))?;
350 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
351
352 let attributes = domain_value
354 .get(1)
355 .and_then(|v| v.as_array())
356 .ok_or(error!("Sequence attributes is not a json array"))?;
357
358 let size = attributes
359 .first()
360 .and_then(|v| v.as_object())
361 .ok_or(error!("Sequence size attributes is not an object"))?;
362 let size = parse_size_attr(size, symbols)?;
363
364 let jectivity = attributes
365 .get(1)
366 .and_then(|v| v.as_str())
367 .ok_or(error!("jectivity is not a string"))?;
368 let jectivity = match jectivity {
369 "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
370 "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
371 "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
372 "JectivityAttr_None" => Some(JectivityAttr::None),
373 _ => None,
374 };
375 let jectivity =
376 jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
377
378 let attr: SequenceAttr<IntVal> = SequenceAttr { size, jectivity };
379 match attr.size {
380 Range::Unbounded | Range::UnboundedR(_) => Err(Error::Parse(
381 "Sequence must have size or maxSize attribute".to_string(),
382 )),
383 _ => Ok(Domain::sequence(attr, domain)),
384 }
385 }
386
387 "DomainTuple" => {
388 let domain_value = domain_value
389 .as_array()
390 .ok_or(error!("Domain tuple is not an array"))?;
391
392 let domain = domain_value
394 .iter()
395 .map(|x| {
396 let domain = x
397 .as_object()
398 .ok_or(error!("DomainTuple[0] is not an object"))?
399 .iter()
400 .next()
401 .ok_or(error!("DomainTuple[0] is an empty object"))?;
402 parse_domain(domain.0, domain.1, symbols)
403 })
404 .collect::<Result<Vec<DomainPtr>>>()?;
405
406 Ok(Domain::tuple(domain))
407 }
408 "DomainRecord" | "DomainVariant" => {
409 let is_record = domain_name == "DomainRecord";
411 let domain_string = match is_record {
413 true => "Record",
414 false => "Variant",
415 };
416 let domain_value = domain_value.as_array().ok_or(error!(&format!(
417 "Domain {domain_string} is not a json array"
418 )))?;
419
420 let mut entries = vec![];
421
422 for item in domain_value {
423 let name = item[0]
425 .as_object()
426 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
427 .as_str()
428 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
429
430 let name = Name::User(Ustr::from(name));
431 let domain = item[1]
433 .as_object()
434 .ok_or(error!("FindOrGiven[2] is not an object"))?
435 .iter()
436 .next()
437 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
438
439 let domain = parse_domain(domain.0, domain.1, symbols)?;
440
441 let rec = FieldEntry { name, domain };
442
443 entries.push(rec);
444 }
445
446 for decl in entries
448 .iter()
449 .cloned()
450 .map(DeclarationPtr::new_record_field)
451 {
452 symbols.insert(decl).ok_or(error!(
453 "record field should not already be in the symbol table"
454 ))?;
455 }
456 if is_record {
457 Ok(Domain::record(entries))
458 } else {
459 Ok(Domain::variant(entries))
460 }
461 }
462 "DomainFunction" => {
463 let domain = domain_value
464 .get(2)
465 .and_then(|v| v.as_object())
466 .ok_or(error!("Function domain is not an object"))?;
467 let domain = domain
468 .iter()
469 .next()
470 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
471 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
472
473 let codomain = domain_value
474 .get(3)
475 .and_then(|v| v.as_object())
476 .ok_or(error!("Function codomain is not an object"))?;
477 let codomain = codomain
478 .iter()
479 .next()
480 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
481 let codomain = parse_domain(codomain.0.as_str(), codomain.1, symbols)?;
482
483 let attributes = domain_value
485 .get(1)
486 .and_then(|v| v.as_array())
487 .ok_or(error!("Function attributes is not a json array"))?;
488 let size = attributes
489 .first()
490 .and_then(|v| v.as_object())
491 .ok_or(error!("Function size attributes is not an object"))?;
492 let size = parse_size_attr(size, symbols)?;
493 let partiality = attributes
494 .get(1)
495 .and_then(|v| v.as_str())
496 .ok_or(error!("Function partiality is not a string"))?;
497 let partiality = match partiality {
498 "PartialityAttr_Partial" => Some(PartialityAttr::Partial),
499 "PartialityAttr_Total" => Some(PartialityAttr::Total),
500 _ => None,
501 };
502 let partiality =
503 partiality.ok_or(Error::Parse("Partiality is an unknown type".to_owned()))?;
504 let jectivity = attributes
505 .get(2)
506 .and_then(|v| v.as_str())
507 .ok_or(error!("Function jectivity is not a string"))?;
508 let jectivity = match jectivity {
509 "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
510 "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
511 "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
512 "JectivityAttr_None" => Some(JectivityAttr::None),
513 _ => None,
514 };
515 let jectivity =
516 jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
517
518 let attr: FuncAttr<IntVal> = FuncAttr {
519 size,
520 partiality,
521 jectivity,
522 };
523
524 Ok(Domain::function(attr, domain, codomain))
525 }
526
527 "DomainRelation" => {
528 let domains = domain_value
529 .get(2)
530 .and_then(|v| v.as_array())
531 .ok_or(Error::Parse(
532 "Relation domains are not a json array".to_owned(),
533 ))?;
534 let domains = domains
535 .iter()
536 .map(|x| {
537 let domain = x
538 .as_object()
539 .ok_or(Error::Parse("Relation domain is not an object".to_owned()))?
540 .iter()
541 .next()
542 .ok_or(Error::Parse(
543 "Relation domain is an empty object".to_owned(),
544 ))?;
545 parse_domain(domain.0, domain.1, symbols)
546 })
547 .collect::<Result<Vec<DomainPtr>>>()?;
548
549 let attributes = domain_value
551 .get(1)
552 .and_then(|v| v.as_array())
553 .ok_or(Error::Parse(
554 "Relation attributes are not a json array".to_owned(),
555 ))?;
556 let size = attributes
557 .first()
558 .and_then(|v| v.as_object())
559 .ok_or(Error::Parse(
560 "Relation size attributes are not an object".to_owned(),
561 ))?;
562 let size = parse_size_attr(size, symbols)?;
563 let binary = attributes
564 .get(1)
565 .and_then(|v| v.as_array())
566 .ok_or(Error::Parse(
567 "Relation binary attributes are not a json array".to_owned(),
568 ))?;
569 let binary = binary
570 .iter()
571 .map(|x| {
572 let attr = x.as_str().ok_or(Error::Parse(
573 "Relation binary attribute is not a string".to_owned(),
574 ))?;
575 match attr {
576 "BinRelAttr_Reflexive" => Ok(BinaryAttr::Reflexive),
577 "BinRelAttr_Irreflexive" => Ok(BinaryAttr::Irreflexive),
578 "BinRelAttr_Coreflexive" => Ok(BinaryAttr::Coreflexive),
579 "BinRelAttr_Symmetric" => Ok(BinaryAttr::Symmetric),
580 "BinRelAttr_AntiSymmetric" => Ok(BinaryAttr::AntiSymmetric),
581 "BinRelAttr_ASymmetric" => Ok(BinaryAttr::ASymmetric),
582 "BinRelAttr_Transitive" => Ok(BinaryAttr::Transitive),
583 "BinRelAttr_Total" => Ok(BinaryAttr::Total),
584 "BinRelAttr_Connex" => Ok(BinaryAttr::Connex),
585 "BinRelAttr_Euclidean" => Ok(BinaryAttr::Euclidean),
586 "BinRelAttr_Serial" => Ok(BinaryAttr::Serial),
587 "BinRelAttr_Equivalence" => Ok(BinaryAttr::Equivalence),
588 "BinRelAttr_PartialOrder" => Ok(BinaryAttr::PartialOrder),
589 _ => Err(Error::Parse(
590 "Relation binary attribute is invalid".to_owned(),
591 )),
592 }
593 })
594 .collect::<Result<Vec<BinaryAttr>>>()?;
595
596 let attr: RelAttr<IntVal> = RelAttr { size, binary };
597
598 Ok(Domain::relation(attr, domains))
599 }
600 _ => Err(Error::Parse(
601 "FindOrGiven[2] is an unknown object".to_owned(), )),
603 }
604}
605
606fn parse_size_attr(
607 attr_map: &JsonMap<String, JsonValue>,
608 symbols: &mut SymbolTable,
609) -> Result<Range<IntVal>> {
610 let scope = SymbolTablePtr::new();
611 *scope.write() = symbols.clone();
612
613 let attr_obj = attr_map
614 .iter()
615 .next()
616 .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
617 match attr_obj.0.as_str() {
618 "SizeAttr_None" => Ok(Range::Unbounded),
619 "SizeAttr_MinSize" => {
620 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
621 Ok(Range::UnboundedR(size))
622 }
623 "SizeAttr_MaxSize" => {
624 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
625 Ok(Range::UnboundedL(size))
626 }
627 "SizeAttr_MinMaxSize" => {
628 let min_max = attr_obj
629 .1
630 .as_array()
631 .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
632 let min = min_max
633 .first()
634 .ok_or(error!("SizeAttr Min is not present"))?;
635 let min_int = parse_expression_to_int_val(min, &scope)?;
636 let max = min_max
637 .get(1)
638 .ok_or(error!("SizeAttr Max is not present"))?;
639 let max_int = parse_expression_to_int_val(max, &scope)?;
640 Ok(Range::Bounded(min_int, max_int))
641 }
642 "SizeAttr_Size" => {
643 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
644 Ok(Range::Single(size))
645 }
646 _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
647 }
648}
649
650fn parse_occur_attr(
651 attr_map: &JsonMap<String, JsonValue>,
652 symbols: &mut SymbolTable,
653) -> Result<Range<IntVal>> {
654 let scope = SymbolTablePtr::new();
655 *scope.write() = symbols.clone();
656 let attr_obj = attr_map
657 .iter()
658 .next()
659 .ok_or(Error::Parse("OccurAttr is an empty object".to_owned()))?;
660 match attr_obj.0.as_str() {
661 "OccurAttr_None" => Ok(Range::Unbounded),
662 "OccurAttr_MinOccur" => {
663 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
664 Ok(Range::UnboundedR(size_int))
665 }
666 "OccurAttr_MaxOccur" => {
667 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
668 Ok(Range::UnboundedL(size_int))
669 }
670 "OccurAttr_MinMaxOccur" => {
671 let min_max = attr_obj
672 .1
673 .as_array()
674 .ok_or(error!("OccurAttr MinMaxOccur is not a json array"))?;
675 let min = min_max
676 .first()
677 .ok_or(error!("OccurAttr Min is not present"))?;
678 let min_int = parse_expression_to_int_val(min, &scope)?;
679 let max = min_max
680 .get(1)
681 .ok_or(error!("OccurAttr Max is not present"))?;
682 let max_int = parse_expression_to_int_val(max, &scope)?;
683 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}
692
693fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<DomainPtr> {
694 let scope = SymbolTablePtr::new();
695 *scope.write() = symbols.clone();
696
697 let mut ranges = Vec::new();
698 let arr = v
699 .as_array()
700 .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
701 .as_array()
702 .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
703 for range in arr {
704 let range = range
705 .as_object()
706 .ok_or(error!("DomainInt[1] contains a non-object"))?
707 .iter()
708 .next()
709 .ok_or(error!("DomainInt[1] contains an empty object"))?;
710 match range.0.as_str() {
711 "RangeBounded" => {
712 let arr = range
713 .1
714 .as_array()
715 .ok_or(error!("RangeBounded is not an array".to_owned()))?;
716 let mut nums = Vec::new();
717 for item in arr.iter() {
718 let num = parse_expression_to_int_val(item, &scope)?;
719 nums.push(num);
720 }
721 let lower = nums
722 .first()
723 .cloned()
724 .ok_or(error!("RangeBounded lower bound missing"))?;
725 let upper = nums
726 .get(1)
727 .cloned()
728 .ok_or(error!("RangeBounded upper bound missing"))?;
729 ranges.push(Range::Bounded(lower, upper));
730 }
731 "RangeSingle" => {
732 let num = parse_expression_to_int_val(range.1, &scope)?;
733 ranges.push(Range::Single(num));
734 }
735 _ => return throw_error!("DomainInt[1] contains an unknown object"),
736 }
737 }
738 Ok(Domain::int(ranges))
739}
740
741fn parse_expression_to_int_val(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<IntVal> {
742 parser_trace!("trying to parse domain value as expression: {}", obj);
743 let expr = parse_expression(obj, scope)?;
744
745 if let Some(Literal::Int(i)) = expr.clone().into_literal() {
746 return Ok(IntVal::Const(i));
747 }
748
749 if let Expression::Atomic(_, Atom::Reference(reference)) = &expr
750 && let Some(reference_val) = IntVal::new_ref(reference)
751 {
752 return Ok(reference_val);
753 }
754
755 IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
756}
757
758type BinOp = fn(Metadata, Moo<Expression>, Moo<Expression>) -> Expression;
759type UnaryOp = fn(Metadata, Moo<Expression>) -> Expression;
760
761fn binary_operator(op_name: &str) -> Option<BinOp> {
762 match op_name {
763 "MkOpIn" => Some(Expression::In),
764 "MkOpUnion" => Some(Expression::Union),
765 "MkOpIntersect" => Some(Expression::Intersect),
766 "MkOpSupset" => Some(Expression::Supset),
767 "MkOpSupsetEq" => Some(Expression::SupsetEq),
768 "MkOpSubset" => Some(Expression::Subset),
769 "MkOpSubsetEq" => Some(Expression::SubsetEq),
770 "MkOpEq" => Some(Expression::Eq),
771 "MkOpNeq" => Some(Expression::Neq),
772 "MkOpGeq" => Some(Expression::Geq),
773 "MkOpLeq" => Some(Expression::Leq),
774 "MkOpGt" => Some(Expression::Gt),
775 "MkOpLt" => Some(Expression::Lt),
776 "MkOpLexLt" => Some(Expression::LexLt),
777 "MkOpLexGt" => Some(Expression::LexGt),
778 "MkOpLexLeq" => Some(Expression::LexLeq),
779 "MkOpLexGeq" => Some(Expression::LexGeq),
780 "MkOpDiv" => Some(Expression::UnsafeDiv),
781 "MkOpMod" => Some(Expression::UnsafeMod),
782 "MkOpMinus" => Some(Expression::Minus),
783 "MkOpImply" => Some(Expression::Imply),
784 "MkOpIff" => Some(Expression::Iff),
785 "MkOpPow" => Some(Expression::UnsafePow),
786 "MkOpImage" => Some(Expression::Image),
787 "MkOpImageSet" => Some(Expression::ImageSet),
788 "MkOpPreImage" => Some(Expression::PreImage),
789 "MkOpInverse" => Some(Expression::Inverse),
790 "MkOpRestrict" => Some(Expression::Restrict),
791 "MkOpApart" => Some(Expression::Apart),
792 "MkOpTogether" => Some(Expression::Together),
793 "MkOpParty" => Some(Expression::Party),
794 "MkOpActive" => Some(Expression::Active),
795 "MkOpSubstring" => Some(Expression::Substring),
796 "MkOpSubsequence" => Some(Expression::Subsequence),
797 _ => None,
798 }
799}
800
801fn unary_operator(op_name: &str, inner: Option<&Expression>) -> Option<UnaryOp> {
802 match op_name {
803 "MkOpNot" => Some(Expression::Not),
804 "MkOpNegate" => Some(Expression::Neg),
805 "MkOpTwoBars" => {
806 if let Some(inner) = inner {
807 match inner.return_type() {
808 ReturnType::Int => Some(Expression::Abs),
809 ReturnType::Matrix(_)
810 | ReturnType::Set(_)
811 | ReturnType::MSet(_)
812 | ReturnType::Relation(_)
813 | ReturnType::Function(_, _) => Some(Expression::Card),
814 _ => None,
815 }
816 } else {
817 Some(Expression::Abs)
819 }
820 }
821 "MkOpAnd" => Some(Expression::And),
822 "MkOpSum" => Some(Expression::Sum),
823 "MkOpProduct" => Some(Expression::Product),
824 "MkOpOr" => Some(Expression::Or),
825 "MkOpMin" => Some(Expression::Min),
826 "MkOpMax" => Some(Expression::Max),
827 "MkOpAllDiff" => Some(Expression::AllDiff),
828 "MkOpToInt" => Some(Expression::ToInt),
829 "MkOpDefined" => Some(Expression::Defined),
830 "MkOpRange" => Some(Expression::Range),
831 "MkOpFactorial" => Some(Expression::Factorial),
832 "MkOpToMSet" => Some(Expression::ToMSet),
833 "MkOpToRelation" => Some(Expression::ToRelation),
834 "MkOpParticipants" => Some(Expression::Participants),
835 "MkOpParts" => Some(Expression::Parts),
836 _ => None,
837 }
838}
839
840pub fn parse_expression(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<Expression> {
841 let fail = |stage: &str| -> Error {
842 Error::Parse(format!(
843 "Could not parse expression at stage `{stage}` for json `{obj}`"
844 ))
845 };
846
847 match obj {
848 Value::Object(op) if op.contains_key("Op") => {
849 let op_obj = op
850 .get("Op")
851 .and_then(Value::as_object)
852 .ok_or_else(|| fail("Op.as_object"))?;
853 let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
854
855 if op_obj.contains_key("MkOpFlatten") {
856 parse_flatten_op(op_obj, scope)
857 } else if op_obj.contains_key("MkOpTable") {
858 parse_table_op(op_obj, scope)
859 } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
860 parse_indexing_slicing_op(op_obj, scope)
861 } else if op_obj.contains_key("MkOpRelationProj") {
862 parse_relation_projection(op_obj, scope)
863 } else if op_obj.contains_key("MkOpToSet") {
864 parse_to_set(op_obj, scope)
865 } else if binary_operator(op_name).is_some() {
866 parse_bin_op(op_obj, scope)
867 } else if unary_operator(op_name, None).is_some() {
868 parse_unary_op(op_obj, scope)
869 } else {
870 Err(fail("Op.unknown"))
871 }
872 }
873 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
874 parse_comprehension(comprehension, scope.clone(), None)
875 }
876 Value::Object(refe) if refe.contains_key("Reference") => {
877 let ref_arr = refe["Reference"]
878 .as_array()
879 .ok_or_else(|| fail("Reference.as_array"))?;
880 let ref_obj = ref_arr
881 .first()
882 .and_then(|x| x.as_object())
883 .ok_or_else(|| fail("Reference[0].as_object"))?;
884 let name = ref_obj
885 .get("Name")
886 .and_then(|x| x.as_str())
887 .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
888 let user_name = Name::User(Ustr::from(name));
889
890 let declaration: DeclarationPtr = scope
891 .read()
892 .lookup(&user_name)
893 .ok_or_else(|| fail("Reference.lookup"))?;
894
895 Ok(Expression::Atomic(
896 Metadata::new(),
897 Atom::Reference(crate::ast::Reference::new(declaration)),
898 ))
899 }
900 Value::Object(refe) if refe.contains_key("Name") => {
902 let name = refe
903 .get("Name")
904 .and_then(|x| x.as_str())
905 .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
906 let user_name = Name::User(Ustr::from(name));
907
908 let declaration: DeclarationPtr = scope
909 .read()
910 .lookup(&user_name)
911 .ok_or_else(|| fail("Reference.lookup"))?;
912
913 Ok(Expression::Atomic(
914 Metadata::new(),
915 Atom::Reference(crate::ast::Reference::new(declaration)),
916 ))
917 }
918 Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
919 let abstract_literal = abslit["AbstractLiteral"]
920 .as_object()
921 .ok_or_else(|| fail("AbstractLiteral.as_object"))?;
922
923 if abstract_literal.contains_key("AbsLitSet") {
924 parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
925 } else if abstract_literal.contains_key("AbsLitFunction") {
926 parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
927 } else if abstract_literal.contains_key("AbsLitMSet") {
928 parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
929 } else if abstract_literal.contains_key("AbsLitVariant") {
930 parse_abs_variant(&abslit["AbstractLiteral"]["AbsLitVariant"], scope)
931 } else if abstract_literal.contains_key("AbsLitRelation") {
932 parse_abs_relation(&abslit["AbstractLiteral"]["AbsLitRelation"], scope)
933 } else if abstract_literal.contains_key("AbstractLiteralPartition") {
934 parse_abs_partition(&abslit["AbstractLiteral"]["AbsLitPartition"], scope)
935 } else if abstract_literal.contains_key("AbsLitSequence") {
936 parse_abs_sequence(&abslit["AbstractLiteral"]["AbsLitSequence"], scope)
937 } else {
938 parse_abstract_matrix_as_expr(obj, scope)
939 }
940 }
941
942 Value::Object(constant) if constant.contains_key("Constant") => {
943 parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
944 }
945
946 Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
947 parse_abstract_matrix_as_expr(obj, scope)
948 }
949
950 Value::Object(constant) if constant.contains_key("ConstantInt") => {
951 parse_constant(constant, scope)
952 }
953 Value::Object(constant) if constant.contains_key("ConstantBool") => {
954 parse_constant(constant, scope)
955 }
956
957 _ => Err(fail("no_match")),
958 }
959}
960
961fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
962 let values = abs_set
963 .as_array()
964 .ok_or(error!("AbsLitSet is not an array"))?;
965 let expressions = values
966 .iter()
967 .map(|values| parse_expression(values, scope))
968 .collect::<Result<Vec<_>>>()?;
969
970 Ok(Expression::AbstractLiteral(
971 Metadata::new(),
972 AbstractLiteral::Set(expressions),
973 ))
974}
975
976fn parse_abs_mset(abs_mset: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
977 let values = abs_mset
978 .as_array()
979 .ok_or(error!("AbsLitMSet is not an array"))?;
980 let expressions = values
981 .iter()
982 .map(|values| parse_expression(values, scope))
983 .collect::<Result<Vec<_>>>()?;
984
985 Ok(Expression::AbstractLiteral(
986 Metadata::new(),
987 AbstractLiteral::MSet(expressions),
988 ))
989}
990
991fn parse_abs_partition(abs_partition: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
992 let parts = abs_partition
993 .as_array()
994 .ok_or(error!("AbsLitPartition is not an array"))?;
995
996 let mut partition: Vec<Vec<_>> = Vec::new();
997
998 for part in parts {
999 let vals = part
1000 .as_array()
1001 .ok_or(error!("Part in AbsLitPartition is not an array"))?;
1002
1003 let exprs = vals
1004 .iter()
1005 .map(|values| parse_expression(values, scope))
1006 .collect::<Result<Vec<_>>>()?;
1007
1008 partition.push(exprs);
1009 }
1010
1011 Ok(Expression::AbstractLiteral(
1012 Metadata::new(),
1013 AbstractLiteral::Partition(partition),
1014 ))
1015}
1016
1017fn parse_abs_sequence(abs_seq: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
1018 let values = abs_seq
1019 .as_array()
1020 .ok_or(error!("AbsLitSequence is not an array"))?;
1021 let expressions = values
1022 .iter()
1023 .map(|values| parse_expression(values, scope))
1024 .collect::<Result<Vec<_>>>()?;
1025
1026 Ok(Expression::AbstractLiteral(
1027 Metadata::new(),
1028 AbstractLiteral::Sequence(expressions),
1029 ))
1030}
1031
1032fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
1033 let values = abs_tuple
1034 .as_array()
1035 .ok_or(error!("AbsLitTuple is not an array"))?;
1036 let expressions = values
1037 .iter()
1038 .map(|values| parse_expression(values, scope))
1039 .collect::<Result<Vec<_>>>()?;
1040
1041 Ok(Expression::AbstractLiteral(
1042 Metadata::new(),
1043 AbstractLiteral::Tuple(expressions),
1044 ))
1045}
1046
1047fn parse_abs_record(abs_record: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
1049 let entries = abs_record
1050 .as_array()
1051 .ok_or(error!("AbsLitRecord is not an array"))?;
1052 let mut rec = vec![];
1053
1054 for entry in entries {
1055 let entry = entry
1056 .as_array()
1057 .ok_or(error!("AbsLitRecord entry is not an array"))?;
1058 let name = entry[0]
1059 .as_object()
1060 .ok_or(error!("AbsLitRecord field name is not an object"))?["Name"]
1061 .as_str()
1062 .ok_or(error!("AbsLitRecord field name is not a string"))?;
1063
1064 let value = parse_expression(&entry[1], scope)?;
1065
1066 let name = Name::User(Ustr::from(name));
1067 let rec_entry = FieldValue {
1068 name: name.clone(),
1069 value,
1070 };
1071 rec.push(rec_entry);
1072 }
1073
1074 Ok(Expression::AbstractLiteral(
1075 Metadata::new(),
1076 AbstractLiteral::Record(rec),
1077 ))
1078}
1079
1080fn parse_abs_variant(abs_variant: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
1082 let entry = abs_variant
1083 .as_array()
1084 .ok_or(error!("AbsLitVariant is not an array"))?;
1085 let name = entry[1]
1086 .as_object()
1087 .ok_or(error!("AbsLitVariant field name is not an object"))?["Name"]
1088 .as_str()
1089 .ok_or(error!("AbsLitVariant field name is not a string"))?;
1090
1091 let value = parse_expression(&entry[2], scope)?;
1092
1093 let name = Name::User(Ustr::from(name));
1094 let rec_entry = FieldValue { name, value };
1095
1096 Ok(Expression::AbstractLiteral(
1097 Metadata::new(),
1098 AbstractLiteral::Variant(Moo::new(rec_entry)),
1099 ))
1100}
1101
1102fn parse_abs_function(abs_function: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
1104 let entries = abs_function
1105 .as_array()
1106 .ok_or(error!("AbsLitFunction is not an array"))?;
1107 let mut assignments = vec![];
1108
1109 for entry in entries {
1110 let entry = entry
1111 .as_array()
1112 .ok_or(error!("Explicit function assignment is not an array"))?;
1113 let expression = entry
1114 .iter()
1115 .map(|values| parse_expression(values, scope))
1116 .collect::<Result<Vec<_>>>()?;
1117 let domain_value = expression
1118 .first()
1119 .ok_or(error!("Invalid function domain"))?;
1120 let codomain_value = expression
1121 .get(1)
1122 .ok_or(error!("Invalid function codomain"))?;
1123 let tuple = (domain_value.clone(), codomain_value.clone());
1124 assignments.push(tuple);
1125 }
1126 Ok(Expression::AbstractLiteral(
1127 Metadata::new(),
1128 AbstractLiteral::Function(assignments),
1129 ))
1130}
1131
1132fn parse_abs_relation(abs_relation: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
1134 let entries = abs_relation
1135 .as_array()
1136 .ok_or(error!("AbsLitRelation is not an array"))?;
1137 let mut assignments = vec![];
1138
1139 for entry in entries {
1140 let entry = entry
1141 .as_array()
1142 .ok_or(error!("Explicit relation assignment is not an array"))?;
1143 let expression = entry
1144 .iter()
1145 .map(|values| parse_expression(values, scope))
1146 .collect::<Result<Vec<_>>>()?;
1147 assignments.push(expression);
1148 }
1149 Ok(Expression::AbstractLiteral(
1150 Metadata::new(),
1151 AbstractLiteral::Relation(assignments),
1152 ))
1153}
1154
1155fn parse_comprehension(
1156 comprehension: &serde_json::Map<String, Value>,
1157 scope: SymbolTablePtr,
1158 comprehension_kind: Option<ACOperatorKind>,
1159) -> Result<Expression> {
1160 let fail = |stage: &str| -> Error {
1161 Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
1162 };
1163
1164 let value = &comprehension["Comprehension"];
1165 let mut comprehension = ComprehensionBuilder::new(scope.clone());
1166 let generator_symboltable = comprehension.generator_symboltable();
1167 let return_expr_symboltable = comprehension.return_expr_symboltable();
1168
1169 let generators_and_guards_array = value
1170 .pointer("/1")
1171 .and_then(Value::as_array)
1172 .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
1173 let generators_and_guards = generators_and_guards_array.iter();
1174
1175 for gen_or_guard in generators_and_guards {
1176 let gen_or_guard_obj = gen_or_guard
1177 .as_object()
1178 .ok_or_else(|| fail("generator_or_guard.as_object"))?;
1179 let (name, inner) = gen_or_guard_obj
1180 .iter()
1181 .next()
1182 .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
1183 comprehension = match name.as_str() {
1184 "Generator" => {
1185 let generator_obj = inner
1187 .as_object()
1188 .ok_or_else(|| fail("Generator.inner.as_object"))?;
1189 let (name, gen_inner) = generator_obj
1190 .iter()
1191 .next()
1192 .ok_or_else(|| fail("Generator.inner.iter().next"))?;
1193 match name.as_str() {
1194 "GenDomainNoRepr" => {
1195 let name = gen_inner
1196 .pointer("/0/Single/Name")
1197 .and_then(Value::as_str)
1198 .ok_or_else(|| {
1199 fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
1200 })?;
1201 let domain_obj = gen_inner
1202 .pointer("/1")
1203 .and_then(Value::as_object)
1204 .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
1205 let (domain_name, domain_value) = domain_obj
1206 .iter()
1207 .next()
1208 .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
1209 let domain = parse_domain(
1210 domain_name,
1211 domain_value,
1212 &mut generator_symboltable.write(),
1213 )?;
1214 comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
1215 }
1216 "GenInExpr" => {
1217 let name = gen_inner
1218 .pointer("/0/Single/Name")
1219 .and_then(Value::as_str)
1220 .ok_or_else(|| {
1221 fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
1222 })?;
1223 let generator_expr = gen_inner
1224 .pointer("/1")
1225 .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
1226 let expr = parse_expression(generator_expr, &scope)
1227 .map_err(|_| fail("GenInExpr.parse_expression"))?;
1228 comprehension.expression_generator(name.into(), expr)
1229 }
1230 _ => {
1231 bug!("unknown generator type inside comprehension {name}");
1232 }
1233 }
1234 }
1235
1236 "Condition" => {
1237 let expr = parse_expression(inner, &generator_symboltable)
1238 .map_err(|_| fail("Condition.parse_expression"))?;
1239 comprehension.guard(expr)
1240 }
1241
1242 x => {
1243 bug!("unknown field inside comprehension {x}");
1244 }
1245 }
1246 }
1247
1248 let return_expr_value = value
1249 .pointer("/0")
1250 .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
1251 let expr = parse_expression(return_expr_value, &return_expr_symboltable)
1252 .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
1253
1254 Ok(Expression::Comprehension(
1255 Metadata::new(),
1256 Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
1257 ))
1258}
1259
1260fn parse_bin_op(
1261 bin_op: &serde_json::Map<String, Value>,
1262 scope: &SymbolTablePtr,
1263) -> Result<Expression> {
1264 let (key, value) = bin_op
1267 .into_iter()
1268 .next()
1269 .ok_or(error!("Binary op object is empty"))?;
1270
1271 let constructor = binary_operator(key.as_str())
1272 .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
1273
1274 match &value {
1275 Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
1276 let arg1 = parse_expression(&bin_op_args[0], scope)?;
1277 let arg2 = parse_expression(&bin_op_args[1], scope)?;
1278 Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
1279 }
1280 _ => Err(error!("Binary operator arguments are not a 2-array")),
1281 }
1282}
1283
1284fn parse_table_op(
1285 op: &serde_json::Map<String, Value>,
1286 scope: &SymbolTablePtr,
1287) -> Result<Expression> {
1288 let args = op
1289 .get("MkOpTable")
1290 .ok_or(error!("MkOpTable missing"))?
1291 .as_array()
1292 .ok_or(error!("MkOpTable is not an array"))?;
1293
1294 if args.len() != 2 {
1295 return Err(error!("MkOpTable arguments are not a 2-array"));
1296 }
1297
1298 let tuple_expr = parse_expression(&args[0], scope)?;
1299 let allowed_rows_expr = parse_expression(&args[1], scope)?;
1300
1301 let (tuple_elems, _) = tuple_expr
1302 .clone()
1303 .unwrap_matrix_unchecked()
1304 .ok_or(error!("MkOpTable first argument is not a matrix"))?;
1305 let (allowed_rows, _) = allowed_rows_expr
1306 .clone()
1307 .unwrap_matrix_unchecked()
1308 .ok_or(error!("MkOpTable second argument is not a matrix"))?;
1309
1310 for row_expr in allowed_rows {
1311 let (row_elems, _) = row_expr
1312 .unwrap_matrix_unchecked()
1313 .ok_or(error!("MkOpTable row is not a matrix"))?;
1314
1315 if row_elems.len() != tuple_elems.len() {
1316 return Err(error!("MkOpTable row width does not match tuple width"));
1317 }
1318 }
1319
1320 Ok(Expression::Table(
1321 Metadata::new(),
1322 Moo::new(tuple_expr),
1323 Moo::new(allowed_rows_expr),
1324 ))
1325}
1326
1327fn parse_indexing_slicing_op(
1328 op: &serde_json::Map<String, Value>,
1329 scope: &SymbolTablePtr,
1330) -> Result<Expression> {
1331 let (key, value) = op
1334 .into_iter()
1335 .next()
1336 .ok_or(error!("Indexing/Slicing op object is empty"))?;
1337
1338 let mut target: Expression;
1347 let mut indices: Vec<Option<Expression>> = vec![];
1348
1349 let mut all_known = true;
1351
1352 match key.as_str() {
1353 "MkOpIndexing" => {
1354 match &value {
1355 Value::Array(op_args) if op_args.len() == 2 => {
1356 target = parse_expression(&op_args[0], scope)?;
1357 indices.push(Some(parse_expression(&op_args[1], scope)?));
1358 }
1359 _ => return Err(error!("Unknown object inside MkOpIndexing")),
1360 };
1361 }
1362
1363 "MkOpSlicing" => {
1364 all_known = false;
1365 match &value {
1366 Value::Array(op_args) if op_args.len() == 3 => {
1367 target = parse_expression(&op_args[0], scope)?;
1368 indices.push(None);
1369 }
1370 _ => return Err(error!("Unknown object inside MkOpSlicing")),
1371 };
1372 }
1373
1374 _ => return Err(error!("Unknown indexing/slicing operator")),
1375 }
1376
1377 loop {
1378 match &mut target {
1379 Expression::UnsafeIndex(_, new_target, new_indices) => {
1380 indices.extend(new_indices.iter().cloned().rev().map(Some));
1381 target = Moo::unwrap_or_clone(new_target.clone());
1382 }
1383
1384 Expression::UnsafeSlice(_, new_target, new_indices) => {
1385 all_known = false;
1386 indices.extend(new_indices.iter().cloned().rev());
1387 target = Moo::unwrap_or_clone(new_target.clone());
1388 }
1389
1390 _ => {
1391 break;
1393 }
1394 }
1395 }
1396
1397 indices.reverse();
1398
1399 if all_known {
1400 Ok(Expression::UnsafeIndex(
1401 Metadata::new(),
1402 Moo::new(target),
1403 indices
1404 .into_iter()
1405 .collect::<Option<Vec<_>>>()
1406 .ok_or(error!("Missing index in fully-known indexing operation"))?,
1407 ))
1408 } else {
1409 Ok(Expression::UnsafeSlice(
1410 Metadata::new(),
1411 Moo::new(target),
1412 indices,
1413 ))
1414 }
1415}
1416
1417fn parse_relation_projection(
1419 op: &serde_json::Map<String, Value>,
1420 scope: &SymbolTablePtr,
1421) -> Result<Expression> {
1422 let args = op
1423 .get("MkOpRelationProj")
1424 .ok_or(error!("MkOpRelationProj missing"))?
1425 .as_array()
1426 .ok_or(error!("MkOpRelationProj is not an array"))?;
1427 let first = args
1428 .first()
1429 .ok_or(error!("MkOpRelationProj missing first argument"))?;
1430 let second = args
1431 .get(1)
1432 .ok_or(error!("MkOpRelationProj missing second argument"))?
1433 .as_array()
1434 .ok_or(error!("MkOpRelationProj second argument is not an array"))?;
1435 let relation = parse_expression(first, scope).ok();
1436 let projections = second
1440 .iter()
1441 .map(|expr| parse_expression(expr, scope).ok())
1442 .collect();
1443 if let Some(relation) = relation {
1444 Ok(Expression::RelationProj(
1445 Metadata::new(),
1446 Moo::new(relation),
1447 projections,
1448 ))
1449 } else {
1450 Err(error!("MkOpRelationProj does not contain relation"))
1451 }
1452}
1453
1454fn parse_to_set(op: &serde_json::Map<String, Value>, scope: &SymbolTablePtr) -> Result<Expression> {
1458 let args = op
1459 .get("MkOpToSet")
1460 .ok_or(error!("MkOpToSet missing"))?
1461 .as_array()
1462 .ok_or(error!("MkOpToSet is not an array"))?;
1463 let second = args
1464 .get(1)
1465 .ok_or(error!("MkOpToSet missing second argument"))?;
1466 let inner = parse_expression(second, scope)?;
1467 Ok(Expression::ToSet(Metadata::new(), Moo::new(inner)))
1468}
1469
1470fn parse_flatten_op(
1471 op: &serde_json::Map<String, Value>,
1472 scope: &SymbolTablePtr,
1473) -> Result<Expression> {
1474 let args = op
1475 .get("MkOpFlatten")
1476 .ok_or(error!("MkOpFlatten missing"))?
1477 .as_array()
1478 .ok_or(error!("MkOpFlatten is not an array"))?;
1479
1480 let first = args
1481 .first()
1482 .ok_or(error!("MkOpFlatten missing first argument"))?;
1483 let second = args
1484 .get(1)
1485 .ok_or(error!("MkOpFlatten missing second argument"))?;
1486 let n = parse_expression(first, scope).ok();
1487 let matrix = parse_expression(second, scope)?;
1488
1489 if let Some(n) = n {
1490 Ok(Expression::Flatten(
1491 Metadata::new(),
1492 Some(Moo::new(n)),
1493 Moo::new(matrix),
1494 ))
1495 } else {
1496 Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
1497 }
1498}
1499
1500fn parse_unary_op(
1501 un_op: &serde_json::Map<String, Value>,
1502 scope: &SymbolTablePtr,
1503) -> Result<Expression> {
1504 let fail = |stage: &str| -> Error {
1505 Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
1506 };
1507
1508 let (key, value) = un_op
1509 .iter()
1510 .next()
1511 .ok_or_else(|| fail("un_op.iter().next"))?;
1512
1513 let arg = match value {
1517 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
1518 let comprehension_kind = match key.as_str() {
1519 "MkOpOr" => Some(ACOperatorKind::Or),
1520 "MkOpAnd" => Some(ACOperatorKind::And),
1521 "MkOpSum" => Some(ACOperatorKind::Sum),
1522 "MkOpProduct" => Some(ACOperatorKind::Product),
1523 _ => None,
1524 };
1525 parse_comprehension(comprehension, scope.clone(), comprehension_kind)
1526 .map_err(|_| fail("value.Comprehension.parse_comprehension"))
1527 }
1528 _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
1529 }
1530 .map_err(|_| fail("arg"))?;
1531
1532 let constructor =
1533 unary_operator(key.as_str(), Some(&arg)).ok_or_else(|| fail("unary_operator"))?;
1534
1535 Ok(constructor(Metadata::new(), Moo::new(arg)))
1536}
1537
1538fn parse_abstract_matrix_as_expr(
1540 value: &serde_json::Value,
1541 scope: &SymbolTablePtr,
1542) -> Result<Expression> {
1543 parser_trace!("trying to parse an abstract literal matrix");
1544 let (values, domain_name, domain_value) =
1545 if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
1546 parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
1547 let (domain_name, domain_value) = abs_lit_matrix
1548 .pointer("/0")
1549 .and_then(Value::as_object)
1550 .and_then(|x| x.iter().next())
1551 .ok_or(error!("AbsLitMatrix missing domain"))?;
1552 let values = abs_lit_matrix
1553 .pointer("/1")
1554 .ok_or(error!("AbsLitMatrix missing values"))?;
1555
1556 Some((values, domain_name, domain_value))
1557 }
1558 else if let Some(const_abs_lit_matrix) =
1560 value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
1561 {
1562 parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
1563 let (domain_name, domain_value) = const_abs_lit_matrix
1564 .pointer("/0")
1565 .and_then(Value::as_object)
1566 .and_then(|x| x.iter().next())
1567 .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
1568 let values = const_abs_lit_matrix
1569 .pointer("/1")
1570 .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
1571
1572 Some((values, domain_name, domain_value))
1573 } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
1574 parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
1575 let (domain_name, domain_value) = const_abs_lit_matrix
1576 .pointer("/0")
1577 .and_then(Value::as_object)
1578 .and_then(|x| x.iter().next())
1579 .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
1580 let values = const_abs_lit_matrix
1581 .pointer("/1")
1582 .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
1583 Some((values, domain_name, domain_value))
1584 } else {
1585 None
1586 }
1587 .ok_or(error!("Could not parse abstract literal matrix"))?;
1588
1589 parser_trace!(".. found in domain and values in JSON:");
1590 parser_trace!(".. .. index domain name {domain_name}");
1591 parser_trace!(".. .. values {value}");
1592
1593 let args_parsed = values
1594 .as_array()
1595 .ok_or(error!("Matrix values are not an array"))?
1596 .iter()
1597 .map(|x| parse_expression(x, scope))
1598 .collect::<Result<Vec<Expression>>>()?;
1599
1600 if !args_parsed.is_empty() {
1601 parser_trace!(
1602 ".. successfully parsed values as expressions: {}, ... ",
1603 args_parsed[0]
1604 );
1605 } else {
1606 parser_trace!(".. successfully parsed empty values ",);
1607 }
1608
1609 let mut symbols = scope.write();
1610 match parse_domain(domain_name, domain_value, &mut symbols) {
1611 Ok(domain) => {
1612 parser_trace!("... sucessfully parsed domain as {domain}");
1613 Ok(into_matrix_expr![args_parsed;domain])
1614 }
1615 Err(_) => {
1616 parser_trace!("... failed to parse domain, creating a matrix without one.");
1617 Ok(into_matrix_expr![args_parsed])
1618 }
1619 }
1620}
1621
1622fn parse_constant(
1623 constant: &serde_json::Map<String, Value>,
1624 scope: &SymbolTablePtr,
1625) -> Result<Expression> {
1626 match &constant.get("Constant") {
1627 Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
1628 let int_32: i32 = match int["ConstantInt"]
1629 .as_array()
1630 .ok_or(error!("ConstantInt is not an array"))?[1]
1631 .as_i64()
1632 .ok_or(error!("ConstantInt does not contain int"))?
1633 .try_into()
1634 {
1635 Ok(x) => x,
1636 Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
1637 };
1638
1639 Ok(Expression::Atomic(
1640 Metadata::new(),
1641 Atom::Literal(Literal::Int(int_32)),
1642 ))
1643 }
1644
1645 Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
1646 let b: bool = b["ConstantBool"]
1647 .as_bool()
1648 .ok_or(error!("ConstantBool does not contain bool"))?;
1649 Ok(Expression::Atomic(
1650 Metadata::new(),
1651 Atom::Literal(Literal::Bool(b)),
1652 ))
1653 }
1654
1655 Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
1656 if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
1657 if let Some(arr) = obj.get("AbsLitSet") {
1658 return parse_abs_lit(arr, scope);
1659 } else if let Some(arr) = obj.get("AbsLitMSet") {
1660 return parse_abs_mset(arr, scope);
1661 } else if let Some(arr) = obj.get("AbsLitMatrix") {
1662 return parse_abstract_matrix_as_expr(arr, scope);
1663 } else if let Some(arr) = obj.get("AbsLitTuple") {
1664 return parse_abs_tuple(arr, scope);
1665 } else if let Some(arr) = obj.get("AbsLitRecord") {
1666 return parse_abs_record(arr, scope);
1667 } else if let Some(arr) = obj.get("AbsLitPartition") {
1668 return parse_abs_partition(arr, scope);
1669 } else if let Some(arr) = obj.get("AbsLitFunction") {
1670 return parse_abs_function(arr, scope);
1671 } else if let Some(arr) = obj.get("AbsLitVariant") {
1672 return parse_abs_variant(arr, scope);
1673 } else if let Some(arr) = obj.get("AbsLitRelation") {
1674 return parse_abs_relation(arr, scope);
1675 } else if let Some(arr) = obj.get("AbsLitSequence") {
1676 return parse_abs_sequence(arr, scope);
1677 }
1678 }
1679 Err(error!("Unhandled ConstantAbstract literal type"))
1680 }
1681
1682 None => {
1685 let int_expr = constant
1686 .get("ConstantInt")
1687 .and_then(|x| x.as_array())
1688 .and_then(|x| x[1].as_i64())
1689 .and_then(|x| x.try_into().ok())
1690 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
1691
1692 if let Some(expr) = int_expr {
1693 return Ok(expr);
1694 }
1695
1696 let bool_expr = constant
1697 .get("ConstantBool")
1698 .and_then(|x| x.as_bool())
1699 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
1700
1701 if let Some(expr) = bool_expr {
1702 return Ok(expr);
1703 }
1704
1705 Err(error!(format!("Unhandled parse_constant {constant:#?}")))
1706 }
1707 otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
1708 }
1709}