@@ -5,86 +5,13 @@ Authors: Leonardo de Moura
5
5
-/
6
6
prelude
7
7
import Init.Grind.Util
8
+ import Lean.Meta.LitValues
8
9
import Lean.Meta.Tactic.Grind.Types
9
10
import Lean.Meta.Tactic.Grind.Inv
10
- import Lean.Meta.LitValues
11
+ import Lean.Meta.Tactic.Grind.Propagate
12
+ import Lean.Meta.Tactic.Grind.PP
11
13
12
14
namespace Lean.Meta.Grind
13
- /-- Helper function for pretty printing the state for debugging purposes. -/
14
- def ppENodeRef (e : Expr) : GoalM Format := do
15
- let some n ← getENode? e | return "_"
16
- return f!"#{n.idx}"
17
-
18
- /-- Returns expressions in the given expression equivalence class. -/
19
- partial def getEqc (e : Expr) : GoalM (List Expr) :=
20
- go e e []
21
- where
22
- go (first : Expr) (e : Expr) (acc : List Expr) : GoalM (List Expr) := do
23
- let next ← getNext e
24
- let acc := e :: acc
25
- if isSameExpr first next then
26
- return acc
27
- else
28
- go first next acc
29
-
30
- /-- Returns all equivalence classes in the current goal. -/
31
- partial def getEqcs : GoalM (List (List Expr)) := do
32
- let mut r := []
33
- let nodes ← getENodes
34
- for node in nodes do
35
- if isSameExpr node.root node.self then
36
- r := (← getEqc node.self) :: r
37
- return r
38
-
39
- /-- Helper function for pretty printing the state for debugging purposes. -/
40
- def ppENodeDeclValue (e : Expr) : GoalM Format := do
41
- if e.isApp && !(← isLitValue e) then
42
- e.withApp fun f args => do
43
- let r ← if f.isConst then
44
- ppExpr f
45
- else
46
- ppENodeRef f
47
- let mut r := r
48
- for arg in args do
49
- r := r ++ " " ++ (← ppENodeRef arg)
50
- return r
51
- else
52
- ppExpr e
53
-
54
- /-- Helper function for pretty printing the state for debugging purposes. -/
55
- def ppENodeDecl (e : Expr) : GoalM Format := do
56
- let mut r := f!"{← ppENodeRef e} := {← ppENodeDeclValue e}"
57
- let n ← getENode e
58
- unless isSameExpr e n.root do
59
- r := r ++ f!" ↦ {← ppENodeRef n.root}"
60
- if n.interpreted then
61
- r := r ++ ", [val]"
62
- if n.ctor then
63
- r := r ++ ", [ctor]"
64
- if grind.debug.get (← getOptions) then
65
- if let some target ← getTarget? e then
66
- r := r ++ f!" ↝ {← ppENodeRef target}"
67
- return r
68
-
69
- /-- Pretty print goal state for debugging purposes. -/
70
- def ppState : GoalM Format := do
71
- let mut r := f!"Goal:"
72
- let nodes ← getENodes
73
- for node in nodes do
74
- r := r ++ "\n " ++ (← ppENodeDecl node.self)
75
- let eqcs ← getEqcs
76
- for eqc in eqcs do
77
- if eqc.length > 1 then
78
- r := r ++ "\n " ++ "{" ++ (Format.joinSep (← eqc.mapM ppENodeRef) ", " ) ++ "}"
79
- return r
80
-
81
- /--
82
- Returns `true` if `e` is `True`, `False`, or a literal value.
83
- See `LitValues` for supported literals.
84
- -/
85
- def isInterpreted (e : Expr) : MetaM Bool := do
86
- if e.isTrue || e.isFalse then return true
87
- isLitValue e
88
15
89
16
/--
90
17
Creates an `ENode` for `e` if one does not already exist.
@@ -96,23 +23,14 @@ def mkENode (e : Expr) (generation : Nat) : GoalM Unit := do
96
23
let interpreted ← isInterpreted e
97
24
mkENodeCore e interpreted ctor generation
98
25
99
- private def pushNewEqCore (lhs rhs proof : Expr) (isHEq : Bool) : GoalM Unit :=
100
- modify fun s => { s with newEqs := s.newEqs.push { lhs, rhs, proof, isHEq } }
101
-
102
- @[inline] private def pushNewEq (lhs rhs proof : Expr) : GoalM Unit := do
103
- if (← isDefEq (← inferType lhs) (← inferType rhs)) then
104
- pushNewEqCore lhs rhs proof (isHEq := false )
105
- else
106
- pushNewEqCore lhs rhs proof (isHEq := true )
107
-
108
26
/-- We use this auxiliary constant to mark delayed congruence proofs. -/
109
27
private def congrPlaceholderProof := mkConst (Name.mkSimple "[congruence]" )
110
28
111
29
/-- Adds `e` to congruence table. -/
112
30
def addCongrTable (e : Expr) : GoalM Unit := do
113
31
if let some { e := e' } := (← get).congrTable.find? { e } then
114
32
trace[grind.congr] "{e} = {e'}"
115
- pushNewEq e e' congrPlaceholderProof
33
+ pushEqHEq e e' congrPlaceholderProof
116
34
-- TODO: we must check whether the types of the functions are the same
117
35
-- TODO: update cgRoot for `e`
118
36
else
@@ -242,7 +160,8 @@ where
242
160
}
243
161
let parents ← removeParents lhsRoot.self
244
162
-- TODO: set propagateBool
245
- updateRoots lhs rhsNode.root true -- TODO
163
+ let isTrueOrFalse ← isTrueExpr rhsNode.root <||> isFalseExpr rhsNode.root
164
+ updateRoots lhs rhsNode.root (isTrueOrFalse && !(← isInconsistent))
246
165
trace[grind.debug] "{← ppENodeRef lhs} new root {← ppENodeRef rhsNode.root}, {← ppENodeRef (← getRoot lhs)}"
247
166
reinsertParents parents
248
167
setENode lhsNode.root { (← getENode lhsRoot.self) with -- We must retrieve `lhsRoot` since it was updated.
@@ -255,12 +174,18 @@ where
255
174
heqProofs := isHEq || rhsRoot.heqProofs || lhsRoot.heqProofs
256
175
}
257
176
copyParentsTo parents rhsNode.root
177
+ unless (← isInconsistent) do
178
+ if isTrueOrFalse then
179
+ for parent in parents do
180
+ propagateConectivesUp parent
258
181
259
- updateRoots (lhs : Expr) (rootNew : Expr) (_propagateBool : Bool) : GoalM Unit := do
182
+ updateRoots (lhs : Expr) (rootNew : Expr) (propagateTruth : Bool) : GoalM Unit := do
260
183
let rec loop (e : Expr) : GoalM Unit := do
261
184
-- TODO: propagateBool
262
185
let n ← getENode e
263
186
setENode e { n with root := rootNew }
187
+ if propagateTruth then
188
+ propagateConnectivesDown e
264
189
if isSameExpr lhs n.next then return ()
265
190
loop n.next
266
191
loop lhs
0 commit comments