@@ -198,84 +198,98 @@ def simp(t: smt.ExprRef, by: list[kd.kernel.Proof] = [], **kwargs) -> kd.kernel.
198198
199199
200200class Lemma :
201- # Isar style forward proof
202- def __init__ (self , goal ):
203- self .goal = goal
204- self .lemmas = []
205- self .vars = []
206- self .hyps = []
207-
208- def intro (self , vars ): # fix
209- self .vars .extend (vars )
210- return self
211-
212- def assume (self , hyps ):
213- self .hyps .extend (hyps )
214- return self
215-
216- def _wrap (self , form ):
217- return smt .ForAll (self .vars , smt .Implies (smt .And (self .hyps ), form ))
218-
219- def have (self , conc , ** kwargs ):
220- self .lemmas .append (lemma (self ._wrap (conc ), ** kwargs ))
221- return self
222-
223- def qed (self ):
224- return lemma (self .goal , by = self .lemmas )
225-
226-
227- class Lemma2 :
228201 # Isar style forward proof
229202 def __init__ (self , goal : smt .BoolRef ):
230203 # self.cur_goal = goal
231204 self .lemmas = []
232205 self .thm = goal
233- self .goals = [goal ]
206+ self .goals = [([], goal ) ]
234207
235208 def intros (self ):
236- goal = self .goals .pop ()
237- vs , herb_lemma = kd .kernel .herb (goal )
238- self .lemmas .append (herb_lemma )
239- self .goals .append (goal .thm .arg (0 ))
240- return vs
209+ ctx , goal = self .goals .pop ()
210+ if smt .is_quantifier (goal ) and goal .is_forall ():
211+ vs , herb_lemma = kd .kernel .herb (goal )
212+ self .lemmas .append (herb_lemma )
213+ self .goals .append ((ctx , herb_lemma .thm .arg (0 )))
214+ return vs
215+ elif smt .is_implies (goal ):
216+ self .goals .append ((ctx + [goal .arg (0 )], goal .arg (1 )))
217+ return self
218+
219+ def cases (self , t ):
220+ ctx , goal = self .goals .pop ()
221+ if t .sort () == smt .BoolSort ():
222+ self .goals .append ((ctx + [smt .Not (t )], goal ))
223+ self .goals .append ((ctx + [t ], goal ))
224+ elif isinstance (t , smt .DatatypeRef ):
225+ dsort = t .sort ()
226+ for i in reversed (range (dsort .num_constructors ())):
227+ self .goals .append ((ctx + [dsort .recognizer (i )(t )], goal ))
228+ else :
229+ raise ValueError ("Cases failed. Not a bool or datatype" )
230+ return self
241231
242- def cases (self ):
243- pass
232+ def auto (self ):
233+ ctx , goal = self .goals [- 1 ]
234+ self .lemmas .append (lemma (smt .Implies (smt .And (ctx ), goal )))
235+ self .goals .pop ()
236+ return self
244237
245238 def split (self ):
246- goal = self .goals . pop ()
239+ ctx , goal = self .goals [ - 1 ]
247240 if smt .is_and (goal ):
248- goals .extend (goal .children ())
241+ self .goals .pop ()
242+ self .goals .extend ([(ctx , c ) for c in goal .children ()])
249243 else :
250244 raise ValueError ("Split failed. Not an and" )
251245
252246 def exists (self , * ts ):
253- goal = self .goals .pop ()
254- # kd.kernel.forget(self.goal, t)
255- self .goals .append (utils .instan (goal , * ts ))
247+ ctx , goal = self .goals [- 1 ]
248+ lemma = kd .kernel .forget2 (ts , goal )
249+ self .lemmas .append (lemma )
250+ self .goals [- 1 ] = (ctx , lemma .thm .arg (0 ))
251+ return self
256252
257253 def apply (self , pf : kd .kernel .Proof ):
258- goal = self .goals .pop ()
259- self .lemmas .append (pf )
260- self .goals .append (utils .apply (goal , pf .thm ))
261- # TODO.
262- # self.lemmas.append(pf)
263- # self.cur_goal = pf.thm.arg(0)
264- # return self
265-
266- def assume (self , hyps ):
267- self .goal .arg (0 )
254+ ctx , goal = self .goals .pop ()
255+ thm = pf .thm
256+ if smt .is_quantifier (thm ) and thm .is_forall ():
257+ vs , thm = kd .utils .open_binder (thm )
258+ else :
259+ vs = []
260+ if not smt .is_implies (thm ):
261+ head = thm
262+ body = smt .BoolVal (True )
263+ else :
264+ body , head = thm .children ()
265+ subst = kd .utils .pmatch (vs , head , goal )
266+ if subst is None :
267+ raise ValueError (f"Apply tactic failed to goal { goal } lemma { pf } " )
268+ else :
269+ pf1 = kd .kernel .instan ([subst [v ] for v in vs ], pf )
270+ self .lemmas .append (pf1 )
271+ if smt .is_implies (pf1 .thm ):
272+ self .goals .append ((ctx , pf1 .thm .arg (0 )))
268273 return self
269274
270- def _wrap (self , form ):
271- return smt .ForAll (self .vars , smt .Implies (smt .And (self .hyps ), form ))
275+ def assumption (self ):
276+ ctx , goal = self .goals .pop ()
277+ if any ([goal .eq (h ) for h in ctx ]):
278+ return self
279+ else :
280+ raise ValueError ("Assumption tactic failed" , goal , ctx )
272281
273282 def have (self , conc , ** kwargs ):
274- self .lemmas .append (lemma (self ._wrap (conc ), ** kwargs ))
283+ ctx , goal = self .goals .pop ()
284+ self .lemmas .append (lemma (smt .Implies (smt .And (ctx ), conc )), ** kwargs )
285+ self .goals .append ((ctx + [conc ], conc ))
275286 return self
276287
277288 def __repr__ (self ):
278- return "?|- " + repr (self .goals [- 1 ])
289+ if len (self .goals ) == 0 :
290+ return "Nothing to do. Hooray!"
291+ ctx , goal = self .goals [- 1 ]
292+ return repr (ctx ) + " ?|- " + repr (goal )
279293
280294 def qed (self ):
281295 return lemma (self .thm , by = self .lemmas )
0 commit comments