conjure_cp_core/representation/
default_impls.rs1use super::errors::ReprUpError;
5use super::types::{LookupFn, ReprDomainLevel, ReprInstantiateResult};
6use super::util::try_up_via;
7use crate::ast::{
8 DeclarationKind, DeclarationPtr, DomainPtr, Expression, Literal, Name, SymbolTable,
9 eval_constant,
10};
11use crate::representation::ReprInstantiateError;
12use anyhow::anyhow;
13use funcmap::{FuncMap, TryFuncMap};
14pub fn domain_size(domain: &DomainPtr) -> usize {
17 domain
18 .length()
19 .ok()
20 .and_then(|size| usize::try_from(size).ok())
21 .unwrap_or(usize::MAX)
22}
23
24pub fn lookup_via_default_impl<DeclL, A>(
26 decl_level: &DeclL,
27 lookup: &LookupFn<'_>,
28) -> Result<A, ReprUpError>
29where
30 DeclL: Clone + TryFuncMap<DeclarationPtr, Literal, Output = A>,
31{
32 decl_level
33 .clone()
34 .try_func_map(|decl: DeclarationPtr| try_up_via(decl, lookup))
35}
36
37pub fn to_domain_level_default_impl<DomL, DecL>(decl_level: DecL) -> DomL
39where
40 DecL: FuncMap<DeclarationPtr, DomainPtr, Output = DomL>,
41{
42 let field_dom = |decl: DeclarationPtr| decl.domain().expect("variable must have a domain");
43 decl_level.func_map(field_dom)
44}
45
46pub fn instantiate_default_impl<DomL, DecL, A, SF>(
50 dom_level: DomL,
51 decl: DeclarationPtr,
52 structural: SF,
53) -> ReprInstantiateResult<DecL>
54where
55 DomL: ReprDomainLevel<Assignment = A, DeclLevel = DecL>
56 + FuncMap<DomainPtr, DeclarationPtr, Output = DecL>,
57 A: FuncMap<Literal, DeclarationPtr, Output = DecL>,
58 SF: Fn(&DecL) -> Vec<Expression>,
59{
60 let src_name = decl.name();
61 let repr_name = <DomL as ReprDomainLevel>::RULE.id();
62 let mut symtab = SymbolTable::new();
63 let mut counter = 1;
64 let element_domains = decl.as_find().and_then(|var| var.element_domains.clone());
65
66 match &decl.kind() as &DeclarationKind {
67 DeclarationKind::Find(_) | DeclarationKind::FindAuxiliary(_) => {
68 let declare_field_var = |dom: DomainPtr| {
69 let dom = element_domains
70 .as_ref()
71 .and_then(|domains| domains.get(counter - 1))
72 .cloned()
73 .unwrap_or(dom);
74 let name = Name::repr(src_name.clone(), repr_name, &counter.to_string());
75 let mut field_decl = if decl.is_find_auxiliary() {
76 DeclarationPtr::new_find_auxiliary(name, dom)
77 } else {
78 DeclarationPtr::new_find(name, dom)
79 };
80 *(field_decl.source_mut()) = Some(decl.clone());
81 symtab
82 .insert(field_decl.clone())
83 .expect("declaration already exists");
84 counter += 1;
85 field_decl
86 };
87
88 let decl_level = dom_level.func_map(declare_field_var);
89 let constraints = structural(&decl_level);
90 Ok((decl_level, symtab, constraints))
91 }
92 DeclarationKind::ValueLetting(expr, _) | DeclarationKind::TemporaryValueLetting(expr) => {
93 let declare_field_value_letting = |lit: Literal| {
94 let name = Name::repr(src_name.clone(), repr_name, &counter.to_string());
95 let mut field_decl = DeclarationPtr::new_value_letting(name, lit.into());
96 *(field_decl.source_mut()) = Some(decl.clone());
97 symtab
98 .insert(field_decl.clone())
99 .expect("declaration already exists");
100 counter += 1;
101 field_decl
102 };
103
104 let val = eval_constant(expr).ok_or(ReprInstantiateError::Other(anyhow!(
105 "expression {expr} is not constant"
106 )))?;
107 let val_down = dom_level.down(val).unwrap();
108 let decl_level = val_down.func_map(declare_field_value_letting);
109 let constraints = vec![];
111 Ok((decl_level, symtab, constraints))
112 }
113 _ => Err(ReprInstantiateError::BadKind(
114 decl.clone(),
115 String::from("expected a variable or value letting"),
116 )),
117 }
118}