lean4-htt/tests/lean/run/meta2.lean
2019-11-22 11:19:02 -08:00

167 lines
4.9 KiB
Text

import Init.Lean.Meta
open Lean
open Lean.Meta
def dbgOpt : Options :=
let opt : Options := {};
let opt := opt.setBool `trace.Meta true;
-- let opt := opt.setBool `trace.Meta.check false;
opt
def print (msg : MessageData) : MetaM Unit :=
trace! `Meta.debug msg
def check (x : MetaM Bool) : MetaM Unit :=
unlessM x $ throw $ Exception.other "check failed"
def getAssignment (m : Expr) : MetaM Expr :=
do v? ← getExprMVarAssignment m.mvarId!;
match v? with
| some v => pure v
| none => throw $ Exception.other "metavariable is not assigned"
def run (mods : List Name) (x : MetaM Unit) (opts : Options := dbgOpt) : IO Unit :=
do env ← importModules $ mods.map $ fun m => {module := m};
match x { config := { opts := opts } } { env := env } with
| EStateM.Result.ok _ s => do
s.traceState.traces.forM $ fun m => IO.println $ format m;
pure ()
| EStateM.Result.error err s => do
s.traceState.traces.forM $ fun m => IO.println $ format m;
throw (IO.userError (toString err))
def nat := mkConst `Nat
def succ := mkConst `Nat.succ
def add := mkConst `Nat.add
def tst1 : MetaM Unit :=
do print "----- tst1 -----";
mvar ← mkFreshExprMVar nat;
check $ isExprDefEq mvar (mkNatLit 10);
check $ isExprDefEq mvar (mkNatLit 10);
pure ()
#eval run [`Init.Data.Nat] tst1
def tst2 : MetaM Unit :=
do print "----- tst2 -----";
mvar ← mkFreshExprMVar nat;
check $ isExprDefEq (mkApp succ mvar) (mkApp succ (mkNatLit 10));
check $ isExprDefEq mvar (mkNatLit 10);
pure ()
#eval run [`Init.Data.Nat] tst2
def tst3 : MetaM Unit :=
do print "----- tst3 -----";
let t := mkLambda `x BinderInfo.default nat $ mkBVar 0;
mvar ← mkFreshExprMVar (mkForall `x BinderInfo.default nat nat);
lambdaTelescope t $ fun xs _ => do {
let x := xs.get! 0;
check $ isExprDefEq (mkApp mvar x) (mkAppN add #[x, mkAppN add #[mkNatLit 10, x]]);
pure ()
};
v ← getAssignment mvar;
print v;
pure ()
#eval run [`Init.Data.Nat] tst3
def tst4 : MetaM Unit :=
do print "----- tst4 -----";
let t := mkLambda `x BinderInfo.default nat $ mkBVar 0;
lambdaTelescope t $ fun xs _ => do {
let x := xs.get! 0;
mvar ← mkFreshExprMVar (mkForall `x BinderInfo.default nat nat);
-- the following `isExprDefEq` fails because `x` is also in the context of `mvar`
check $ not <$> isExprDefEq (mkApp mvar x) (mkAppN add #[x, mkAppN add #[mkNatLit 10, x]]);
check $ approxDefEq $ isExprDefEq (mkApp mvar x) (mkAppN add #[x, mkAppN add #[mkNatLit 10, x]]);
v ← getAssignment mvar;
print v;
pure ()
};
pure ()
#eval run [`Init.Data.Nat] tst4
def mkProd (a b : Expr) : MetaM Expr :=
do u ← getLevel a;
v ← getLevel b;
let r := mkAppN (mkConst `Prod [u.dec.getD u, v.dec.getD v]) #[a, b];
check r;
pure r
def mkPair (a b : Expr) : MetaM Expr :=
do aType ← inferType a;
bType ← inferType b;
u ← getLevel aType;
v ← getLevel bType;
let r := mkAppN (mkConst `Prod.mk [u.dec.getD u, v.dec.getD v]) #[aType, bType, a, b];
check r;
pure r
def mkFst (s : Expr) : MetaM Expr :=
do sType ← inferType s;
sType ← whnfUsingDefault sType;
unless (sType.isAppOfArity `Prod 2) $ throw $ Exception.other "product expected";
let lvls := sType.getAppFn.constLevels!;
let r := mkAppN (mkConst `Prod.fst lvls) #[sType.getArg! 0, sType.getArg! 1, s];
check r;
pure r
def mkSnd (s : Expr) : MetaM Expr :=
do sType ← inferType s;
sType ← whnfUsingDefault sType;
unless (sType.isAppOfArity `Prod 2) $ throw $ Exception.other "product expected";
let lvls := sType.getAppFn.constLevels!;
let r := mkAppN (mkConst `Prod.snd lvls) #[sType.getArg! 0, sType.getArg! 1, s];
check r;
pure r
def mkId (a : Expr) : MetaM Expr :=
do aType ← inferType a;
lvl ← getLevel aType;
let r := mkAppN (mkConst `id [lvl]) #[aType, a];
check r;
pure r
#print id
def tst5 : MetaM Unit :=
do print "----- tst5 -----";
p₁ ← mkPair (mkNatLit 1) (mkNatLit 2);
x ← mkFst p₁;
x ← mkId x;
print x;
prod ← mkProd nat nat;
m ← mkFreshExprMVar prod;
y ← mkFst m;
check $ isExprDefEq y x;
print y
#eval run [`Init.Data.Nat] tst5
def tst6 : MetaM Unit :=
do print "----- tst6 -----";
withLocalDecl `x nat BinderInfo.default $ fun x => do
m ← mkFreshExprMVar nat;
let t := mkAppN add #[m, mkNatLit 4];
let s := mkAppN add #[x, mkNatLit 3];
check $ not <$> isExprDefEq t s;
let s := mkAppN add #[x, mkNatLit 6];
check $ isExprDefEq t s;
v ← getAssignment m;
check $ pure $ v == mkAppN add #[x, mkNatLit 2];
print v;
m ← mkFreshExprMVar nat;
let t := mkAppN add #[m, mkNatLit 4];
let s := mkNatLit 3;
check $ not <$> isExprDefEq t s;
let s := mkNatLit 10;
check $ isExprDefEq t s;
v ← getAssignment m;
check $ pure $ v == mkNatLit 6;
print v;
pure ()
#eval run [`Init.Data.Nat] tst6