feat: add support for Lean.reduceNat and Lean.reduceBool at MetaM isDefEq

This commit is contained in:
Leonardo de Moura 2020-03-16 10:52:56 -07:00
parent b57d229efe
commit fba18edfa3
3 changed files with 62 additions and 4 deletions

View file

@ -36,6 +36,18 @@ if a.isLambda && !b.isLambda then do
else
pure false
/-- Support for `Lean.reduceBool` and `Lean.reduceNat` -/
def isDefEqNative (s t : Expr) : MetaM LBool := do
let isDefEq (s t) : MetaM LBool := toLBoolM $ isExprDefEqAux s t;
s? ← reduceNative? s;
match s? with
| some s => isDefEq s t
| none => do
t? ← reduceNative? t;
match t? with
| some t => isDefEq s t
| none => pure LBool.undef
/--
Return `true` if `e` is of the form `fun (x_1 ... x_n) => ?m x_1 ... x_n)`, and `?m` is unassigned.
Remark: `n` may be 0. -/
@ -990,6 +1002,7 @@ partial def isExprDefEqAuxImpl : Expr → Expr → MetaM Bool
whenUndefDo (isDefEqProofIrrel t s) $
isDefEqWHNF t s $ fun t s => do
condM (isDefEqEta t s <||> isDefEqEta s t) (pure true) $
whenUndefDo (isDefEqNative t s) $ do
whenUndefDo (isDefEqOffset t s) $ do
whenUndefDo (isDefEqDelta t s) $
match t, s with

View file

@ -21,13 +21,41 @@ Lean.WHNF.unfoldDefinitionAux getConstNoEx isAuxDef? whnf inferType isExprDefEq
def whnfCore (e : Expr) : MetaM Expr :=
Lean.WHNF.whnfCore getConstNoEx isAuxDef? whnf inferType isExprDefEqAux getLocalDecl getExprMVarAssignment? e
unsafe def reduceNativeConst (α : Type) (typeName : Name) (constName : Name) : MetaM α := do
env ← getEnv;
match env.evalConstCheck α typeName constName with
| Except.error ex => throw $ Exception.other ex
| Except.ok v => pure v
unsafe def reduceBoolNativeUnsafe (constName : Name) : MetaM Bool := reduceNativeConst Bool `Bool constName
unsafe def reduceNatNativeUnsafe (constName : Name) : MetaM Nat := reduceNativeConst Nat `Nat constName
@[implementedBy reduceBoolNativeUnsafe] constant reduceBoolNative (constName : Name) : MetaM Bool := arbitrary _
@[implementedBy reduceNatNativeUnsafe] constant reduceNatNative (constName : Name) : MetaM Nat := arbitrary _
def reduceNative? (e : Expr) : MetaM (Option Expr) :=
match e with
| Expr.app (Expr.const fName _ _) (Expr.const argName _ _) _ =>
if fName == `Lean.reduceBool then do
b ← reduceBoolNative argName;
pure $ if b then some $ mkConst `Bool.true else some $ mkConst `Bool.false
else if fName == `Lean.reduceNat then do
n ← reduceNatNative argName;
pure $ some $ mkNatLit n
else
pure none
| _ => pure none
partial def whnfImpl : Expr → MetaM Expr
| e => Lean.WHNF.whnfEasyCases getLocalDecl getExprMVarAssignment? e $ fun e => do
e ← whnfCore e;
e? ← unfoldDefinition? e;
match e? with
| some e => whnfImpl e
| none => pure e
v? ← reduceNative? e;
match v? with
| some v => pure v
| none => do
e? ← unfoldDefinition? e;
match e? with
| some e => whnfImpl e
| none => pure e
@[init] def setWHNFRef : IO Unit :=
whnfRef.set whnfImpl

View file

@ -0,0 +1,17 @@
def fact : Nat → Nat
| 0 => 1
| (n+1) => (n+1)*fact n
#eval fact 10
new_frontend
def v1 : Nat := fact 10
theorem tst1 : Lean.reduceNat v1 = 3628800 :=
rfl
def v2 : Bool := 10000000000000000 < 200000000000000000000
theorem tst2 : Lean.reduceBool v2 = true :=
rfl