smt_lang/solution/
method.rs1use super::*;
2use crate::combine::Combine;
3use crate::problem::*;
4use crate::solve::Smt;
5
6pub struct MethodValue<T: Id> {
9 id: MethodId<T>,
10 calls: Vec<CallValue>,
11}
12
13pub trait NewMethod<T: Id> {
14 fn new(smt: &Smt, model: &z3::Model, instance: InstanceId, method: &Method<T>) -> Self;
15}
16
17impl NewMethod<StructureId> for MethodValue<StructureId> {
18 fn new(
19 smt: &Smt,
20 model: &z3::Model,
21 instance: InstanceId,
22 method: &Method<StructureId>,
23 ) -> Self {
24 let mut calls = Vec::new();
25 let params_all = method
27 .parameters()
28 .iter()
29 .map(|p| p.typ().all(smt.problem()))
30 .collect();
31 let mut combine = Combine::new(params_all);
32 loop {
34 let inst = Expr::Instance(instance, None);
35 let values = combine.values();
36 let call = Expr::StrucMetCall(Box::new(inst), method.id(), values.clone(), None);
37 let value = CallValue::new(smt, model, values, &call);
39 calls.push(value);
40 if !combine.step() {
42 break;
43 }
44 }
45
46 Self {
47 id: method.id(),
48 calls,
49 }
50 }
51}
52
53impl ToLang for MethodValue<StructureId> {
56 fn to_lang(&self, problem: &Problem) -> String {
57 let mut meth = problem.get(self.id).unwrap().clone();
58 meth.set_expr(None);
59 let mut s = format!("{} {{\n", meth.to_lang(problem));
60 for v in self.calls.iter() {
61 s.push_str(&format!(" {}\n", v.to_lang(problem)));
62 }
63 s.push_str(" }");
64 s
65 }
66}
67
68impl NewMethod<ClassId> for MethodValue<ClassId> {
69 fn new(smt: &Smt, model: &z3::Model, instance: InstanceId, method: &Method<ClassId>) -> Self {
70 let mut calls = Vec::new();
71 let params_all = method
73 .parameters()
74 .iter()
75 .map(|p| p.typ().all(smt.problem()))
76 .collect();
77 let mut combine = Combine::new(params_all);
78 loop {
80 let inst = Expr::Instance(instance, None);
81 let values = combine.values();
82 let call = Expr::ClassMetCall(Box::new(inst), method.id(), values.clone(), None);
83 let value = CallValue::new(smt, model, values, &call);
85 calls.push(value);
86 if !combine.step() {
88 break;
89 }
90 }
91
92 Self {
93 id: method.id(),
94 calls,
95 }
96 }
97}
98
99impl ToLang for MethodValue<ClassId> {
102 fn to_lang(&self, problem: &Problem) -> String {
103 let mut meth = problem.get(self.id).unwrap().clone();
104 meth.set_expr(None);
105 let mut s = format!("{} {{\n", meth.to_lang(problem));
106 for v in self.calls.iter() {
107 s.push_str(&format!(" {}\n", v.to_lang(problem)));
108 }
109 s.push_str(" }");
110 s
111 }
112}