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