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::ac_operators::ACOperatorKind;
12use crate::ast::comprehension::ComprehensionBuilder;
13use crate::ast::records::RecordValue;
14use crate::ast::{
15 AbstractLiteral, Atom, DeclarationPtr, Domain, Expression, FuncAttr, IntVal, JectivityAttr,
16 Literal, MSetAttr, Name, PartialityAttr, Range, RecordEntry, SetAttr, SymbolTable,
17 SymbolTablePtr,
18};
19use crate::ast::{DomainPtr, Metadata};
20use crate::context::Context;
21use crate::error::{Error, Result};
22use crate::{Model, bug, error, into_matrix_expr, throw_error};
23
24#[allow(unused_macros)]
25macro_rules! parser_trace {
26 ($($arg:tt)+) => {
27 log::trace!(target:"jsonparser",$($arg)+)
28 };
29}
30
31#[allow(unused_macros)]
32macro_rules! parser_debug {
33 ($($arg:tt)+) => {
34 log::debug!(target:"jsonparser",$($arg)+)
35 };
36}
37
38pub fn model_from_json(str: &str, context: Arc<RwLock<Context<'static>>>) -> Result<Model> {
39 let mut m = Model::new(context);
40 let v: JsonValue = serde_json::from_str(str)?;
41 let statements = v["mStatements"]
42 .as_array()
43 .ok_or(error!("mStatements is not an array"))?;
44
45 for statement in statements {
46 let entry = statement
47 .as_object()
48 .ok_or(error!("mStatements contains a non-object"))?
49 .iter()
50 .next()
51 .ok_or(error!("mStatements contains an empty object"))?;
52
53 match entry.0.as_str() {
54 "Declaration" => {
55 let decl = entry
56 .1
57 .as_object()
58 .ok_or(error!("Declaration is not an object".to_owned()))?;
59
60 let mut valid_decl: bool = false;
67 let scope = m.symbols_ptr_unchecked().clone();
68 let model = &mut m;
69 for (kind, value) in decl {
70 match kind.as_str() {
71 "FindOrGiven" => {
72 parse_variable(value, &mut model.symbols_mut())?;
73 valid_decl = true;
74 break;
75 }
76 "Letting" => {
77 parse_letting(value, &scope)?;
78 valid_decl = true;
79 break;
80 }
81 _ => continue,
82 }
83 }
84
85 if !valid_decl {
86 throw_error!("Declaration is not a valid kind")?;
87 }
88 }
89 "SuchThat" => {
90 let constraints_arr = match entry.1.as_array() {
91 Some(x) => x,
92 None => bug!("SuchThat is not a vector"),
93 };
94
95 let constraints: Vec<Expression> = constraints_arr
96 .iter()
97 .map(|x| parse_expression(x, m.symbols_ptr_unchecked()))
98 .collect::<Result<Vec<_>>>()?;
99 m.add_constraints(constraints);
100 }
101 otherwise => bug!("Unhandled Statement {:#?}", otherwise),
102 }
103 }
104 Ok(m)
105}
106
107fn parse_variable(v: &JsonValue, symtab: &mut SymbolTable) -> Result<()> {
108 let arr = v.as_array().ok_or(error!("FindOrGiven is not an array"))?;
109
110 let variable_type = arr[0]
111 .as_str()
112 .ok_or(error!("FindOrGiven[0] is not a string"))?;
113
114 let name = arr[1]
115 .as_object()
116 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
117 .as_str()
118 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
119
120 let name = Name::User(Ustr::from(name));
121
122 let domain = arr[2]
123 .as_object()
124 .ok_or(error!("FindOrGiven[2] is not an object"))?
125 .iter()
126 .next()
127 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
128
129 let domain = parse_domain(domain.0, domain.1, symtab)?;
130
131 let decl = match variable_type {
132 "Find" => DeclarationPtr::new_find(name.clone(), domain),
133 "Given" => DeclarationPtr::new_given(name.clone(), domain),
134 _ => {
135 return Err(error!("FindOrGiven[0] is not 'Find' or 'Given'"));
136 }
137 };
138
139 symtab.insert(decl).ok_or(Error::Parse(format!(
140 "Could not add {name} to symbol table as it already exists"
141 )))
142}
143
144fn parse_letting(v: &JsonValue, scope: &SymbolTablePtr) -> Result<()> {
145 let arr = v.as_array().ok_or(error!("Letting is not an array"))?;
146 let name = arr[0]
147 .as_object()
148 .ok_or(error!("Letting[0] is not an object"))?["Name"]
149 .as_str()
150 .ok_or(error!("Letting[0].Name is not a string"))?;
151 let name = Name::User(Ustr::from(name));
152 if let Ok(value) = parse_expression(&arr[1], scope) {
154 let mut symtab = scope.write();
155 symtab
156 .insert(DeclarationPtr::new_value_letting(name.clone(), value))
157 .ok_or(Error::Parse(format!(
158 "Could not add {name} to symbol table as it already exists"
159 )))
160 } else {
161 let domain = &arr[1]
163 .as_object()
164 .ok_or(error!("Letting[1] is not an object".to_owned()))?["Domain"]
165 .as_object()
166 .ok_or(error!("Letting[1].Domain is not an object"))?
167 .iter()
168 .next()
169 .ok_or(error!("Letting[1].Domain is an empty object"))?;
170
171 let mut symtab = scope.write();
172 let domain = parse_domain(domain.0, domain.1, &mut symtab)?;
173
174 symtab
175 .insert(DeclarationPtr::new_domain_letting(name.clone(), domain))
176 .ok_or(Error::Parse(format!(
177 "Could not add {name} to symbol table as it already exists"
178 )))
179 }
180}
181
182fn parse_domain(
183 domain_name: &str,
184 domain_value: &JsonValue,
185 symbols: &mut SymbolTable,
186) -> Result<DomainPtr> {
187 match domain_name {
188 "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
189 "DomainBool" => Ok(Domain::bool()),
190 "DomainReference" => {
191 let name = Name::user(
192 domain_value
193 .as_array()
194 .ok_or(error!("DomainReference is not an array"))?[0]
195 .as_object()
196 .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
197 .as_str()
198 .ok_or(error!("DomainReference[0].Name is not a string"))?,
199 );
200 let ptr = symbols
201 .lookup(&name)
202 .ok_or(error!(format!("Name {name} not found")))?;
203 let dom =
204 Domain::reference(ptr).ok_or(error!("Could not construct reference domain"))?;
205 Ok(dom)
206 }
207 "DomainSet" => {
208 let dom = domain_value.get(2).and_then(|v| v.as_object());
209 let domain_obj = dom.ok_or(error!("DomainSet is missing domain object"))?;
210 let domain = domain_obj
211 .iter()
212 .next()
213 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
214 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
215 let size = domain_value
216 .get(1)
217 .and_then(|v| v.as_object())
218 .ok_or(error!("Set size attributes is not an object"))?;
219 let size = parse_size_attr(size, symbols)?;
220 let attr: SetAttr<IntVal> = SetAttr { size };
221 Ok(Domain::set(attr, domain))
222 }
223 "DomainMSet" => {
224 let dom = domain_value
225 .get(2)
226 .and_then(|v| v.as_object())
227 .expect("domain object exists");
228 let domain = dom
229 .iter()
230 .next()
231 .ok_or(Error::Parse("DomainMSet is an empty object".to_owned()))?;
232 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
233
234 let attributes = domain_value
236 .get(1)
237 .and_then(|v| v.as_array())
238 .ok_or(error!("MSet attributes is not a json array"))?;
239
240 let size = attributes
241 .first()
242 .and_then(|v| v.as_object())
243 .ok_or(error!("MSet size attributes is not an object"))?;
244 let size = parse_size_attr(size, symbols)?;
245
246 let occurrence = attributes
247 .get(1)
248 .and_then(|v| v.as_object())
249 .ok_or(error!("MSet occurrence attributes is not an object"))?;
250 let occurrence = parse_occur_attr(occurrence, symbols)?;
251
252 let attr: MSetAttr<IntVal> = MSetAttr { size, occurrence };
253 Ok(Domain::mset(attr, domain))
254 }
255
256 "DomainMatrix" => {
257 let domain_value = domain_value
258 .as_array()
259 .ok_or(error!("Domain matrix is not an array"))?;
260
261 let indexed_by_domain = domain_value[0].clone();
262 let (index_domain_name, index_domain_value) = indexed_by_domain
263 .as_object()
264 .ok_or(error!("DomainMatrix[0] is not an object"))?
265 .iter()
266 .next()
267 .ok_or(error!(""))?;
268
269 let (value_domain_name, value_domain_value) = domain_value[1]
270 .as_object()
271 .ok_or(error!(""))?
272 .iter()
273 .next()
274 .ok_or(error!(""))?;
275
276 let mut index_domains: Vec<DomainPtr> = vec![];
281
282 index_domains.push(parse_domain(
283 index_domain_name,
284 index_domain_value,
285 symbols,
286 )?);
287
288 let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
294 while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
295 index_domains.append(&mut indices);
296 value_domain = new_value_domain.clone()
297 }
298
299 Ok(Domain::matrix(value_domain, index_domains))
300 }
301 "DomainTuple" => {
302 let domain_value = domain_value
303 .as_array()
304 .ok_or(error!("Domain tuple is not an array"))?;
305
306 let domain = domain_value
308 .iter()
309 .map(|x| {
310 let domain = x
311 .as_object()
312 .ok_or(error!("DomainTuple[0] is not an object"))?
313 .iter()
314 .next()
315 .ok_or(error!("DomainTuple[0] is an empty object"))?;
316 parse_domain(domain.0, domain.1, symbols)
317 })
318 .collect::<Result<Vec<DomainPtr>>>()?;
319
320 Ok(Domain::tuple(domain))
321 }
322 "DomainRecord" => {
323 let domain_value = domain_value
324 .as_array()
325 .ok_or(error!("Domain Record is not a json array"))?;
326
327 let mut record_entries = vec![];
328
329 for item in domain_value {
330 let name = item[0]
332 .as_object()
333 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
334 .as_str()
335 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
336
337 let name = Name::User(Ustr::from(name));
338 let domain = item[1]
340 .as_object()
341 .ok_or(error!("FindOrGiven[2] is not an object"))?
342 .iter()
343 .next()
344 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
345
346 let domain = parse_domain(domain.0, domain.1, symbols)?;
347
348 let rec = RecordEntry { name, domain };
349
350 record_entries.push(rec);
351 }
352
353 for decl in record_entries
355 .iter()
356 .cloned()
357 .map(DeclarationPtr::new_record_field)
358 {
359 symbols.insert(decl).ok_or(error!(
360 "record field should not already be in the symbol table"
361 ))?;
362 }
363
364 Ok(Domain::record(record_entries))
365 }
366 "DomainFunction" => {
367 let domain = domain_value
368 .get(2)
369 .and_then(|v| v.as_object())
370 .ok_or(error!("Function domain is not an object"))?;
371 let domain = domain
372 .iter()
373 .next()
374 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
375 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
376
377 let codomain = domain_value
378 .get(3)
379 .and_then(|v| v.as_object())
380 .ok_or(error!("Function codomain is not an object"))?;
381 let codomain = codomain
382 .iter()
383 .next()
384 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
385 let codomain = parse_domain(codomain.0.as_str(), codomain.1, symbols)?;
386
387 let attributes = domain_value
389 .get(1)
390 .and_then(|v| v.as_array())
391 .ok_or(error!("Function attributes is not a json array"))?;
392 let size = attributes
393 .first()
394 .and_then(|v| v.as_object())
395 .ok_or(error!("Function size attributes is not an object"))?;
396 let size = parse_size_attr(size, symbols)?;
397 let partiality = attributes
398 .get(1)
399 .and_then(|v| v.as_str())
400 .ok_or(error!("Function partiality is not a string"))?;
401 let partiality = match partiality {
402 "PartialityAttr_Partial" => Some(PartialityAttr::Partial),
403 "PartialityAttr_Total" => Some(PartialityAttr::Total),
404 _ => None,
405 };
406 let partiality =
407 partiality.ok_or(Error::Parse("Partiality is an unknown type".to_owned()))?;
408 let jectivity = attributes
409 .get(2)
410 .and_then(|v| v.as_str())
411 .ok_or(error!("Function jectivity is not a string"))?;
412 let jectivity = match jectivity {
413 "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
414 "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
415 "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
416 "JectivityAttr_None" => Some(JectivityAttr::None),
417 _ => None,
418 };
419 let jectivity =
420 jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
421
422 let attr: FuncAttr<IntVal> = FuncAttr {
423 size,
424 partiality,
425 jectivity,
426 };
427
428 Ok(Domain::function(attr, domain, codomain))
429 }
430 _ => Err(Error::Parse(
431 "FindOrGiven[2] is an unknown object".to_owned(), )),
433 }
434}
435
436fn parse_size_attr(
437 attr_map: &JsonMap<String, JsonValue>,
438 symbols: &mut SymbolTable,
439) -> Result<Range<IntVal>> {
440 let scope = SymbolTablePtr::new();
441 *scope.write() = symbols.clone();
442
443 let attr_obj = attr_map
444 .iter()
445 .next()
446 .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
447 match attr_obj.0.as_str() {
448 "SizeAttr_None" => Ok(Range::Unbounded),
449 "SizeAttr_MinSize" => {
450 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
451 Ok(Range::UnboundedR(size))
452 }
453 "SizeAttr_MaxSize" => {
454 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
455 Ok(Range::UnboundedL(size))
456 }
457 "SizeAttr_MinMaxSize" => {
458 let min_max = attr_obj
459 .1
460 .as_array()
461 .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
462 let min = min_max
463 .first()
464 .ok_or(error!("SizeAttr Min is not present"))?;
465 let min_int = parse_expression_to_int_val(min, &scope)?;
466 let max = min_max
467 .get(1)
468 .ok_or(error!("SizeAttr Max is not present"))?;
469 let max_int = parse_expression_to_int_val(max, &scope)?;
470 Ok(Range::Bounded(min_int, max_int))
471 }
472 "SizeAttr_Size" => {
473 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
474 Ok(Range::Single(size))
475 }
476 _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
477 }
478}
479
480fn parse_occur_attr(
481 attr_map: &JsonMap<String, JsonValue>,
482 symbols: &mut SymbolTable,
483) -> Result<Range<IntVal>> {
484 let scope = SymbolTablePtr::new();
485 *scope.write() = symbols.clone();
486 let attr_obj = attr_map
487 .iter()
488 .next()
489 .ok_or(Error::Parse("OccurAttr is an empty object".to_owned()))?;
490 match attr_obj.0.as_str() {
491 "OccurAttr_None" => Ok(Range::Unbounded),
492 "OccurAttr_MinOccur" => {
493 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
494 Ok(Range::UnboundedR(size_int))
495 }
496 "OccurAttr_MaxOccur" => {
497 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
498 Ok(Range::UnboundedL(size_int))
499 }
500 "OccurAttr_MinMaxOccur" => {
501 let min_max = attr_obj
502 .1
503 .as_array()
504 .ok_or(error!("OccurAttr MinMaxOccur is not a json array"))?;
505 let min = min_max
506 .first()
507 .ok_or(error!("OccurAttr Min is not present"))?;
508 let min_int = parse_expression_to_int_val(min, &scope)?;
509 let max = min_max
510 .get(1)
511 .ok_or(error!("OccurAttr Max is not present"))?;
512 let max_int = parse_expression_to_int_val(max, &scope)?;
513 Ok(Range::Bounded(min_int, max_int))
514 }
515 "OccurAttr_Size" => {
516 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
517 Ok(Range::Single(size_int))
518 }
519 _ => Err(Error::Parse("OccurAttr is an unknown type".to_owned())),
520 }
521}
522
523fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<DomainPtr> {
524 let scope = SymbolTablePtr::new();
525 *scope.write() = symbols.clone();
526
527 let mut ranges = Vec::new();
528 let arr = v
529 .as_array()
530 .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
531 .as_array()
532 .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
533 for range in arr {
534 let range = range
535 .as_object()
536 .ok_or(error!("DomainInt[1] contains a non-object"))?
537 .iter()
538 .next()
539 .ok_or(error!("DomainInt[1] contains an empty object"))?;
540 match range.0.as_str() {
541 "RangeBounded" => {
542 let arr = range
543 .1
544 .as_array()
545 .ok_or(error!("RangeBounded is not an array".to_owned()))?;
546 let mut nums = Vec::new();
547 for item in arr.iter() {
548 let num = parse_expression_to_int_val(item, &scope)?;
549 nums.push(num);
550 }
551 let lower = nums
552 .first()
553 .cloned()
554 .ok_or(error!("RangeBounded lower bound missing"))?;
555 let upper = nums
556 .get(1)
557 .cloned()
558 .ok_or(error!("RangeBounded upper bound missing"))?;
559 ranges.push(Range::Bounded(lower, upper));
560 }
561 "RangeSingle" => {
562 let num = parse_expression_to_int_val(range.1, &scope)?;
563 ranges.push(Range::Single(num));
564 }
565 _ => return throw_error!("DomainInt[1] contains an unknown object"),
566 }
567 }
568 Ok(Domain::int(ranges))
569}
570
571fn parse_expression_to_int_val(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<IntVal> {
572 parser_trace!("trying to parse domain value as expression: {}", obj);
573 let expr = parse_expression(obj, scope)?;
574
575 if let Some(Literal::Int(i)) = expr.clone().into_literal() {
576 return Ok(IntVal::Const(i));
577 }
578
579 if let Expression::Atomic(_, Atom::Reference(reference)) = &expr
580 && let Some(reference_val) = IntVal::new_ref(reference)
581 {
582 return Ok(reference_val);
583 }
584
585 IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
586}
587
588type BinOp = fn(Metadata, Moo<Expression>, Moo<Expression>) -> Expression;
589type UnaryOp = fn(Metadata, Moo<Expression>) -> Expression;
590
591fn binary_operator(op_name: &str) -> Option<BinOp> {
592 match op_name {
593 "MkOpIn" => Some(Expression::In),
594 "MkOpUnion" => Some(Expression::Union),
595 "MkOpIntersect" => Some(Expression::Intersect),
596 "MkOpSupset" => Some(Expression::Supset),
597 "MkOpSupsetEq" => Some(Expression::SupsetEq),
598 "MkOpSubset" => Some(Expression::Subset),
599 "MkOpSubsetEq" => Some(Expression::SubsetEq),
600 "MkOpEq" => Some(Expression::Eq),
601 "MkOpNeq" => Some(Expression::Neq),
602 "MkOpGeq" => Some(Expression::Geq),
603 "MkOpLeq" => Some(Expression::Leq),
604 "MkOpGt" => Some(Expression::Gt),
605 "MkOpLt" => Some(Expression::Lt),
606 "MkOpLexLt" => Some(Expression::LexLt),
607 "MkOpLexGt" => Some(Expression::LexGt),
608 "MkOpLexLeq" => Some(Expression::LexLeq),
609 "MkOpLexGeq" => Some(Expression::LexGeq),
610 "MkOpDiv" => Some(Expression::UnsafeDiv),
611 "MkOpMod" => Some(Expression::UnsafeMod),
612 "MkOpMinus" => Some(Expression::Minus),
613 "MkOpImply" => Some(Expression::Imply),
614 "MkOpIff" => Some(Expression::Iff),
615 "MkOpPow" => Some(Expression::UnsafePow),
616 "MkOpImage" => Some(Expression::Image),
617 "MkOpImageSet" => Some(Expression::ImageSet),
618 "MkOpPreImage" => Some(Expression::PreImage),
619 "MkOpInverse" => Some(Expression::Inverse),
620 "MkOpRestrict" => Some(Expression::Restrict),
621 _ => None,
622 }
623}
624
625fn unary_operator(op_name: &str) -> Option<UnaryOp> {
626 match op_name {
627 "MkOpNot" => Some(Expression::Not),
628 "MkOpNegate" => Some(Expression::Neg),
629 "MkOpTwoBars" => Some(Expression::Abs),
630 "MkOpAnd" => Some(Expression::And),
631 "MkOpSum" => Some(Expression::Sum),
632 "MkOpProduct" => Some(Expression::Product),
633 "MkOpOr" => Some(Expression::Or),
634 "MkOpMin" => Some(Expression::Min),
635 "MkOpMax" => Some(Expression::Max),
636 "MkOpAllDiff" => Some(Expression::AllDiff),
637 "MkOpToInt" => Some(Expression::ToInt),
638 "MkOpDefined" => Some(Expression::Defined),
639 "MkOpRange" => Some(Expression::Range),
640 "MkOpFactorial" => Some(Expression::Factorial),
641 _ => None,
642 }
643}
644
645pub fn parse_expression(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<Expression> {
646 let fail = |stage: &str| -> Error {
647 Error::Parse(format!(
648 "Could not parse expression at stage `{stage}` for json `{obj}`"
649 ))
650 };
651
652 match obj {
653 Value::Object(op) if op.contains_key("Op") => {
654 let op_obj = op
655 .get("Op")
656 .and_then(Value::as_object)
657 .ok_or_else(|| fail("Op.as_object"))?;
658 let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
659
660 if op_obj.contains_key("MkOpFlatten") {
661 parse_flatten_op(op_obj, scope)
662 } else if op_obj.contains_key("MkOpTable") {
663 parse_table_op(op_obj, scope)
664 } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
665 parse_indexing_slicing_op(op_obj, scope)
666 } else if binary_operator(op_name).is_some() {
667 parse_bin_op(op_obj, scope)
668 } else if unary_operator(op_name).is_some() {
669 parse_unary_op(op_obj, scope)
670 } else {
671 Err(fail("Op.unknown"))
672 }
673 }
674 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
675 parse_comprehension(comprehension, scope.clone(), None)
676 }
677 Value::Object(refe) if refe.contains_key("Reference") => {
678 let ref_arr = refe["Reference"]
679 .as_array()
680 .ok_or_else(|| fail("Reference.as_array"))?;
681 let ref_obj = ref_arr
682 .first()
683 .and_then(|x| x.as_object())
684 .ok_or_else(|| fail("Reference[0].as_object"))?;
685 let name = ref_obj
686 .get("Name")
687 .and_then(|x| x.as_str())
688 .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
689 let user_name = Name::User(Ustr::from(name));
690
691 let declaration: DeclarationPtr = scope
692 .read()
693 .lookup(&user_name)
694 .ok_or_else(|| fail("Reference.lookup"))?;
695
696 Ok(Expression::Atomic(
697 Metadata::new(),
698 Atom::Reference(crate::ast::Reference::new(declaration)),
699 ))
700 }
701 Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
702 let abstract_literal = abslit["AbstractLiteral"]
703 .as_object()
704 .ok_or_else(|| fail("AbstractLiteral.as_object"))?;
705
706 if abstract_literal.contains_key("AbsLitSet") {
707 parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
708 } else if abstract_literal.contains_key("AbsLitFunction") {
709 parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
710 } else if abstract_literal.contains_key("AbsLitMSet") {
711 parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
712 } else {
713 parse_abstract_matrix_as_expr(obj, scope)
714 }
715 }
716
717 Value::Object(constant) if constant.contains_key("Constant") => {
718 parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
719 }
720
721 Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
722 parse_abstract_matrix_as_expr(obj, scope)
723 }
724
725 Value::Object(constant) if constant.contains_key("ConstantInt") => {
726 parse_constant(constant, scope)
727 }
728 Value::Object(constant) if constant.contains_key("ConstantBool") => {
729 parse_constant(constant, scope)
730 }
731
732 _ => Err(fail("no_match")),
733 }
734}
735
736fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
737 let values = abs_set
738 .as_array()
739 .ok_or(error!("AbsLitSet is not an array"))?;
740 let expressions = values
741 .iter()
742 .map(|values| parse_expression(values, scope))
743 .collect::<Result<Vec<_>>>()?;
744
745 Ok(Expression::AbstractLiteral(
746 Metadata::new(),
747 AbstractLiteral::Set(expressions),
748 ))
749}
750
751fn parse_abs_mset(abs_mset: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
752 let values = abs_mset
753 .as_array()
754 .ok_or(error!("AbsLitMSet is not an array"))?;
755 let expressions = values
756 .iter()
757 .map(|values| parse_expression(values, scope))
758 .collect::<Result<Vec<_>>>()?;
759
760 Ok(Expression::AbstractLiteral(
761 Metadata::new(),
762 AbstractLiteral::MSet(expressions),
763 ))
764}
765
766fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
767 let values = abs_tuple
768 .as_array()
769 .ok_or(error!("AbsLitTuple is not an array"))?;
770 let expressions = values
771 .iter()
772 .map(|values| parse_expression(values, scope))
773 .collect::<Result<Vec<_>>>()?;
774
775 Ok(Expression::AbstractLiteral(
776 Metadata::new(),
777 AbstractLiteral::Tuple(expressions),
778 ))
779}
780
781fn parse_abs_record(abs_record: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
783 let entries = abs_record
784 .as_array()
785 .ok_or(error!("AbsLitRecord is not an array"))?;
786 let mut rec = vec![];
787
788 for entry in entries {
789 let entry = entry
790 .as_array()
791 .ok_or(error!("AbsLitRecord entry is not an array"))?;
792 let name = entry[0]
793 .as_object()
794 .ok_or(error!("AbsLitRecord field name is not an object"))?["Name"]
795 .as_str()
796 .ok_or(error!("AbsLitRecord field name is not a string"))?;
797
798 let value = parse_expression(&entry[1], scope)?;
799
800 let name = Name::User(Ustr::from(name));
801 let rec_entry = RecordValue {
802 name: name.clone(),
803 value,
804 };
805 rec.push(rec_entry);
806 }
807
808 Ok(Expression::AbstractLiteral(
809 Metadata::new(),
810 AbstractLiteral::Record(rec),
811 ))
812}
813
814fn parse_abs_function(abs_function: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
816 let entries = abs_function
817 .as_array()
818 .ok_or(error!("AbsLitFunction is not an array"))?;
819 let mut assignments = vec![];
820
821 for entry in entries {
822 let entry = entry
823 .as_array()
824 .ok_or(error!("Explicit function assignment is not an array"))?;
825 let expression = entry
826 .iter()
827 .map(|values| parse_expression(values, scope))
828 .collect::<Result<Vec<_>>>()?;
829 let domain_value = expression
830 .first()
831 .ok_or(error!("Invalid function domain"))?;
832 let codomain_value = expression
833 .get(1)
834 .ok_or(error!("Invalid function codomain"))?;
835 let tuple = (domain_value.clone(), codomain_value.clone());
836 assignments.push(tuple);
837 }
838 Ok(Expression::AbstractLiteral(
839 Metadata::new(),
840 AbstractLiteral::Function(assignments),
841 ))
842}
843
844fn parse_comprehension(
845 comprehension: &serde_json::Map<String, Value>,
846 scope: SymbolTablePtr,
847 comprehension_kind: Option<ACOperatorKind>,
848) -> Result<Expression> {
849 let fail = |stage: &str| -> Error {
850 Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
851 };
852
853 let value = &comprehension["Comprehension"];
854 let mut comprehension = ComprehensionBuilder::new(scope.clone());
855 let generator_symboltable = comprehension.generator_symboltable();
856 let return_expr_symboltable = comprehension.return_expr_symboltable();
857
858 let generators_and_guards_array = value
859 .pointer("/1")
860 .and_then(Value::as_array)
861 .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
862 let generators_and_guards = generators_and_guards_array.iter();
863
864 for gen_or_guard in generators_and_guards {
865 let gen_or_guard_obj = gen_or_guard
866 .as_object()
867 .ok_or_else(|| fail("generator_or_guard.as_object"))?;
868 let (name, inner) = gen_or_guard_obj
869 .iter()
870 .next()
871 .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
872 comprehension = match name.as_str() {
873 "Generator" => {
874 let generator_obj = inner
876 .as_object()
877 .ok_or_else(|| fail("Generator.inner.as_object"))?;
878 let (name, gen_inner) = generator_obj
879 .iter()
880 .next()
881 .ok_or_else(|| fail("Generator.inner.iter().next"))?;
882 match name.as_str() {
883 "GenDomainNoRepr" => {
884 let name = gen_inner
885 .pointer("/0/Single/Name")
886 .and_then(Value::as_str)
887 .ok_or_else(|| {
888 fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
889 })?;
890 let domain_obj = gen_inner
891 .pointer("/1")
892 .and_then(Value::as_object)
893 .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
894 let (domain_name, domain_value) = domain_obj
895 .iter()
896 .next()
897 .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
898 let domain = parse_domain(
899 domain_name,
900 domain_value,
901 &mut generator_symboltable.write(),
902 )?;
903 comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
904 }
905 "GenInExpr" => {
906 let name = gen_inner
907 .pointer("/0/Single/Name")
908 .and_then(Value::as_str)
909 .ok_or_else(|| {
910 fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
911 })?;
912 let generator_expr = gen_inner
913 .pointer("/1")
914 .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
915 let expr = parse_expression(generator_expr, &scope)
916 .map_err(|_| fail("GenInExpr.parse_expression"))?;
917 comprehension.expression_generator(name.into(), expr)
918 }
919 _ => {
920 bug!("unknown generator type inside comprehension {name}");
921 }
922 }
923 }
924
925 "Condition" => {
926 let expr = parse_expression(inner, &generator_symboltable)
927 .map_err(|_| fail("Condition.parse_expression"))?;
928 comprehension.guard(expr)
929 }
930
931 x => {
932 bug!("unknown field inside comprehension {x}");
933 }
934 }
935 }
936
937 let return_expr_value = value
938 .pointer("/0")
939 .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
940 let expr = parse_expression(return_expr_value, &return_expr_symboltable)
941 .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
942
943 Ok(Expression::Comprehension(
944 Metadata::new(),
945 Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
946 ))
947}
948
949fn parse_bin_op(
950 bin_op: &serde_json::Map<String, Value>,
951 scope: &SymbolTablePtr,
952) -> Result<Expression> {
953 let (key, value) = bin_op
956 .into_iter()
957 .next()
958 .ok_or(error!("Binary op object is empty"))?;
959
960 let constructor = binary_operator(key.as_str())
961 .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
962
963 match &value {
964 Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
965 let arg1 = parse_expression(&bin_op_args[0], scope)?;
966 let arg2 = parse_expression(&bin_op_args[1], scope)?;
967 Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
968 }
969 _ => Err(error!("Binary operator arguments are not a 2-array")),
970 }
971}
972
973fn parse_table_op(
974 op: &serde_json::Map<String, Value>,
975 scope: &SymbolTablePtr,
976) -> Result<Expression> {
977 let args = op
978 .get("MkOpTable")
979 .ok_or(error!("MkOpTable missing"))?
980 .as_array()
981 .ok_or(error!("MkOpTable is not an array"))?;
982
983 if args.len() != 2 {
984 return Err(error!("MkOpTable arguments are not a 2-array"));
985 }
986
987 let tuple_expr = parse_expression(&args[0], scope)?;
988 let allowed_rows_expr = parse_expression(&args[1], scope)?;
989
990 let (tuple_elems, _) = tuple_expr
991 .clone()
992 .unwrap_matrix_unchecked()
993 .ok_or(error!("MkOpTable first argument is not a matrix"))?;
994 let (allowed_rows, _) = allowed_rows_expr
995 .clone()
996 .unwrap_matrix_unchecked()
997 .ok_or(error!("MkOpTable second argument is not a matrix"))?;
998
999 for row_expr in allowed_rows {
1000 let (row_elems, _) = row_expr
1001 .unwrap_matrix_unchecked()
1002 .ok_or(error!("MkOpTable row is not a matrix"))?;
1003
1004 if row_elems.len() != tuple_elems.len() {
1005 return Err(error!("MkOpTable row width does not match tuple width"));
1006 }
1007 }
1008
1009 Ok(Expression::Table(
1010 Metadata::new(),
1011 Moo::new(tuple_expr),
1012 Moo::new(allowed_rows_expr),
1013 ))
1014}
1015
1016fn parse_indexing_slicing_op(
1017 op: &serde_json::Map<String, Value>,
1018 scope: &SymbolTablePtr,
1019) -> Result<Expression> {
1020 let (key, value) = op
1023 .into_iter()
1024 .next()
1025 .ok_or(error!("Indexing/Slicing op object is empty"))?;
1026
1027 let mut target: Expression;
1036 let mut indices: Vec<Option<Expression>> = vec![];
1037
1038 let mut all_known = true;
1040
1041 match key.as_str() {
1042 "MkOpIndexing" => {
1043 match &value {
1044 Value::Array(op_args) if op_args.len() == 2 => {
1045 target = parse_expression(&op_args[0], scope)?;
1046 indices.push(Some(parse_expression(&op_args[1], scope)?));
1047 }
1048 _ => return Err(error!("Unknown object inside MkOpIndexing")),
1049 };
1050 }
1051
1052 "MkOpSlicing" => {
1053 all_known = false;
1054 match &value {
1055 Value::Array(op_args) if op_args.len() == 3 => {
1056 target = parse_expression(&op_args[0], scope)?;
1057 indices.push(None);
1058 }
1059 _ => return Err(error!("Unknown object inside MkOpSlicing")),
1060 };
1061 }
1062
1063 _ => return Err(error!("Unknown indexing/slicing operator")),
1064 }
1065
1066 loop {
1067 match &mut target {
1068 Expression::UnsafeIndex(_, new_target, new_indices) => {
1069 indices.extend(new_indices.iter().cloned().rev().map(Some));
1070 target = Moo::unwrap_or_clone(new_target.clone());
1071 }
1072
1073 Expression::UnsafeSlice(_, new_target, new_indices) => {
1074 all_known = false;
1075 indices.extend(new_indices.iter().cloned().rev());
1076 target = Moo::unwrap_or_clone(new_target.clone());
1077 }
1078
1079 _ => {
1080 break;
1082 }
1083 }
1084 }
1085
1086 indices.reverse();
1087
1088 if all_known {
1089 Ok(Expression::UnsafeIndex(
1090 Metadata::new(),
1091 Moo::new(target),
1092 indices
1093 .into_iter()
1094 .collect::<Option<Vec<_>>>()
1095 .ok_or(error!("Missing index in fully-known indexing operation"))?,
1096 ))
1097 } else {
1098 Ok(Expression::UnsafeSlice(
1099 Metadata::new(),
1100 Moo::new(target),
1101 indices,
1102 ))
1103 }
1104}
1105
1106fn parse_flatten_op(
1107 op: &serde_json::Map<String, Value>,
1108 scope: &SymbolTablePtr,
1109) -> Result<Expression> {
1110 let args = op
1111 .get("MkOpFlatten")
1112 .ok_or(error!("MkOpFlatten missing"))?
1113 .as_array()
1114 .ok_or(error!("MkOpFlatten is not an array"))?;
1115
1116 let first = args
1117 .first()
1118 .ok_or(error!("MkOpFlatten missing first argument"))?;
1119 let second = args
1120 .get(1)
1121 .ok_or(error!("MkOpFlatten missing second argument"))?;
1122 let n = parse_expression(first, scope).ok();
1123 let matrix = parse_expression(second, scope)?;
1124
1125 if let Some(n) = n {
1126 Ok(Expression::Flatten(
1127 Metadata::new(),
1128 Some(Moo::new(n)),
1129 Moo::new(matrix),
1130 ))
1131 } else {
1132 Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
1133 }
1134}
1135
1136fn parse_unary_op(
1137 un_op: &serde_json::Map<String, Value>,
1138 scope: &SymbolTablePtr,
1139) -> Result<Expression> {
1140 let fail = |stage: &str| -> Error {
1141 Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
1142 };
1143
1144 let (key, value) = un_op
1145 .iter()
1146 .next()
1147 .ok_or_else(|| fail("un_op.iter().next"))?;
1148 let constructor = unary_operator(key.as_str()).ok_or_else(|| fail("unary_operator"))?;
1149
1150 let arg = match value {
1154 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
1155 let comprehension_kind = match key.as_str() {
1156 "MkOpOr" => Some(ACOperatorKind::Or),
1157 "MkOpAnd" => Some(ACOperatorKind::And),
1158 "MkOpSum" => Some(ACOperatorKind::Sum),
1159 "MkOpProduct" => Some(ACOperatorKind::Product),
1160 _ => None,
1161 };
1162 parse_comprehension(comprehension, scope.clone(), comprehension_kind)
1163 .map_err(|_| fail("value.Comprehension.parse_comprehension"))
1164 }
1165 _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
1166 }
1167 .map_err(|_| fail("arg"))?;
1168
1169 Ok(constructor(Metadata::new(), Moo::new(arg)))
1170}
1171
1172fn parse_abstract_matrix_as_expr(
1174 value: &serde_json::Value,
1175 scope: &SymbolTablePtr,
1176) -> Result<Expression> {
1177 parser_trace!("trying to parse an abstract literal matrix");
1178 let (values, domain_name, domain_value) =
1179 if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
1180 parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
1181 let (domain_name, domain_value) = abs_lit_matrix
1182 .pointer("/0")
1183 .and_then(Value::as_object)
1184 .and_then(|x| x.iter().next())
1185 .ok_or(error!("AbsLitMatrix missing domain"))?;
1186 let values = abs_lit_matrix
1187 .pointer("/1")
1188 .ok_or(error!("AbsLitMatrix missing values"))?;
1189
1190 Some((values, domain_name, domain_value))
1191 }
1192 else if let Some(const_abs_lit_matrix) =
1194 value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
1195 {
1196 parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
1197 let (domain_name, domain_value) = const_abs_lit_matrix
1198 .pointer("/0")
1199 .and_then(Value::as_object)
1200 .and_then(|x| x.iter().next())
1201 .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
1202 let values = const_abs_lit_matrix
1203 .pointer("/1")
1204 .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
1205
1206 Some((values, domain_name, domain_value))
1207 } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
1208 parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
1209 let (domain_name, domain_value) = const_abs_lit_matrix
1210 .pointer("/0")
1211 .and_then(Value::as_object)
1212 .and_then(|x| x.iter().next())
1213 .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
1214 let values = const_abs_lit_matrix
1215 .pointer("/1")
1216 .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
1217 Some((values, domain_name, domain_value))
1218 } else {
1219 None
1220 }
1221 .ok_or(error!("Could not parse abstract literal matrix"))?;
1222
1223 parser_trace!(".. found in domain and values in JSON:");
1224 parser_trace!(".. .. index domain name {domain_name}");
1225 parser_trace!(".. .. values {value}");
1226
1227 let args_parsed = values
1228 .as_array()
1229 .ok_or(error!("Matrix values are not an array"))?
1230 .iter()
1231 .map(|x| parse_expression(x, scope))
1232 .collect::<Result<Vec<Expression>>>()?;
1233
1234 if !args_parsed.is_empty() {
1235 parser_trace!(
1236 ".. successfully parsed values as expressions: {}, ... ",
1237 args_parsed[0]
1238 );
1239 } else {
1240 parser_trace!(".. successfully parsed empty values ",);
1241 }
1242
1243 let mut symbols = scope.write();
1244 match parse_domain(domain_name, domain_value, &mut symbols) {
1245 Ok(domain) => {
1246 parser_trace!("... sucessfully parsed domain as {domain}");
1247 Ok(into_matrix_expr![args_parsed;domain])
1248 }
1249 Err(_) => {
1250 parser_trace!("... failed to parse domain, creating a matrix without one.");
1251 Ok(into_matrix_expr![args_parsed])
1252 }
1253 }
1254}
1255
1256fn parse_constant(
1257 constant: &serde_json::Map<String, Value>,
1258 scope: &SymbolTablePtr,
1259) -> Result<Expression> {
1260 match &constant.get("Constant") {
1261 Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
1262 let int_32: i32 = match int["ConstantInt"]
1263 .as_array()
1264 .ok_or(error!("ConstantInt is not an array"))?[1]
1265 .as_i64()
1266 .ok_or(error!("ConstantInt does not contain int"))?
1267 .try_into()
1268 {
1269 Ok(x) => x,
1270 Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
1271 };
1272
1273 Ok(Expression::Atomic(
1274 Metadata::new(),
1275 Atom::Literal(Literal::Int(int_32)),
1276 ))
1277 }
1278
1279 Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
1280 let b: bool = b["ConstantBool"]
1281 .as_bool()
1282 .ok_or(error!("ConstantBool does not contain bool"))?;
1283 Ok(Expression::Atomic(
1284 Metadata::new(),
1285 Atom::Literal(Literal::Bool(b)),
1286 ))
1287 }
1288
1289 Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
1290 if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
1291 if let Some(arr) = obj.get("AbsLitSet") {
1292 return parse_abs_lit(arr, scope);
1293 } else if let Some(arr) = obj.get("AbsLitMSet") {
1294 return parse_abs_mset(arr, scope);
1295 } else if let Some(arr) = obj.get("AbsLitMatrix") {
1296 return parse_abstract_matrix_as_expr(arr, scope);
1297 } else if let Some(arr) = obj.get("AbsLitTuple") {
1298 return parse_abs_tuple(arr, scope);
1299 } else if let Some(arr) = obj.get("AbsLitRecord") {
1300 return parse_abs_record(arr, scope);
1301 } else if let Some(arr) = obj.get("AbsLitFunction") {
1302 return parse_abs_function(arr, scope);
1303 }
1304 }
1305 Err(error!("Unhandled ConstantAbstract literal type"))
1306 }
1307
1308 None => {
1311 let int_expr = constant
1312 .get("ConstantInt")
1313 .and_then(|x| x.as_array())
1314 .and_then(|x| x[1].as_i64())
1315 .and_then(|x| x.try_into().ok())
1316 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
1317
1318 if let Some(expr) = int_expr {
1319 return Ok(expr);
1320 }
1321
1322 let bool_expr = constant
1323 .get("ConstantBool")
1324 .and_then(|x| x.as_bool())
1325 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
1326
1327 if let Some(expr) = bool_expr {
1328 return Ok(expr);
1329 }
1330
1331 Err(error!(format!("Unhandled parse_constant {constant:#?}")))
1332 }
1333 otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
1334 }
1335}