1use crate::prelude::*;
2
3impl Runtime {
6 pub fn verify_fact_well_defined(
7 &mut self,
8 fact: &Fact,
9 verify_state: &VerifyState,
10 ) -> Result<(), RuntimeError> {
11 match fact {
12 Fact::AtomicFact(atomic_fact) => {
13 self.verify_atomic_fact_well_defined(atomic_fact, verify_state)
14 }
15 Fact::AndFact(and_fact) => self.verify_and_fact_well_defined(and_fact, verify_state),
16 Fact::ChainFact(chain_fact) => {
17 self.verify_chain_fact_well_defined(chain_fact, verify_state)
18 }
19 Fact::OrFact(or_fact) => self.verify_or_fact_well_defined(or_fact, verify_state),
20 Fact::ExistFact(exist_fact) => {
21 self.verify_exist_fact_well_defined(exist_fact, verify_state)
22 }
23 Fact::ForallFact(forall_fact) => {
24 self.verify_forall_fact_well_defined(forall_fact, verify_state)
25 }
26 Fact::ForallFactWithIff(forall_fact_with_iff) => {
27 self.verify_forall_fact_with_iff_well_defined(forall_fact_with_iff, verify_state)
28 }
29 Fact::NotForall(not_forall) => {
30 self.verify_not_forall_fact_well_defined(not_forall, verify_state)
31 }
32 }
33 }
34
35 pub fn verify_atomic_fact_well_defined(
36 &mut self,
37 atomic_fact: &AtomicFact,
38 verify_state: &VerifyState,
39 ) -> Result<(), RuntimeError> {
40 match atomic_fact {
41 AtomicFact::EqualFact(equal_fact) => {
42 self.verify_equal_fact_well_defined(equal_fact, verify_state)
43 }
44 _ => self.verify_non_equational_atomic_fact_well_defined(atomic_fact, verify_state),
45 }
46 }
47
48 fn verify_equal_fact_well_defined(
49 &mut self,
50 equal_fact: &EqualFact,
51 verify_state: &VerifyState,
52 ) -> Result<(), RuntimeError> {
53 self.verify_obj_well_defined_and_store_cache(&equal_fact.left, verify_state)?;
54 self.verify_obj_well_defined_and_store_cache(&equal_fact.right, verify_state)?;
55 Ok(())
56 }
57
58 fn verify_non_equational_atomic_fact_well_defined(
59 &mut self,
60 atomic_fact: &AtomicFact,
61 verify_state: &VerifyState,
62 ) -> Result<(), RuntimeError> {
63 let name_string = atomic_fact.key();
65 if is_builtin_predicate(&name_string) {
66 let expected_len = atomic_fact.is_builtin_predicate_and_return_expected_args_len();
67 let actual_args = atomic_fact.args();
68 if actual_args.len() != expected_len {
69 return Err(WellDefinedRuntimeError(
70 RuntimeErrorStruct::new_with_msg_and_line_file(
71 format!(
72 "fact `{}` expects {} argument(s), but got {}",
73 name_string,
74 expected_len,
75 actual_args.len()
76 ),
77 atomic_fact.line_file(),
78 ),
79 )
80 .into());
81 }
82 } else {
83 let expected_len = if let Some(predicate_definition) =
84 self.get_prop_definition_by_name(&name_string)
85 {
86 predicate_definition.params_def_with_type.number_of_params()
87 } else if let Some(abstract_prop_definition) =
88 self.get_abstract_prop_definition_by_name(&name_string)
89 {
90 abstract_prop_definition.params.len()
91 } else {
92 return Err(WellDefinedRuntimeError(
93 RuntimeErrorStruct::new_with_msg_and_line_file(
94 format!("fact `{}` not defined", name_string),
95 atomic_fact.line_file(),
96 ),
97 )
98 .into());
99 };
100
101 let actual_args = atomic_fact.args();
102 if actual_args.len() != expected_len {
103 return Err(WellDefinedRuntimeError(
104 RuntimeErrorStruct::new_with_msg_and_line_file(
105 format!(
106 "fact `{}` expects {} argument(s), but got {}",
107 name_string,
108 expected_len,
109 actual_args.len()
110 ),
111 atomic_fact.line_file(),
112 ),
113 )
114 .into());
115 }
116 }
117
118 for arg in atomic_fact.args() {
120 self.verify_obj_well_defined_and_store_cache(&arg, verify_state)?;
121 }
122
123 Ok(())
124 }
125
126 pub fn verify_and_fact_well_defined(
127 &mut self,
128 and_fact: &AndFact,
129 verify_state: &VerifyState,
130 ) -> Result<(), RuntimeError> {
131 for fact in and_fact.facts.iter() {
132 self.verify_atomic_fact_well_defined(fact, verify_state)?;
133 }
134 Ok(())
135 }
136
137 pub fn verify_chain_fact_well_defined(
138 &mut self,
139 chain_fact: &ChainFact,
140 verify_state: &VerifyState,
141 ) -> Result<(), RuntimeError> {
142 let facts = chain_fact.facts()?;
143 for fact in facts.iter() {
144 self.verify_atomic_fact_well_defined(fact, verify_state)?;
145 }
146 Ok(())
147 }
148
149 pub fn verify_or_fact_well_defined(
150 &mut self,
151 or_fact: &OrFact,
152 verify_state: &VerifyState,
153 ) -> Result<(), RuntimeError> {
154 for fact in or_fact.facts.iter() {
155 self.verify_and_chain_atomic_fact_well_defined(fact, verify_state)?;
156 }
157 Ok(())
158 }
159
160 fn verify_and_chain_atomic_fact_well_defined(
161 &mut self,
162 fact: &AndChainAtomicFact,
163 verify_state: &VerifyState,
164 ) -> Result<(), RuntimeError> {
165 match fact {
166 AndChainAtomicFact::AtomicFact(a) => {
167 self.verify_atomic_fact_well_defined(a, verify_state)?
168 }
169 AndChainAtomicFact::AndFact(a) => self.verify_and_fact_well_defined(a, verify_state)?,
170 AndChainAtomicFact::ChainFact(c) => {
171 self.verify_chain_fact_well_defined(c, verify_state)?
172 }
173 }
174 Ok(())
175 }
176
177 pub fn verify_exist_fact_well_defined(
178 &mut self,
179 exist_fact: &ExistFactEnum,
180 verify_state: &VerifyState,
181 ) -> Result<(), RuntimeError> {
182 self.run_in_local_env(|rt| {
183 if let Err(e) = rt.define_params_with_type(
184 exist_fact.params_def_with_type(),
185 false,
186 ParamObjType::Exist,
187 ) {
188 return Err(WellDefinedRuntimeError(RuntimeErrorStruct::new(
189 None,
190 "failed to define parameters in exist fact".to_string(),
191 exist_fact.line_file(),
192 Some(e),
193 vec![],
194 ))
195 .into());
196 }
197
198 for fact in exist_fact.facts() {
199 match fact {
200 ExistBodyFact::AtomicFact(f) => {
201 let body_fact = OrAndChainAtomicFact::AtomicFact(f.clone());
202 rt.verify_or_and_chain_atomic_fact_well_defined(&body_fact, verify_state)?;
203 rt.store_or_and_chain_atomic_fact_without_well_defined_verified_and_infer(
204 body_fact,
205 )?;
206 }
207 ExistBodyFact::AndFact(f) => {
208 let body_fact = OrAndChainAtomicFact::AndFact(f.clone());
209 rt.verify_or_and_chain_atomic_fact_well_defined(&body_fact, verify_state)?;
210 rt.store_or_and_chain_atomic_fact_without_well_defined_verified_and_infer(
211 body_fact,
212 )?;
213 }
214 ExistBodyFact::ChainFact(f) => {
215 let body_fact = OrAndChainAtomicFact::ChainFact(f.clone());
216 rt.verify_or_and_chain_atomic_fact_well_defined(&body_fact, verify_state)?;
217 rt.store_or_and_chain_atomic_fact_without_well_defined_verified_and_infer(
218 body_fact,
219 )?;
220 }
221 ExistBodyFact::OrFact(f) => {
222 let body_fact = OrAndChainAtomicFact::OrFact(f.clone());
223 rt.verify_or_and_chain_atomic_fact_well_defined(&body_fact, verify_state)?;
224 rt.store_or_and_chain_atomic_fact_without_well_defined_verified_and_infer(
225 body_fact,
226 )?;
227 }
228 ExistBodyFact::InlineForall(f) => {
229 rt.verify_forall_fact_well_defined(f, verify_state)?;
230 rt.store_forall_fact_without_well_defined_verified_and_infer(f.clone())?;
231 }
232 }
233 }
234 Ok(())
235 })
236 }
237
238 pub fn verify_forall_fact_well_defined(
239 &mut self,
240 forall_fact: &ForallFact,
241 verify_state: &VerifyState,
242 ) -> Result<(), RuntimeError> {
243 self.run_in_local_env(|rt| {
244 rt.verify_forall_fact_well_defined_inner(forall_fact, verify_state)
245 })
246 }
247
248 pub fn verify_forall_fact_params_and_dom_well_defined(
249 &mut self,
250 forall_fact: &ForallFact,
251 verify_state: &VerifyState,
252 ) -> Result<(), RuntimeError> {
253 self.run_in_local_env(|rt| {
254 rt.verify_forall_fact_params_and_dom_well_defined_inner(forall_fact, verify_state)
255 })
256 }
257
258 fn verify_forall_fact_params_and_dom_well_defined_inner(
259 &mut self,
260 forall_fact: &ForallFact,
261 verify_state: &VerifyState,
262 ) -> Result<(), RuntimeError> {
263 if let Err(e) = self.define_params_with_type(
264 &forall_fact.params_def_with_type,
265 false,
266 ParamObjType::Forall,
267 ) {
268 return Err(WellDefinedRuntimeError(RuntimeErrorStruct::new(
269 None,
270 "failed to define parameters in forall fact".to_string(),
271 forall_fact.line_file.clone(),
272 Some(e),
273 vec![],
274 ))
275 .into());
276 }
277
278 for dom_fact in forall_fact.dom_facts.iter() {
279 if let Err(exec_stmt_error) =
280 self.verify_fact_well_defined_and_store_and_infer(dom_fact.clone(), verify_state)
281 {
282 return Err(WellDefinedRuntimeError(RuntimeErrorStruct::new(
283 None,
284 String::new(),
285 dom_fact.line_file(),
286 Some(exec_stmt_error),
287 vec![],
288 ))
289 .into());
290 }
291 }
292 Ok(())
293 }
294
295 fn verify_forall_fact_well_defined_inner(
296 &mut self,
297 forall_fact: &ForallFact,
298 verify_state: &VerifyState,
299 ) -> Result<(), RuntimeError> {
300 self.verify_forall_fact_params_and_dom_well_defined_inner(forall_fact, verify_state)?;
301 for fact in forall_fact.then_facts.iter() {
302 if let Err(exec_stmt_error) = self
303 .verify_exist_or_and_chain_atomic_fact_well_defined_and_store_and_infer(
304 fact,
305 verify_state,
306 )
307 {
308 return Err(WellDefinedRuntimeError(RuntimeErrorStruct::new(
309 None,
310 String::new(),
311 fact.line_file(),
312 Some(exec_stmt_error),
313 vec![],
314 ))
315 .into());
316 }
317 }
318 Ok(())
319 }
320
321 pub fn verify_or_and_chain_atomic_fact_well_defined(
322 &mut self,
323 fact: &OrAndChainAtomicFact,
324 verify_state: &VerifyState,
325 ) -> Result<(), RuntimeError> {
326 match fact {
327 OrAndChainAtomicFact::AtomicFact(a) => {
328 self.verify_atomic_fact_well_defined(a, verify_state)?
329 }
330 OrAndChainAtomicFact::AndFact(a) => {
331 self.verify_and_fact_well_defined(a, verify_state)?
332 }
333 OrAndChainAtomicFact::ChainFact(c) => {
334 self.verify_chain_fact_well_defined(c, verify_state)?
335 }
336 OrAndChainAtomicFact::OrFact(o) => self.verify_or_fact_well_defined(o, verify_state)?,
337 }
338 Ok(())
339 }
340
341 pub fn verify_exist_or_and_chain_atomic_fact_well_defined(
342 &mut self,
343 fact: &ExistOrAndChainAtomicFact,
344 verify_state: &VerifyState,
345 ) -> Result<(), RuntimeError> {
346 match fact {
347 ExistOrAndChainAtomicFact::AtomicFact(a) => {
348 self.verify_atomic_fact_well_defined(a, verify_state)?
349 }
350 ExistOrAndChainAtomicFact::AndFact(a) => {
351 self.verify_and_fact_well_defined(a, verify_state)?
352 }
353 ExistOrAndChainAtomicFact::ChainFact(c) => {
354 self.verify_chain_fact_well_defined(c, verify_state)?
355 }
356 ExistOrAndChainAtomicFact::OrFact(o) => {
357 self.verify_or_fact_well_defined(o, verify_state)?
358 }
359 ExistOrAndChainAtomicFact::ExistFact(e) => {
360 self.verify_exist_fact_well_defined(e, verify_state)?
361 }
362 }
363 Ok(())
364 }
365
366 pub fn verify_forall_fact_with_iff_well_defined(
367 &mut self,
368 forall_fact_with_iff: &ForallFactWithIff,
369 verify_state: &VerifyState,
370 ) -> Result<(), RuntimeError> {
371 self.run_in_local_env(|rt| {
372 rt.verify_forall_fact_well_defined_inner(
373 &forall_fact_with_iff.forall_fact,
374 verify_state,
375 )?;
376 for fact in forall_fact_with_iff.iff_facts.iter() {
377 rt.verify_exist_or_and_chain_atomic_fact_well_defined(fact, verify_state)?;
378 }
379 Ok(())
380 })
381 }
382
383 pub fn verify_not_forall_fact_well_defined(
384 &mut self,
385 not_forall: &NotForallFact,
386 verify_state: &VerifyState,
387 ) -> Result<(), RuntimeError> {
388 self.verify_forall_fact_well_defined(¬_forall.forall_fact, verify_state)
389 }
390}