1#![allow(clippy::unwrap_used)]
2#![allow(clippy::expect_used)]
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::rc::Rc;
6use std::sync::{Arc, RwLock};
7
8use serde_json::Value;
9use serde_json::Value as JsonValue;
10
11use crate::ast::comprehension::{ComprehensionBuilder, ComprehensionKind};
12use crate::ast::{
13 AbstractLiteral, Atom, Domain, Expression, Literal, Name, Range, SetAttr, SymbolTable,
14};
15use crate::ast::{Declaration, DeclarationKind};
16use crate::context::Context;
17use crate::error::{Error, Result};
18use crate::metadata::Metadata;
19use crate::{bug, error, into_matrix_expr, throw_error, Model};
20macro_rules! parser_trace {
21 ($($arg:tt)+) => {
22 log::trace!(target:"jsonparser",$($arg)+)
23 };
24}
25
26macro_rules! parser_debug {
27 ($($arg:tt)+) => {
28 log::debug!(target:"jsonparser",$($arg)+)
29 };
30}
31
32pub fn model_from_json(str: &str, context: Arc<RwLock<Context<'static>>>) -> Result<Model> {
33 let mut m = Model::new(context);
34 let v: JsonValue = serde_json::from_str(str)?;
35 let statements = v["mStatements"]
36 .as_array()
37 .ok_or(error!("mStatements is not an array"))?;
38
39 for statement in statements {
40 let entry = statement
41 .as_object()
42 .ok_or(error!("mStatements contains a non-object"))?
43 .iter()
44 .next()
45 .ok_or(error!("mStatements contains an empty object"))?;
46
47 match entry.0.as_str() {
48 "Declaration" => {
49 let decl = entry
50 .1
51 .as_object()
52 .ok_or(error!("Declaration is not an object".to_owned()))?;
53
54 let mut valid_decl: bool = false;
61 let scope = m.as_submodel().symbols_ptr_unchecked().clone();
62 let submodel = m.as_submodel_mut();
63 for (kind, value) in decl {
64 match kind.as_str() {
65 "FindOrGiven" => {
66 parse_variable(value, &mut submodel.symbols_mut())?;
67 valid_decl = true;
68 break;
69 }
70 "Letting" => {
71 parse_letting(value, &scope)?;
72 valid_decl = true;
73 break;
74 }
75 _ => continue,
76 }
77 }
78
79 if !valid_decl {
80 throw_error!("Declaration is not a valid kind")?;
81 }
82 }
83 "SuchThat" => {
84 let constraints_arr = match entry.1.as_array() {
85 Some(x) => x,
86 None => bug!("SuchThat is not a vector"),
87 };
88
89 let constraints: Vec<Expression> = constraints_arr
90 .iter()
91 .map(|x| {
92 parse_expression(x, m.as_submodel_mut().symbols_ptr_unchecked()).unwrap()
93 })
94 .collect();
95 m.as_submodel_mut().add_constraints(constraints);
96 }
98 otherwise => bug!("Unhandled Statement {:#?}", otherwise),
99 }
100 }
101
102 Ok(m)
103}
104
105fn parse_variable(v: &JsonValue, symtab: &mut SymbolTable) -> Result<()> {
106 let arr = v.as_array().ok_or(error!("FindOrGiven is not an array"))?;
107 let name = arr[1]
108 .as_object()
109 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
110 .as_str()
111 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
112
113 let name = Name::UserName(name.to_owned());
114
115 let domain = arr[2]
116 .as_object()
117 .ok_or(error!("FindOrGiven[2] is not an object"))?
118 .iter()
119 .next()
120 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
121
122 let domain = parse_domain(domain.0, domain.1, symtab)?;
123
124 symtab
125 .insert(Rc::new(Declaration::new_var(name.clone(), domain)))
126 .ok_or(Error::Parse(format!(
127 "Could not add {name} to symbol table as it already exists"
128 )))
129}
130
131fn parse_letting(v: &JsonValue, scope: &Rc<RefCell<SymbolTable>>) -> Result<()> {
132 let arr = v.as_array().ok_or(error!("Letting is not an array"))?;
133 let name = arr[0]
134 .as_object()
135 .ok_or(error!("Letting[0] is not an object"))?["Name"]
136 .as_str()
137 .ok_or(error!("Letting[0].Name is not a string"))?;
138 let name = Name::UserName(name.to_owned());
139 if let Some(value) = parse_expression(&arr[1], scope) {
141 let mut symtab = scope.borrow_mut();
142 symtab
143 .insert(Rc::new(Declaration::new_value_letting(name.clone(), value)))
144 .ok_or(Error::Parse(format!(
145 "Could not add {name} to symbol table as it already exists"
146 )))
147 } else {
148 let domain = &arr[1]
150 .as_object()
151 .ok_or(error!("Letting[1] is not an object".to_owned()))?["Domain"]
152 .as_object()
153 .ok_or(error!("Letting[1].Domain is not an object"))?
154 .iter()
155 .next()
156 .ok_or(error!("Letting[1].Domain is an empty object"))?;
157
158 let mut symtab = scope.borrow_mut();
159 let domain = parse_domain(domain.0, domain.1, &symtab)?;
160
161 symtab
162 .insert(Rc::new(Declaration::new_domain_letting(
163 name.clone(),
164 domain,
165 )))
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: &SymbolTable,
176) -> Result<Domain> {
177 match domain_name {
178 "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
179 "DomainBool" => Ok(Domain::BoolDomain),
180 "DomainReference" => Ok(Domain::DomainReference(Name::UserName(
181 domain_value
182 .as_array()
183 .ok_or(error!("DomainReference is not an array"))?[0]
184 .as_object()
185 .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
186 .as_str()
187 .ok_or(error!("DomainReference[0].Name is not a string"))?
188 .into(),
189 ))),
190 "DomainSet" => {
191 let dom = domain_value.get(2).and_then(|v| v.as_object());
192 let domain_obj = dom.expect("domain object exists");
193 let domain = domain_obj
194 .iter()
195 .next()
196 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
197 let domain = match domain_name {
198 "DomainInt" => {
199 println!("DomainInt: {:#?}", domain.1);
200 Ok(parse_int_domain(domain.1, symbols)?)
201 }
202 "DomainBool" => Ok(Domain::BoolDomain),
203 _ => Err(Error::Parse(
204 "FindOrGiven[2] is an unknown object".to_owned(),
205 )),
206 }?;
207 print!("{:?}", domain);
208 Ok(Domain::DomainSet(SetAttr::None, Box::new(domain)))
209 }
210
211 "DomainMatrix" => {
212 let domain_value = domain_value
213 .as_array()
214 .ok_or(error!("Domain matrix is not an array"))?;
215
216 let indexed_by_domain = domain_value[0].clone();
217 let (index_domain_name, index_domain_value) = indexed_by_domain
218 .as_object()
219 .ok_or(error!("DomainMatrix[0] is not an object"))?
220 .iter()
221 .next()
222 .ok_or(error!(""))?;
223
224 let (value_domain_name, value_domain_value) = domain_value[1]
225 .as_object()
226 .ok_or(error!(""))?
227 .iter()
228 .next()
229 .ok_or(error!(""))?;
230
231 let mut index_domains: Vec<Domain> = vec![];
236
237 index_domains.push(parse_domain(
238 index_domain_name,
239 index_domain_value,
240 symbols,
241 )?);
242
243 let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
249 while let Domain::DomainMatrix(new_value_domain, mut indices) = value_domain {
250 index_domains.append(&mut indices);
251 value_domain = *new_value_domain.clone()
252 }
253
254 Ok(Domain::DomainMatrix(Box::new(value_domain), index_domains))
255 }
256
257 _ => Err(Error::Parse(
258 "FindOrGiven[2] is an unknown object".to_owned(), )),
260 }
261}
262
263fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<Domain> {
264 let mut ranges = Vec::new();
265 let arr = v
266 .as_array()
267 .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
268 .as_array()
269 .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
270 for range in arr {
271 let range = range
272 .as_object()
273 .ok_or(error!("DomainInt[1] contains a non-object"))?
274 .iter()
275 .next()
276 .ok_or(error!("DomainInt[1] contains an empty object"))?;
277 match range.0.as_str() {
278 "RangeBounded" => {
279 let arr = range
280 .1
281 .as_array()
282 .ok_or(error!("RangeBounded is not an array".to_owned()))?;
283 let mut nums = Vec::new();
284 for item in arr.iter() {
285 let num = parse_domain_value_int(item, symbols)
286 .ok_or(error!("Could not parse int domain constant"))?;
287 nums.push(num);
288 }
289 ranges.push(Range::Bounded(nums[0], nums[1]));
290 }
291 "RangeSingle" => {
292 let num = parse_domain_value_int(range.1, symbols)
293 .ok_or(error!("Could not parse int domain constant"))?;
294 ranges.push(Range::Single(num));
295 }
296 _ => return throw_error!("DomainInt[1] contains an unknown object"),
297 }
298 }
299 Ok(Domain::IntDomain(ranges))
300}
301
302fn parse_domain_value_int(obj: &JsonValue, symbols: &SymbolTable) -> Option<i32> {
313 parser_trace!("trying to parse domain value: {}", obj);
314
315 fn try_parse_positive_int(obj: &JsonValue) -> Option<i32> {
316 parser_trace!(".. trying as a positive domain value: {}", obj);
317 let leaf_node = obj
320 .pointer("/Constant/ConstantInt/1")
321 .or_else(|| obj.pointer("/ConstantInt/1"))?;
322
323 match leaf_node.as_i64()?.try_into() {
324 Ok(x) => {
325 parser_trace!(".. success!");
326 Some(x)
327 }
328 Err(_) => {
329 println!(
330 "Could not convert integer constant to i32: {:#?}",
331 leaf_node
332 );
333 None
334 }
335 }
336 }
337
338 fn try_parse_negative_int(obj: &JsonValue) -> Option<i32> {
339 parser_trace!(".. trying as a negative domain value: {}", obj);
346 let inner_constant_node = obj.pointer("/Op/MkOpNegate")?;
347 let inner_num = try_parse_positive_int(inner_constant_node)?;
348
349 parser_trace!(".. success!");
350 Some(-inner_num)
351 }
352
353 fn try_parse_reference(obj: &JsonValue, symbols: &SymbolTable) -> Option<i32> {
360 parser_trace!(".. trying as a domain reference: {}", obj);
361 let inner_name = obj.pointer("/Reference/0/Name")?.as_str()?;
362 parser_trace!(
363 ".. found domain reference to {}, trying to resolve it",
364 inner_name
365 );
366 let name = Name::UserName(inner_name.to_string());
367 let decl = symbols.lookup(&name)?;
368 let DeclarationKind::ValueLetting(d) = decl.kind() else {
369 parser_trace!(".. name exists but is not a value letting!");
370 return None;
371 };
372
373 let a = d.clone().to_literal()?;
374 let Literal::Int(a) = a else {
375 return None;
376 };
377
378 Some(a)
379 }
380
381 try_parse_positive_int(obj)
382 .or_else(|| try_parse_negative_int(obj))
383 .or_else(|| try_parse_reference(obj, symbols))
384}
385
386type BinOp = Box<dyn Fn(Metadata, Box<Expression>, Box<Expression>) -> Expression>;
388type UnaryOp = Box<dyn Fn(Metadata, Box<Expression>) -> Expression>;
389type VecOp = Box<dyn Fn(Metadata, Vec<Expression>) -> Expression>;
390
391pub fn parse_expression(obj: &JsonValue, scope: &Rc<RefCell<SymbolTable>>) -> Option<Expression> {
392 let binary_operators: HashMap<&str, BinOp> = [
393 (
394 "MkOpEq",
395 Box::new(Expression::Eq) as Box<dyn Fn(_, _, _) -> _>,
396 ),
397 (
398 "MkOpNeq",
399 Box::new(Expression::Neq) as Box<dyn Fn(_, _, _) -> _>,
400 ),
401 (
402 "MkOpGeq",
403 Box::new(Expression::Geq) as Box<dyn Fn(_, _, _) -> _>,
404 ),
405 (
406 "MkOpLeq",
407 Box::new(Expression::Leq) as Box<dyn Fn(_, _, _) -> _>,
408 ),
409 (
410 "MkOpGt",
411 Box::new(Expression::Gt) as Box<dyn Fn(_, _, _) -> _>,
412 ),
413 (
414 "MkOpLt",
415 Box::new(Expression::Lt) as Box<dyn Fn(_, _, _) -> _>,
416 ),
417 (
418 "MkOpGt",
419 Box::new(Expression::Gt) as Box<dyn Fn(_, _, _) -> _>,
420 ),
421 (
422 "MkOpLt",
423 Box::new(Expression::Lt) as Box<dyn Fn(_, _, _) -> _>,
424 ),
425 (
426 "MkOpDiv",
427 Box::new(Expression::UnsafeDiv) as Box<dyn Fn(_, _, _) -> _>,
428 ),
429 (
430 "MkOpMod",
431 Box::new(Expression::UnsafeMod) as Box<dyn Fn(_, _, _) -> _>,
432 ),
433 (
434 "MkOpMinus",
435 Box::new(Expression::Minus) as Box<dyn Fn(_, _, _) -> _>,
436 ),
437 (
438 "MkOpImply",
439 Box::new(Expression::Imply) as Box<dyn Fn(_, _, _) -> _>,
440 ),
441 (
442 "MkOpPow",
443 Box::new(Expression::UnsafePow) as Box<dyn Fn(_, _, _) -> _>,
444 ),
445 ]
446 .into_iter()
447 .collect();
448
449 let unary_operators: HashMap<&str, UnaryOp> = [
450 (
451 "MkOpNot",
452 Box::new(Expression::Not) as Box<dyn Fn(_, _) -> _>,
453 ),
454 (
455 "MkOpNegate",
456 Box::new(Expression::Neg) as Box<dyn Fn(_, _) -> _>,
457 ),
458 (
459 "MkOpTwoBars",
460 Box::new(Expression::Abs) as Box<dyn Fn(_, _) -> _>,
461 ),
462 (
463 "MkOpAnd",
464 Box::new(Expression::And) as Box<dyn Fn(_, _) -> _>,
465 ),
466 (
467 "MkOpSum",
468 Box::new(Expression::Sum) as Box<dyn Fn(_, _) -> _>,
469 ),
470 ("MkOpOr", Box::new(Expression::Or) as Box<dyn Fn(_, _) -> _>),
471 (
472 "MkOpMin",
473 Box::new(Expression::Min) as Box<dyn Fn(_, _) -> _>,
474 ),
475 (
476 "MkOpMax",
477 Box::new(Expression::Max) as Box<dyn Fn(_, _) -> _>,
478 ),
479 (
480 "MkOpAllDiff",
481 Box::new(Expression::AllDiff) as Box<dyn Fn(_, _) -> _>,
482 ),
483 ]
484 .into_iter()
485 .collect();
486
487 let vec_operators: HashMap<&str, VecOp> = [(
488 "MkOpProduct",
489 Box::new(Expression::Product) as Box<dyn Fn(_, _) -> _>,
490 )]
491 .into_iter()
492 .collect();
493
494 let mut binary_operator_names = binary_operators.iter().map(|x| x.0);
495 let mut unary_operator_names = unary_operators.iter().map(|x| x.0);
496 let mut vec_operator_names = vec_operators.iter().map(|x| x.0);
497 #[allow(clippy::unwrap_used)]
498 match obj {
499 Value::Object(op) if op.contains_key("Op") => match &op["Op"] {
500 Value::Object(bin_op) if binary_operator_names.any(|key| bin_op.contains_key(*key)) => {
501 Some(parse_bin_op(bin_op, binary_operators, scope).unwrap())
502 }
503 Value::Object(un_op) if unary_operator_names.any(|key| un_op.contains_key(*key)) => {
504 Some(parse_unary_op(un_op, unary_operators, scope).unwrap())
505 }
506 Value::Object(vec_op) if vec_operator_names.any(|key| vec_op.contains_key(*key)) => {
507 Some(parse_vec_op(vec_op, vec_operators, scope).unwrap())
508 }
509
510 Value::Object(op)
511 if op.contains_key("MkOpIndexing") || op.contains_key("MkOpSlicing") =>
512 {
513 parse_indexing_slicing_op(op, scope)
514 }
515 otherwise => bug!("Unhandled Op {:#?}", otherwise),
516 },
517 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
518 Some(parse_comprehension(comprehension, Rc::clone(scope), None).unwrap())
519 }
520 Value::Object(refe) if refe.contains_key("Reference") => {
521 let name = refe["Reference"].as_array()?[0].as_object()?["Name"].as_str()?;
522 Some(Expression::Atomic(
523 Metadata::new(),
524 Atom::Reference(Name::UserName(name.to_string())),
525 ))
526 }
527 Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
528 if abslit["AbstractLiteral"]
529 .as_object()?
530 .contains_key("AbsLitSet")
531 {
532 Some(parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope).unwrap())
533 } else {
534 Some(parse_abstract_matrix_as_expr(obj, scope).unwrap())
535 }
536 }
537
538 Value::Object(constant) if constant.contains_key("Constant") => Some(
539 parse_constant(constant, scope)
540 .or_else(|| parse_abstract_matrix_as_expr(obj, scope))
541 .unwrap(),
542 ),
543
544 Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
545 Some(parse_abstract_matrix_as_expr(obj, scope).unwrap())
546 }
547
548 Value::Object(constant) if constant.contains_key("ConstantInt") => {
549 Some(parse_constant(constant, scope).unwrap())
550 }
551 Value::Object(constant) if constant.contains_key("ConstantBool") => {
552 Some(parse_constant(constant, scope).unwrap())
553 }
554
555 _ => None,
556 }
557}
558
559fn parse_abs_lit(abs_set: &Value, scope: &Rc<RefCell<SymbolTable>>) -> Option<Expression> {
560 let values = abs_set.as_array()?; let expressions = values
562 .iter()
563 .map(|values| parse_expression(values, scope))
564 .map(|values| values.expect("invalid subexpression")) .collect::<Vec<Expression>>(); Some(Expression::AbstractLiteral(
568 Metadata::new(),
569 AbstractLiteral::Set(expressions),
570 ))
571}
572fn parse_comprehension(
573 comprehension: &serde_json::Map<String, Value>,
574 scope: Rc<RefCell<SymbolTable>>,
575 comprehension_kind: Option<ComprehensionKind>,
576) -> Option<Expression> {
577 let value = &comprehension["Comprehension"];
578 let mut comprehension = ComprehensionBuilder::new();
579 let expr = parse_expression(value.pointer("/0")?, &scope)?;
580
581 let generators_and_guards = value.pointer("/1")?.as_array()?.iter();
582
583 for value in generators_and_guards {
584 let value = value.as_object()?;
585 let (name, value) = value.iter().next()?;
586 comprehension = match name.as_str() {
587 "Generator" => {
588 let name = value.pointer("/GenDomainNoRepr/0/Single/Name")?.as_str()?;
590 let (domain_name, domain_value) = value
591 .pointer("/GenDomainNoRepr/1")?
592 .as_object()?
593 .iter()
594 .next()?;
595 let domain = parse_domain(domain_name, domain_value, &scope.borrow()).ok()?;
596 comprehension.generator(Name::UserName(name.to_string()), domain)
597 }
598
599 "Condition" => comprehension.guard(parse_expression(value, &scope)?),
600
601 x => {
602 bug!("unknown field inside comprehension {x}");
603 }
604 }
605 }
606
607 Some(Expression::Comprehension(
608 Metadata::new(),
609 Box::new(comprehension.with_return_value(expr, scope, comprehension_kind)),
610 ))
611}
612
613fn parse_bin_op(
614 bin_op: &serde_json::Map<String, Value>,
615 binary_operators: HashMap<&str, BinOp>,
616 scope: &Rc<RefCell<SymbolTable>>,
617) -> Option<Expression> {
618 let (key, value) = bin_op.into_iter().next()?;
621
622 let constructor = binary_operators.get(key.as_str())?;
623
624 match &value {
625 Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
626 let arg1 = parse_expression(&bin_op_args[0], scope)?;
627 let arg2 = parse_expression(&bin_op_args[1], scope)?;
628 Some(constructor(Metadata::new(), Box::new(arg1), Box::new(arg2)))
629 }
630 otherwise => bug!("Unhandled parse_bin_op {:#?}", otherwise),
631 }
632}
633
634fn parse_indexing_slicing_op(
635 op: &serde_json::Map<String, Value>,
636 scope: &Rc<RefCell<SymbolTable>>,
637) -> Option<Expression> {
638 let (key, value) = op.into_iter().next()?;
641
642 let mut target: Expression;
651 let mut indices: Vec<Option<Expression>> = vec![];
652
653 let mut all_known = true;
655
656 match key.as_str() {
657 "MkOpIndexing" => {
658 match &value {
659 Value::Array(op_args) if op_args.len() == 2 => {
660 target = parse_expression(&op_args[0], scope).expect("expected an expression");
661 indices.push(Some(
662 parse_expression(&op_args[1], scope).expect("expected an expression"),
663 ));
664 }
665 otherwise => bug!("Unknown object inside MkOpIndexing: {:#?}", otherwise),
666 };
667 }
668
669 "MkOpSlicing" => {
670 all_known = false;
671 match &value {
672 Value::Array(op_args) if op_args.len() == 3 => {
673 target = parse_expression(&op_args[0], scope).expect("expected an expression");
674 indices.push(None);
675 }
676 otherwise => bug!("Unknown object inside MkOpSlicing: {:#?}", otherwise),
677 };
678 }
679
680 _ => {
681 return None;
682 }
683 }
684
685 loop {
686 match &mut target {
687 Expression::UnsafeIndex(_, new_target, new_indices) => {
688 indices.extend(new_indices.iter().cloned().map(Some));
689 target = *new_target.clone();
690 }
691
692 Expression::UnsafeSlice(_, new_target, new_indices) => {
693 all_known = false;
694 indices.append(new_indices);
695 target = *new_target.clone();
696 }
697
698 _ => {
699 break;
701 }
702 }
703 }
704
705 indices.reverse();
706
707 if all_known {
708 Some(Expression::UnsafeIndex(
709 Metadata::new(),
710 Box::new(target),
711 indices.into_iter().map(|x| x.unwrap()).collect(),
712 ))
713 } else {
714 Some(Expression::UnsafeSlice(
715 Metadata::new(),
716 Box::new(target),
717 indices,
718 ))
719 }
720}
721
722fn parse_unary_op(
723 un_op: &serde_json::Map<String, Value>,
724 unary_operators: HashMap<&str, UnaryOp>,
725 scope: &Rc<RefCell<SymbolTable>>,
726) -> Option<Expression> {
727 let (key, value) = un_op.into_iter().next()?;
728 let constructor = unary_operators.get(key.as_str())?;
729
730 let arg = match value {
734 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
735 let comprehension_kind = match key.as_str() {
736 "MkOpOr" => Some(ComprehensionKind::Or),
737 "MkOpAnd" => Some(ComprehensionKind::And),
738 "MkOpSum" => Some(ComprehensionKind::Sum),
739 _ => None,
740 };
741 Some(parse_comprehension(comprehension, Rc::clone(scope), comprehension_kind).unwrap())
742 }
743 _ => parse_expression(value, scope),
744 }?;
745
746 Some(constructor(Metadata::new(), Box::new(arg)))
747}
748
749fn parse_vec_op(
750 vec_op: &serde_json::Map<String, Value>,
751 vec_operators: HashMap<&str, VecOp>,
752 scope: &Rc<RefCell<SymbolTable>>,
753) -> Option<Expression> {
754 let (key, value) = vec_op.into_iter().next()?;
755 let constructor = vec_operators.get(key.as_str())?;
756
757 parser_debug!("Trying to parse vec_op: {key} ...");
758
759 let mut args_parsed: Option<Vec<Option<Expression>>> = None;
760 if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix/1") {
761 parser_trace!("... containing a matrix of literals");
762 args_parsed = abs_lit_matrix.as_array().map(|x| {
763 x.iter()
764 .map(|x| parse_expression(x, scope))
765 .collect::<Vec<Option<Expression>>>()
766 });
767 }
768 else if let Some(const_abs_lit_matrix) =
770 value.pointer("/Constant/ConstantAbstract/AbsLitMatrix/1")
771 {
772 parser_trace!("... containing a matrix of constants");
773 args_parsed = const_abs_lit_matrix.as_array().map(|x| {
774 x.iter()
775 .map(|x| parse_expression(x, scope))
776 .collect::<Vec<Option<Expression>>>()
777 });
778 }
779
780 let args_parsed = args_parsed?;
781
782 let number_of_args = args_parsed.len();
783 parser_debug!("... with {number_of_args} args {args_parsed:#?}");
784
785 let valid_args: Vec<Expression> = args_parsed.into_iter().flatten().collect();
786 if number_of_args != valid_args.len() {
787 None
788 } else {
789 parser_debug!("... success!");
790 Some(constructor(Metadata::new(), valid_args))
791 }
792}
793
794fn parse_abstract_matrix_as_expr(
796 value: &serde_json::Value,
797 scope: &Rc<RefCell<SymbolTable>>,
798) -> Option<Expression> {
799 parser_trace!("trying to parse an abstract literal matrix");
800 let (values, domain_name, domain_value) =
801 if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
802 parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
803 let (domain_name, domain_value) =
804 abs_lit_matrix.pointer("/0")?.as_object()?.iter().next()?;
805 let values = abs_lit_matrix.pointer("/1")?;
806
807 Some((values, domain_name, domain_value))
808 }
809 else if let Some(const_abs_lit_matrix) =
811 value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
812 {
813 parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
814 let (domain_name, domain_value) = const_abs_lit_matrix
815 .pointer("/0")?
816 .as_object()?
817 .iter()
818 .next()?;
819 let values = const_abs_lit_matrix.pointer("/1")?;
820
821 Some((values, domain_name, domain_value))
822 } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
823 parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
824 let (domain_name, domain_value) = const_abs_lit_matrix
825 .pointer("/0")?
826 .as_object()?
827 .iter()
828 .next()?;
829 let values = const_abs_lit_matrix.pointer("/1")?;
830 Some((values, domain_name, domain_value))
831 } else {
832 None
833 }?;
834
835 parser_trace!(".. found in domain and values in JSON:");
836 parser_trace!(".. .. index domain name {domain_name}");
837 parser_trace!(".. .. values {value}");
838
839 let args_parsed = values.as_array().map(|x| {
840 x.iter()
841 .map(|x| parse_expression(x, scope))
842 .map(|x| x.expect("invalid subexpression"))
843 .collect::<Vec<Expression>>()
844 })?;
845
846 if !args_parsed.is_empty() {
847 parser_trace!(
848 ".. successfully parsed values as expressions: {}, ... ",
849 args_parsed[0]
850 );
851 } else {
852 parser_trace!(".. successfully parsed empty values ",);
853 }
854
855 let symbols = scope.borrow();
856 match parse_domain(domain_name, domain_value, &symbols) {
857 Ok(domain) => {
858 parser_trace!("... sucessfully parsed domain as {domain}");
859 Some(into_matrix_expr![args_parsed;domain])
860 }
861 Err(_) => {
862 parser_trace!("... failed to parse domain, creating a matrix without one.");
863 Some(into_matrix_expr![args_parsed])
864 }
865 }
866}
867
868fn parse_constant(
869 constant: &serde_json::Map<String, Value>,
870 scope: &Rc<RefCell<SymbolTable>>,
871) -> Option<Expression> {
872 match &constant.get("Constant") {
873 Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
874 let int_32: i32 = match int["ConstantInt"].as_array()?[1].as_i64()?.try_into() {
875 Ok(x) => x,
876 Err(_) => {
877 println!(
878 "Could not convert integer constant to i32: {:#?}",
879 int["ConstantInt"]
880 );
881 return None;
882 }
883 };
884
885 Some(Expression::Atomic(
886 Metadata::new(),
887 Atom::Literal(Literal::Int(int_32)),
888 ))
889 }
890
891 Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
892 let b: bool = b["ConstantBool"].as_bool()?;
893 Some(Expression::Atomic(
894 Metadata::new(),
895 Atom::Literal(Literal::Bool(b)),
896 ))
897 }
898
899 Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
900 if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
901 if let Some(arr) = obj.get("AbsLitSet") {
902 return parse_abs_lit(arr, scope);
903 }
904 }
905 None
906 }
907
908 None => {
911 let int_expr = constant
912 .get("ConstantInt")
913 .and_then(|x| x.as_array())
914 .and_then(|x| x[1].as_i64())
915 .and_then(|x| x.try_into().ok())
916 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
917
918 if let e @ Some(_) = int_expr {
919 return e;
920 }
921
922 let bool_expr = constant
923 .get("ConstantBool")
924 .and_then(|x| x.as_bool())
925 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
926
927 if let e @ Some(_) = bool_expr {
928 return e;
929 }
930
931 bug!("Unhandled parse_constant {:#?}", constant);
932 }
933 otherwise => bug!("Unhandled parse_constant {:#?}", otherwise),
934 }
935}