litex/execute/
exec_claim_stmt.rs1use crate::prelude::*;
2
3impl Runtime {
4 pub fn exec_claim_stmt(&mut self, stmt: &ClaimStmt) -> Result<StmtResult, RuntimeError> {
5 match &stmt.fact {
6 Fact::ForallFactWithIff(_) => unreachable!("claim forall with iff is not supported"),
7 Fact::ForallFact(forall_fact) => {
8 self.verify_fact_well_defined(&stmt.fact, &VerifyState::new(0, false))
9 .map_err(|e| {
10 short_exec_error(
11 stmt.clone().into(),
12 "claim: fact is not well defined".to_string(),
13 Some(e),
14 vec![],
15 )
16 })?;
17
18 let body_exec_result = self.run_in_local_env(|rt| {
19 rt.define_params_with_type(
20 &forall_fact.params_def_with_type,
21 false,
22 ParamObjType::Forall,
23 )
24 .map_err(|define_params_error| {
25 exec_stmt_error_with_stmt_and_cause(
26 stmt.clone().into(),
27 define_params_error,
28 )
29 })?;
30
31 for dom_fact in forall_fact.dom_facts.iter() {
32 rt.verify_well_defined_and_store_and_infer_with_default_verify_state(dom_fact.clone())?;
33 }
34
35 let mut inside_results = vec![];
36 let proof_len = stmt.proof.len();
37 for (proof_index, proof_stmt) in stmt.proof.iter().enumerate() {
38 let result = rt.exec_stmt(proof_stmt)?;
39 if result.is_unknown() {
40 return Err(
41 UnknownRuntimeError(RuntimeErrorStruct::new(
42 Some(proof_stmt.clone()),
43 format!(
44 "claim failed: proof step {}/{} is unknown: `{}`\n{}",
45 proof_index + 1,
46 proof_len,
47 proof_stmt,
48 result.body_string()
49 ),
50 proof_stmt.line_file(),
51 None,
52 vec![],
53 ))
54 .into(),
55 );
56 }
57 inside_results.push(result);
58 }
59
60 let then_count = forall_fact.then_facts.len();
61 for (then_index, then_fact) in forall_fact.then_facts.iter().enumerate() {
62 let result = rt.verify_exist_or_and_chain_atomic_fact(
63 then_fact,
64 &VerifyState::new(0, false),
65 )?;
66 if result.is_unknown() {
67 return Err(
68 UnknownRuntimeError(RuntimeErrorStruct::new(
69 Some(Stmt::Fact(then_fact.clone().to_fact())),
70 format!(
71 "claim failed: cannot prove goal `{}`; then-clause {}/{} `{}` is unknown\n{}",
72 stmt.fact,
73 then_index + 1,
74 then_count,
75 then_fact,
76 result.body_string()
77 ),
78 then_fact.line_file(),
79 None,
80 vec![],
81 ))
82 .into(),
83 );
84 }
85
86 inside_results.push(result);
87 }
88
89 Ok(NonFactualStmtSuccess::new(
90 stmt.clone().into(),
91 InferResult::new(),
92 inside_results,
93 )
94 .into())
95 });
96
97 let non_err_after_body: StmtResult = match body_exec_result {
98 Ok(non_err_stmt_exec_result) => non_err_stmt_exec_result,
99 Err(runtime_error) => return Err(runtime_error),
100 };
101 if non_err_after_body.is_unknown() {
102 return Err(UnknownRuntimeError(RuntimeErrorStruct::new(
103 Some(stmt.clone().into()),
104 format!(
105 "claim failed: cannot prove `{}`\n{}",
106 stmt.fact,
107 non_err_after_body.body_string()
108 ),
109 stmt.line_file.clone(),
110 None,
111 vec![],
112 ))
113 .into());
114 }
115
116 let infer_result_after_store = self
117 .verify_well_defined_and_store_and_infer_with_default_verify_state(
118 stmt.fact.clone(),
119 )?;
120
121 let mut result = non_err_after_body;
122 if let StmtResult::NonFactualStmtSuccess(ref mut nfs) = result {
123 nfs.inside_results.clear();
124 }
125 Ok(result.with_infers(infer_result_after_store))
126 }
127 _ => {
128 self.verify_fact_well_defined(&stmt.fact, &VerifyState::new(0, false))
129 .map_err(|e| {
130 short_exec_error(
131 stmt.clone().into(),
132 "claim: fact is not well defined".to_string(),
133 Some(e),
134 vec![],
135 )
136 })?;
137
138 let body_exec_result = self.run_in_local_env(|rt| {
139 let mut inside_results: Vec<StmtResult> = Vec::new();
140 for proof_stmt in stmt.proof.iter() {
141 let proof_exec_result = rt.exec_stmt(proof_stmt)?;
142 inside_results.push(proof_exec_result);
143 }
144
145 rt.verify_fact_return_err_if_not_true(&stmt.fact, &VerifyState::new(0, false))?;
146
147 Ok(NonFactualStmtSuccess::new(
148 stmt.clone().into(),
149 InferResult::new(),
150 inside_results,
151 )
152 .into())
153 });
154
155 let non_err_after_body: StmtResult = match body_exec_result {
156 Ok(non_err_stmt_exec_result) => non_err_stmt_exec_result,
157 Err(runtime_error) => return Err(runtime_error),
158 };
159 let infer_result_after_store = self
160 .verify_well_defined_and_store_and_infer_with_default_verify_state(
161 stmt.fact.clone(),
162 )?;
163
164 Ok(non_err_after_body.with_infers(infer_result_after_store))
165 }
166 }
167 }
168}