Skip to content

Commit 2b1d708

Browse files
julesmtMassartjoscoh
authored
Fix bool_*_interp reductions via concreteEval + native_decide (#1053)
The four `bool_*_interp` proofs in `Tautologies.lean` were failing because Lean couldn’t reduce expressions involving `ceval`, which comes from a `HashMap` lookup inside `Factory`. Common tactics don’t look inside that structure, so they got stuck. Instead of working directly with `ceval`, first prove the evaluation result using the concrete field `F["..."].concreteEval`, written with `Option.bind` so everything stays total. Then use `native_decide` to evaluate the lookup and boolean cases. After that, rewrite using `h_ceval_eq` to replace `F["..."].concreteEval` with `some ceval`. At this point, Lean can reduce `(some ceval).bind ...` normally, and `simpa` completes the proof. This same approach works for `And`, `Or`, `Implies`, and `Not`. Co-authored-by: Massart <julesmt@amazon.com> Co-authored-by: Josh Cohen <36058610+joscoh@users.noreply.github.com>
1 parent 7194ca5 commit 2b1d708

1 file changed

Lines changed: 61 additions & 35 deletions

File tree

StrataTest/DL/Lambda/Denote/Tautologies.lean

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ over `IntBoolFactory`. Each formula is a closed, well-typed `LExpr` of type
1818
interpretation, type-variable valuation, and free-variable valuation.
1919
2020
Because HashMaps do not reduce well in the kernel, this file uses
21-
`native_decide` and several `sorrys` for simplifying the `Factory`
22-
`concreteEval`.
21+
`native_decide` for simplifying the `Factory` `concreteEval`.
2322
-/
2423

2524
namespace Lambda
@@ -205,8 +204,6 @@ strategy is:
205204
4. Instantiate with concrete boolean constant expressions
206205
5. Since `substReduce` reduces definitionally on ground types, typing proofs (`.const`) work directly
207206
6. Use `change` to normalize the goal (substReduce is defeq but not syntactically reduced)
208-
7. The remaining `sorry` is the `h_eval` step: proving `ceval` computes the right result,
209-
blocked by Factory HashMap lookups not reducing in the kernel (TODO)
210207
-/
211208

212209
private abbrev boolBinSort : LSort :=
@@ -232,24 +229,30 @@ private theorem bool_and_interp (I : Interp F) :
232229
rw [bool_and_input_tys, bool_and_output, bool_and_name] at h_ic
233230
-- Now h_ic uses substReduce which reduces definitionally on ground types
234231
funext p q
235-
have h_eval : ceval () [.const () (.boolConst p), .const () (.boolConst q)]
236-
= some (.const () (.boolConst (p && q))) := by
237-
-- ceval comes from F["Bool.And"].concreteEval. Use simp to reduce the HashMap lookup.
238-
-- Blocked: Factory HashMap lookup doesn't reduce. TODO.
239-
sorry
232+
have h_eval : ceval () [.boolConst () p, .boolConst () q]
233+
= some (.boolConst () (p && q)) := by
234+
have h_concrete :
235+
∀ (b1 b2 : Bool),
236+
(F["Bool.And"]'bool_and_mem).concreteEval.bind
237+
(fun f => f () [.boolConst () b1, .boolConst () b2])
238+
= some (.boolConst () (b1 && b2)) := by
239+
intro b1 b2; cases b1 <;> cases b2 <;> native_decide
240+
have h_inst_concrete := h_concrete p q
241+
rw [h_ceval_eq] at h_inst_concrete
242+
simpa using h_inst_concrete
240243
have h_vt : TyVarVal := fun _ => .tcons "bool" []
241244
have h_fv : FreeVarVal TP I.tcInterp := fun _ s =>
242245
@default _ (@SortDenote.instInhabited I.tcInterp I.allInhabited s)
243246
have h_inst := h_ic h_vt h_fv () Subst.empty
244-
[.const () (.boolConst p), .const () (.boolConst q)]
245-
(.const () (.boolConst (p && q)))
247+
[.boolConst () p, .boolConst () q]
248+
(.boolConst () (p && q))
246249
h_eval
247250
-- substReduce reduces definitionally on ground types. Provide typing proofs.
248251
have h_args : List.Forall₂ (LExpr.HasTypeA (T := TP) [])
249-
[.const () (.boolConst p), .const () (.boolConst q)]
252+
[.boolConst () p, .boolConst () q]
250253
[.tcons "bool" [], .tcons "bool" []] :=
251254
.cons .const (.cons .const .nil)
252-
have h_result : LExpr.HasTypeA (T := TP) [] (.const () (.boolConst (p && q))) (.tcons "bool" []) := .const
255+
have h_result : LExpr.HasTypeA (T := TP) [] (.boolConst () (p && q)) (.tcons "bool" []) := .const
253256
have h_eq := h_inst h_args h_result
254257
-- substReduce reduces definitionally but Lean displays it unreduced.
255258
-- Use change to normalize the type in h_eq.
@@ -271,22 +274,29 @@ private theorem bool_implies_interp (I : Interp F) :
271274
unfold LFunc.InterpConsistentEvalReduce at h_ic
272275
rw [bool_implies_input_tys, bool_implies_output, bool_implies_name] at h_ic
273276
funext p q
274-
have h_eval : ceval () [.const () (.boolConst p), .const () (.boolConst q)]
275-
= some (.const () (.boolConst (!p || q))) := by
276-
-- Blocked: Factory HashMap lookup doesn't reduce. TODO.
277-
sorry
277+
have h_eval : ceval () [.boolConst () p, .boolConst () q]
278+
= some (.boolConst () (!p || q)) := by
279+
have h_concrete :
280+
∀ (b1 b2 : Bool),
281+
(F["Bool.Implies"]'bool_implies_mem).concreteEval.bind
282+
(fun f => f () [.boolConst () b1, .boolConst () b2])
283+
= some (.boolConst () (!b1 || b2)) := by
284+
intro b1 b2; cases b1 <;> cases b2 <;> native_decide
285+
have h_inst_concrete := h_concrete p q
286+
rw [h_ceval_eq] at h_inst_concrete
287+
simpa using h_inst_concrete
278288
have h_vt : TyVarVal := fun _ => .tcons "bool" []
279289
have h_fv : FreeVarVal TP I.tcInterp := fun _ s =>
280290
@default _ (@SortDenote.instInhabited I.tcInterp I.allInhabited s)
281291
have h_inst := h_ic h_vt h_fv () Subst.empty
282-
[.const () (.boolConst p), .const () (.boolConst q)]
283-
(.const () (.boolConst (!p || q)))
292+
[.boolConst () p, .boolConst () q]
293+
(.boolConst () (!p || q))
284294
h_eval
285295
have h_args : List.Forall₂ (LExpr.HasTypeA (T := TP) [])
286-
[.const () (.boolConst p), .const () (.boolConst q)]
296+
[.boolConst () p, .boolConst () q]
287297
[.tcons "bool" [], .tcons "bool" []] :=
288298
.cons .const (.cons .const .nil)
289-
have h_result : LExpr.HasTypeA (T := TP) [] (.const () (.boolConst (!p || q))) (.tcons "bool" []) := .const
299+
have h_result : LExpr.HasTypeA (T := TP) [] (.boolConst () (!p || q)) (.tcons "bool" []) := .const
290300
have h_eq := h_inst h_args h_result
291301
change (!p || q) = I.opInterp "Bool.Implies" boolBinSort p q at h_eq
292302
exact h_eq.symm
@@ -306,21 +316,29 @@ private theorem bool_or_interp (I : Interp F) :
306316
unfold LFunc.InterpConsistentEvalReduce at h_ic
307317
rw [bool_or_input_tys, bool_or_output, bool_or_name] at h_ic
308318
funext p q
309-
have h_eval : ceval () [.const () (.boolConst p), .const () (.boolConst q)]
310-
= some (.const () (.boolConst (p || q))) := by
311-
sorry
319+
have h_eval : ceval () [.boolConst () p, .boolConst () q]
320+
= some (.boolConst () (p || q)) := by
321+
have h_concrete :
322+
∀ (b1 b2 : Bool),
323+
(F["Bool.Or"]'bool_or_mem).concreteEval.bind
324+
(fun f => f () [.boolConst () b1, .boolConst () b2])
325+
= some (.boolConst () (b1 || b2)) := by
326+
intro b1 b2; cases b1 <;> cases b2 <;> native_decide
327+
have h_inst_concrete := h_concrete p q
328+
rw [h_ceval_eq] at h_inst_concrete
329+
simpa using h_inst_concrete
312330
have h_vt : TyVarVal := fun _ => .tcons "bool" []
313331
have h_fv : FreeVarVal TP I.tcInterp := fun _ s =>
314332
@default _ (@SortDenote.instInhabited I.tcInterp I.allInhabited s)
315333
have h_inst := h_ic h_vt h_fv () Subst.empty
316-
[.const () (.boolConst p), .const () (.boolConst q)]
317-
(.const () (.boolConst (p || q)))
334+
[.boolConst () p, .boolConst () q]
335+
(.boolConst () (p || q))
318336
h_eval
319337
have h_args : List.Forall₂ (LExpr.HasTypeA (T := TP) [])
320-
[.const () (.boolConst p), .const () (.boolConst q)]
338+
[.boolConst () p, .boolConst () q]
321339
[.tcons "bool" [], .tcons "bool" []] :=
322340
.cons .const (.cons .const .nil)
323-
have h_result : LExpr.HasTypeA (T := TP) [] (.const () (.boolConst (p || q))) (.tcons "bool" []) := .const
341+
have h_result : LExpr.HasTypeA (T := TP) [] (.boolConst () (p || q)) (.tcons "bool" []) := .const
324342
have h_eq := h_inst h_args h_result
325343
change (p || q) = I.opInterp "Bool.Or" boolBinSort p q at h_eq
326344
exact h_eq.symm
@@ -340,21 +358,29 @@ private theorem bool_not_interp (I : Interp F) :
340358
unfold LFunc.InterpConsistentEvalReduce at h_ic
341359
rw [bool_not_input_tys, bool_not_output, bool_not_name] at h_ic
342360
funext p
343-
have h_eval : ceval () [.const () (.boolConst p)]
344-
= some (.const () (.boolConst (!p))) := by
345-
sorry
361+
have h_eval : ceval () [.boolConst () p]
362+
= some (.boolConst () (!p)) := by
363+
have h_concrete :
364+
∀ (b : Bool),
365+
(F["Bool.Not"]'bool_not_mem).concreteEval.bind
366+
(fun f => f () [.boolConst () b])
367+
= some (.boolConst () (!b)) := by
368+
intro b; cases b <;> native_decide
369+
have h_inst_concrete := h_concrete p
370+
rw [h_ceval_eq] at h_inst_concrete
371+
simpa using h_inst_concrete
346372
have h_vt : TyVarVal := fun _ => .tcons "bool" []
347373
have h_fv : FreeVarVal TP I.tcInterp := fun _ s =>
348374
@default _ (@SortDenote.instInhabited I.tcInterp I.allInhabited s)
349375
have h_inst := h_ic h_vt h_fv () Subst.empty
350-
[.const () (.boolConst p)]
351-
(.const () (.boolConst (!p)))
376+
[.boolConst () p]
377+
(.boolConst () (!p))
352378
h_eval
353379
have h_args : List.Forall₂ (LExpr.HasTypeA (T := TP) [])
354-
[.const () (.boolConst p)]
380+
[.boolConst () p]
355381
[.tcons "bool" []] :=
356382
.cons .const .nil
357-
have h_result : LExpr.HasTypeA (T := TP) [] (.const () (.boolConst (!p))) (.tcons "bool" []) := .const
383+
have h_result : LExpr.HasTypeA (T := TP) [] (.boolConst () (!p)) (.tcons "bool" []) := .const
358384
have h_eq := h_inst h_args h_result
359385
change (!p) = I.opInterp "Bool.Not" boolUnSort p at h_eq
360386
exact h_eq.symm

0 commit comments

Comments
 (0)