import Lean.Meta open Lean open Lean.Meta set_option pp.mvars false -- set_option trace.Meta true --set_option trace.Meta.isDefEq.step false -- set_option trace.Meta.isDefEq.delta false set_option trace.Meta.debug true def print (msg : MessageData) : MetaM Unit := do trace[Meta.debug] msg def checkM (x : MetaM Bool) : MetaM Unit := unless (← x) do throwError "check failed" def getAssignment (m : Expr) : MetaM Expr := do let v? ← getExprMVarAssignment? m.mvarId!; (match v? with | some v => pure v | none => throwError "metavariable is not assigned") def nat := mkConst `Nat def boolE := mkConst `Bool def succ := mkConst `Nat.succ def zero := mkConst `Nat.zero def add := mkConst `Nat.add def io := mkConst `IO def type := mkSort Level.one def boolFalse := mkConst `Bool.false def boolTrue := mkConst `Bool.true def tst1 : MetaM Unit := do print "----- tst1 -----"; let mvar <- mkFreshExprMVar nat; checkM $ isExprDefEq mvar (mkNatLit 10); checkM $ isExprDefEq mvar (mkNatLit 10); pure () /-- trace: [Meta.debug] ----- tst1 ----- -/ #guard_msgs in #eval tst1 def tst2 : MetaM Unit := do print "----- tst2 -----"; let mvar <- mkFreshExprMVar nat; checkM $ isExprDefEq (mkApp succ mvar) (mkApp succ (mkNatLit 10)); checkM $ isExprDefEq mvar (mkNatLit 10); pure () /-- trace: [Meta.debug] ----- tst2 ----- -/ #guard_msgs in #eval tst2 def tst3 : MetaM Unit := do print "----- tst3 -----"; let t := mkLambda `x BinderInfo.default nat $ mkBVar 0; let mvar ← mkFreshExprMVar (mkForall `x BinderInfo.default nat nat); lambdaTelescope t fun xs _ => do let x := xs[0]! checkM $ isExprDefEq (mkApp mvar x) (mkAppN add #[x, mkAppN add #[mkNatLit 10, x]]); pure (); let v ← getAssignment mvar; print v; pure () /-- trace: [Meta.debug] ----- tst3 ----- [Meta.debug] fun x => x.add (Nat.add 10 x) -/ #guard_msgs in #eval 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[0]! let mvar ← mkFreshExprMVar (mkForall `x BinderInfo.default nat nat); -- the following `isExprDefEq` fails because `x` is also in the context of `mvar` checkM $ not <$> isExprDefEq (mkApp mvar x) (mkAppN add #[x, mkAppN add #[mkNatLit 10, x]]); checkM $ approxDefEq $ isExprDefEq (mkApp mvar x) (mkAppN add #[x, mkAppN add #[mkNatLit 10, x]]); let v ← getAssignment mvar; print v; pure (); pure () /-- trace: [Meta.debug] ----- tst4 ----- [Meta.debug] fun x => x.add (Nat.add 10 x) -/ #guard_msgs in #eval tst4 def mkAppC (c : Name) (xs : Array Expr) : MetaM Expr := do let r ← mkAppM c xs; check r; pure r def mkProd (a b : Expr) : MetaM Expr := mkAppC `Prod #[a, b] def mkPair (a b : Expr) : MetaM Expr := mkAppC `Prod.mk #[a, b] def mkFst (s : Expr) : MetaM Expr := mkAppC `Prod.fst #[s] def mkSnd (s : Expr) : MetaM Expr := mkAppC `Prod.snd #[s] def tst5 : MetaM Unit := do print "----- tst5 -----"; let p₁ ← mkPair (mkNatLit 1) (mkNatLit 2); let x ← mkFst p₁; print x; let v ← whnf x; print v; let v ← withTransparency TransparencyMode.reducible $ whnf x; print v; let x ← mkId x; print x; let prod ← mkProd nat nat; let m ← mkFreshExprMVar prod; let y ← mkFst m; checkM $ isExprDefEq y x; print y; let x ← mkProjection p₁ `fst; print x; let y ← mkProjection p₁ `snd; print y /-- trace: [Meta.debug] ----- tst5 ----- [Meta.debug] (1, 2).fst [Meta.debug] 1 [Meta.debug] 1 [Meta.debug] id (1, 2).fst [Meta.debug] (1, 2).fst [Meta.debug] (1, 2).fst [Meta.debug] (1, 2).snd -/ #guard_msgs in #eval tst5 def tst6 : MetaM Unit := do print "----- tst6 -----"; withLocalDeclD `x nat $ fun x => do let m ← mkFreshExprMVar nat; let t := mkAppN add #[m, mkNatLit 4]; let s := mkAppN add #[x, mkNatLit 3]; checkM $ not <$> isExprDefEq t s; let s := mkAppN add #[x, mkNatLit 6]; checkM $ isExprDefEq t s; let v ← getAssignment m; checkM $ pure $ v == (← mkAdd x (mkNatLit 2)) print v; let m ← mkFreshExprMVar nat; let t := mkAppN add #[m, mkNatLit 4]; let s := mkNatLit 3; checkM $ not <$> isExprDefEq t s; let s := mkNatLit 10; checkM $ isExprDefEq t s; let v ← getAssignment m; checkM $ pure $ v == mkNatLit 6; print v; pure () /-- trace: [Meta.debug] ----- tst6 ----- [Meta.debug] x + 2 [Meta.debug] 6 -/ #guard_msgs in #eval tst6 def tst7 : MetaM Unit := do print "----- tst7 -----"; withLocalDeclD `x type $ fun x => do let m1 ← mkFreshExprMVar (← mkArrow type type); let m2 ← mkFreshExprMVar type; let t := mkApp io x; -- we need to use foApprox to solve `?m1 ?m2 =?= IO x` checkM $ not <$> isDefEq (mkApp m1 m2) t; checkM $ approxDefEq $ isDefEq (mkApp m1 m2) t; let v ← getAssignment m1; checkM $ pure $ v == io; let v ← getAssignment m2; checkM $ pure $ v == x; pure () /-- error: check failed --- trace: [Meta.debug] ----- tst7 ----- -/ #guard_msgs in #eval tst7 def tst9 : MetaM Unit := do print "----- tst9 -----"; let env ← getEnv; print (toString (← isReducible `Prod.fst)) print (toString (← isReducible `Add.add)) pure () /-- trace: [Meta.debug] ----- tst9 ----- [Meta.debug] true [Meta.debug] false -/ #guard_msgs in #eval tst9 def tst10 : MetaM Unit := do print "----- tst10 -----"; let t ← withLocalDeclD `x nat $ fun x => do { let b := mkAppN add #[x, mkAppN add #[mkNatLit 2, mkNatLit 3]]; mkLambdaFVars #[x] b }; print t; let t ← reduce t; print t; pure () /-- trace: [Meta.debug] ----- tst10 ----- [Meta.debug] fun x => x.add (Nat.add 2 3) [Meta.debug] fun x => x.succ.succ.succ.succ.succ -/ #guard_msgs in #eval tst10 def tst11 : MetaM Unit := do print "----- tst11 -----"; checkM $ isType nat; checkM $ isType (← mkArrow nat nat); checkM $ not <$> isType add; checkM $ not <$> isType (mkNatLit 1); withLocalDeclD `x nat fun x => do checkM $ not <$> isType x; checkM $ not <$> (mkLambdaFVars #[x] x >>= isType); checkM $ not <$> (mkLambdaFVars #[x] nat >>= isType); let t ← mkEq x (mkNatLit 0); let t ← mkForallFVars #[x] t (usedOnly := true); print t; checkM $ isType t; pure (); pure () /-- trace: [Meta.debug] ----- tst11 ----- [Meta.debug] ∀ (x : Nat), x = 0 -/ #guard_msgs in #eval tst11 def tst12 : MetaM Unit := do print "----- tst12 -----"; withLocalDeclD `x nat $ fun x => do let t ← mkEqRefl x >>= mkLambdaFVars #[x]; print t; let type ← inferType t; print type; isProofQuick t >>= fun b => print (toString b); isProofQuick nat >>= fun b => print (toString b); isProofQuick type >>= fun b => print (toString b); pure (); pure () /-- trace: [Meta.debug] ----- tst12 ----- [Meta.debug] fun x => Eq.refl x [Meta.debug] ∀ (x : Nat), x = x [Meta.debug] true [Meta.debug] false [Meta.debug] false -/ #guard_msgs in #eval tst12 def tst13 : MetaM Unit := do print "----- tst13 -----"; let m₁ ← mkFreshExprMVar (← mkArrow type type); let m₂ ← mkFreshExprMVar (mkApp m₁ nat); let t ← mkId m₂; print t; let r ← abstractMVars t; print r.expr; let (_, _, e) ← openAbstractMVarsResult r; print e; pure () def mkDecEq (type : Expr) : MetaM Expr := mkAppC `DecidableEq #[type] def mkStateM (σ : Expr) : MetaM Expr := mkAppC `StateM #[σ] def mkMonad (m : Expr) : MetaM Expr := mkAppC `Monad #[m] def mkMonadState (σ m : Expr) : MetaM Expr := mkAppC `MonadState #[σ, m] def mkAdd (a : Expr) : MetaM Expr := mkAppC `Add #[a] def mkToString (a : Expr) : MetaM Expr := mkAppC `ToString #[a] def tst14 : MetaM Unit := do print "----- tst14 -----"; let stateM ← mkStateM nat; print stateM; let monad ← mkMonad stateM; let globalInsts ← getGlobalInstancesIndex; let insts ← globalInsts.getUnify monad {}; print (insts.map (·.val)); pure () /-- trace: [Meta.debug] ----- tst14 ----- [Meta.debug] StateM Nat [Meta.debug] #[@StateT.instMonad] -/ #guard_msgs in #eval tst14 def tst15 : MetaM Unit := do print "----- tst15 -----"; let inst ← _root_.mkAdd nat; let r ← synthInstance inst; print r; pure () /-- trace: [Meta.debug] ----- tst15 ----- [Meta.debug] instAddNat -/ #guard_msgs in #eval tst15 def tst16 : MetaM Unit := do print "----- tst16 -----"; let prod ← mkProd nat nat; let inst ← mkToString prod; print inst; let r ← synthInstance inst; print r; pure () /-- trace: [Meta.debug] ----- tst16 ----- [Meta.debug] ToString (Nat × Nat) [Meta.debug] instToStringProd -/ #guard_msgs in #eval tst16 def tst17 : MetaM Unit := do print "----- tst17 -----"; let prod ← mkProd nat nat; let prod ← mkProd boolE prod; let inst ← mkToString prod; print inst; let r ← synthInstance inst; print r; pure () /-- trace: [Meta.debug] ----- tst17 ----- [Meta.debug] ToString (Bool × Nat × Nat) [Meta.debug] instToStringProd -/ #guard_msgs in #eval tst17 def tst18 : MetaM Unit := do print "----- tst18 -----"; let decEqNat ← mkDecEq nat; let r ← synthInstance decEqNat; print r; pure () /-- trace: [Meta.debug] ----- tst18 ----- [Meta.debug] instDecidableEqNat -/ #guard_msgs in #eval tst18 def tst19 : MetaM Unit := do print "----- tst19 -----"; let stateM ← mkStateM nat; print stateM; let monad ← mkMonad stateM; print monad; let r ← synthInstance monad; print r; pure () /-- trace: [Meta.debug] ----- tst19 ----- [Meta.debug] StateM Nat [Meta.debug] Monad (StateM Nat) [Meta.debug] StateT.instMonad -/ #guard_msgs in #eval tst19 def tst20 : MetaM Unit := do print "----- tst20 -----"; let stateM ← mkStateM nat; print stateM; let monadState ← mkMonadState nat stateM; print monadState; let r ← synthInstance monadState; print r; pure () /-- trace: [Meta.debug] ----- tst20 ----- [Meta.debug] StateM Nat [Meta.debug] MonadState Nat (StateM Nat) [Meta.debug] instMonadStateOfMonadStateOf Nat (StateM Nat) -/ #guard_msgs in #eval tst20 def tst21 : MetaM Unit := do print "----- tst21 -----"; withLocalDeclD `x nat $ fun x => do withLocalDeclD `y nat $ fun y => do withLocalDeclD `z nat $ fun z => do let eq₁ ← mkEq x y; let eq₂ ← mkEq y z; withLocalDeclD `h₁ eq₁ $ fun h₁ => do withLocalDeclD `h₂ eq₂ $ fun h₂ => do let h ← mkEqTrans h₁ h₂; let h ← mkEqSymm h; let h ← mkCongrArg succ h; let h₂ ← mkEqRefl succ; let h ← mkCongr h₂ h; let t ← inferType h; check h; print h; print t; let h ← mkCongrFun h₂ x; let t ← inferType h; check h; print t; pure () /-- trace: [Meta.debug] ----- tst21 ----- [Meta.debug] congrArg (fun x => x.succ.succ) (Eq.symm (Eq.trans h₁ h₂)) [Meta.debug] z.succ.succ = x.succ.succ [Meta.debug] x.succ = x.succ -/ #guard_msgs in #eval tst21 def tst22 : MetaM Unit := do print "----- tst22 -----"; withLocalDeclD `x nat $ fun x => do withLocalDeclD `y nat $ fun y => do let t ← mkAppC `Add.add #[x, y]; print t; let t ← mkAppC `Add.add #[y, x]; print t; let t ← mkAppC `ToString.toString #[x]; print t; pure () /-- trace: [Meta.debug] ----- tst22 ----- [Meta.debug] Add.add x y [Meta.debug] Add.add y x [Meta.debug] toString x -/ #guard_msgs in #eval tst22 def test1 : Nat := (fun x y => x + y) 0 1 def tst23 : MetaM Unit := do print "----- tst23 -----"; let cinfo ← getConstInfo `test1; let v := cinfo.value?.get!; print v; print v.headBeta /-- trace: [Meta.debug] ----- tst23 ----- [Meta.debug] (fun x y => x + y) 0 1 [Meta.debug] 0 + 1 -/ #guard_msgs in #eval tst23 def tst26 : MetaM Unit := do print "----- tst26 -----"; let m1 ← mkFreshExprMVar (← mkArrow nat nat); let m2 ← mkFreshExprMVar nat; let m3 ← mkFreshExprMVar nat; checkM $ approxDefEq $ isDefEq (mkApp m1 m2) m3; checkM $ do { let b ← m1.mvarId!.isAssigned; pure (!b) }; checkM $ m3.mvarId!.isAssigned; pure () /-- trace: [Meta.debug] ----- tst26 ----- -/ #guard_msgs in #eval tst26 section set_option trace.Meta.isDefEq true set_option trace.Meta.isDefEq.delta true set_option trace.Meta.isDefEq.assign true def tst27 : MetaM Unit := do print "----- tst27 -----"; let m ← mkFreshExprMVar nat; checkM $ isDefEq (mkNatLit 1) (mkApp (mkConst `Nat.succ) m); pure () #eval tst27 end def tst28 : MetaM Unit := do print "----- tst28 -----"; withLocalDeclD `x nat $ fun x => withLocalDeclD `y nat $ fun y => withLocalDeclD `z nat $ fun z => do let t1 ← mkAppM `Add.add #[x, y]; let t1 ← mkAppM `Add.add #[x, t1]; let t1 ← mkAppM `Add.add #[t1, t1]; let t2 ← mkAppM `Add.add #[z, y]; let t3 ← mkAppM `Eq #[t2, t1]; let t3 ← mkForallFVars #[z] t3; let m ← mkFreshExprMVar nat; let p ← mkAppM `Add.add #[x, m]; print t3; let r ← kabstract t3 p; print r; let p ← mkAppM `Add.add #[x, y]; let r ← kabstract t3 p; print r; pure () /-- trace: [Meta.debug] ----- tst28 ----- [Meta.debug] ∀ (z : Nat), Add.add z y = Add.add (Add.add x (Add.add x y)) (Add.add x (Add.add x y)) [Meta.debug] ∀ (z : Nat), Add.add z y = Add.add #0 #0 [Meta.debug] ∀ (z : Nat), Add.add z y = Add.add (Add.add x #0) (Add.add x #0) -/ #guard_msgs in #eval tst28 def norm : Level → Level := @Lean.Level.normalize def tst29 : MetaM Unit := do print "----- tst29 -----"; let u := mkLevelParam `u; let v := mkLevelParam `v; let u1 := mkLevelSucc u; let m := mkLevelMax Level.one u1; print (norm m); checkM $ pure $ norm m == u1; let m := mkLevelMax u1 Level.one; print (norm m); checkM $ pure $ norm m == u1; let m := mkLevelMax (mkLevelMax Level.one (mkLevelSucc u1)) (mkLevelSucc Level.one); checkM $ pure $ norm m == mkLevelSucc u1; print m; print (norm m); let m := mkLevelMax (mkLevelMax (mkLevelSucc (mkLevelSucc u1)) (mkLevelSucc u1)) (mkLevelSucc Level.one); print m; print (norm m); checkM $ pure $ norm m == mkLevelSucc (mkLevelSucc u1); let m := mkLevelMax (mkLevelMax (mkLevelSucc v) (mkLevelSucc u1)) (mkLevelSucc Level.one); print m; print (norm m); pure () /-- trace: [Meta.debug] ----- tst29 ----- [Meta.debug] u + 1 [Meta.debug] u + 1 [Meta.debug] max (max 1 (u + 2)) 2 [Meta.debug] u + 2 [Meta.debug] max (max (u + 3) (u + 2)) 2 [Meta.debug] u + 3 [Meta.debug] max (max (v + 1) (u + 2)) 2 [Meta.debug] max (u + 2) (v + 1) -/ #guard_msgs in #eval tst29 def tst30 : MetaM Unit := do print "----- tst30 -----"; let m1 ← mkFreshExprMVar nat; let m2 ← mkFreshExprMVar (← mkArrow nat nat); withLocalDeclD `x nat $ fun x => do let t := mkApp succ $ mkApp m2 x; print t; checkM $ approxDefEq $ isDefEq m1 t; let r ← instantiateMVars m1; print r; let r ← instantiateMVars m2; print r; pure () /-- trace: [Meta.debug] ----- tst30 ----- [Meta.debug] Nat.succ (?_ x) [Meta.debug] Nat.succ ?_ [Meta.debug] fun x => ?_ -/ #guard_msgs in #eval tst30 def tst31 : MetaM Unit := do print "----- tst31 -----"; let m ← mkFreshExprMVar nat; let t := mkLet `x nat zero m; print t; checkM $ isDefEq t m; pure () def tst32 : MetaM Unit := do print "----- tst32 -----"; withLocalDeclD `a nat $ fun a => do withLocalDeclD `b nat $ fun b => do let aeqb ← mkEq a b; withLocalDeclD `h2 aeqb $ fun h2 => do let t ← mkEq (mkApp2 add a a) a; print t; let motive := mkLambda `x BinderInfo.default nat (mkApp3 (mkConst `Eq [Level.one]) nat (mkApp2 add a (mkBVar 0)) a); withLocalDeclD `h1 t $ fun h1 => do let r ← mkEqNDRec motive h1 h2; print r; let rType ← inferType r >>= whnf; print rType; check r; pure () /-- trace: [Meta.debug] ----- tst32 ----- [Meta.debug] a.add a = a [Meta.debug] h2 ▸ h1 [Meta.debug] a.add b = a -/ #guard_msgs in #eval tst32 def tst33 : MetaM Unit := do print "----- tst33 -----"; withLocalDeclD `a nat $ fun a => do withLocalDeclD `b nat $ fun b => do let aeqb ← mkEq a b; withLocalDeclD `h2 aeqb $ fun h2 => do let t ← mkEq (mkApp2 add a a) a; let motive := mkLambda `x BinderInfo.default nat $ mkLambda `h BinderInfo.default (mkApp3 (mkConst `Eq [Level.one]) nat a (mkBVar 0)) $ (mkApp3 (mkConst `Eq [Level.one]) nat (mkApp2 add a (mkBVar 1)) a); withLocalDeclD `h1 t $ fun h1 => do let r ← mkEqRec motive h1 h2; print r; let rType ← inferType r >>= whnf; print rType; check r; pure () /-- trace: [Meta.debug] ----- tst33 ----- [Meta.debug] h2 ▸ h1 [Meta.debug] a.add b = a -/ #guard_msgs in #eval tst33 def tst34 : MetaM Unit := do print "----- tst34 -----"; let type := mkSort Level.one; withLocalDeclD `α type $ fun α => do let m ← mkFreshExprMVar type; let t ← mkLambdaFVars #[α] (← mkArrow m m); print t; pure () /-- trace: [Meta.debug] ----- tst34 ----- [Meta.debug] fun α => ?_ α → ?_ α -/ #guard_msgs in #eval tst34 def tst35 : MetaM Unit := do print "----- tst35 -----"; let type := mkSort Level.one; withLocalDeclD `α type $ fun α => do let m1 ← mkFreshExprMVar type; let m2 ← mkFreshExprMVar (← mkArrow nat type); let v := mkLambda `x BinderInfo.default nat m1; m2.mvarId!.assign v; let w := mkApp m2 zero; let t1 ← mkLambdaFVars #[α] (← mkArrow w w); print t1; let m3 ← mkFreshExprMVar type; let t2 ← mkLambdaFVars #[α] (← mkArrow (mkBVar 0) (mkBVar 1)); print t2; checkM $ isDefEq t1 t2; pure () /-- trace: [Meta.debug] ----- tst35 ----- [Meta.debug] fun α => ?_ α → ?_ α [Meta.debug] fun α => α → α -/ #guard_msgs in #eval tst35 #check @Id def tst36 : MetaM Unit := do print "----- tst36 -----"; let type := mkSort Level.one; let m1 ← mkFreshExprMVar (← mkArrow type type); withLocalDeclD `α type $ fun α => do let m2 ← mkFreshExprMVar type; let t ← mkAppM `Id #[m2]; checkM $ approxDefEq $ isDefEq (mkApp m1 α) t; checkM $ approxDefEq $ isDefEq m1 (mkConst `Id [Level.zero]); pure () /-- trace: [Meta.debug] ----- tst36 ----- -/ #guard_msgs in #eval tst36 def tst37 : MetaM Unit := do print "----- tst37 -----"; let m1 ← mkFreshExprMVar (←mkArrow nat (←mkArrow type type)); let m2 ← mkFreshExprMVar (←mkArrow nat type); withLocalDeclD `v nat $ fun v => do let lhs := mkApp2 m1 v (mkApp m2 v); let rhs ← mkAppM `StateM #[nat, nat]; print lhs; print rhs; checkM $ approxDefEq $ isDefEq lhs rhs; pure () /-- trace: [Meta.debug] ----- tst37 ----- [Meta.debug] ?_ v (?_ v) [Meta.debug] StateM Nat Nat -/ #guard_msgs in #eval tst37 def tst38 : MetaM Unit := do print "----- tst38 -----"; let m1 ← mkFreshExprMVar nat; withLocalDeclD `x nat $ fun x => do let m2 ← mkFreshExprMVar type; withLocalDeclD `y m2 $ fun y => do let m3 ← mkFreshExprMVar (←mkArrow m2 nat); let rhs := mkApp m3 y; checkM $ approxDefEq $ isDefEq m2 nat; print m2; checkM $ getAssignment m2 >>= fun v => pure $ v == nat; checkM $ approxDefEq $ isDefEq m1 rhs; print m2; checkM $ getAssignment m2 >>= fun v => pure $ v == nat; pure () set_option pp.all true set_option trace.Meta.isDefEq true set_option trace.Meta.isDefEq.delta true set_option trace.Meta.isDefEq.assign true #eval tst38 def tst39 : MetaM Unit := do print "----- tst39 -----"; withLocalDeclD `α type $ fun α => withLocalDeclD `β type $ fun β => do let p ← mkProd α β; let t ← mkForallFVars #[α, β] p; print t; let e ← instantiateForall t #[nat, boolE]; print e; pure () #eval tst39 def tst40 : MetaM Unit := do print "----- tst40 -----"; withLocalDeclD `α type $ fun α => withLocalDeclD `β type $ fun β => withLocalDeclD `a α $ fun a => withLocalDeclD `b β $ fun b => do let p ← mkProd α β; let t1 ← mkForallFVars #[α, β] p; let t2 ← mkForallFVars #[α, β, a, b] p; print t1; print $ toString $ t1.bindingBody!.hasLooseBVarInExplicitDomain 0 false; print $ toString $ t1.bindingBody!.hasLooseBVarInExplicitDomain 0 true; print $ toString $ t2.bindingBody!.hasLooseBVarInExplicitDomain 0 false; print $ t1.inferImplicit 2 false; checkM $ pure $ ((t1.inferImplicit 2 false).bindingInfo! == BinderInfo.default); checkM $ pure $ ((t1.inferImplicit 2 false).bindingBody!.bindingInfo! == BinderInfo.default); print $ t1.inferImplicit 2 true; checkM $ pure $ ((t1.inferImplicit 2 true).bindingInfo! == BinderInfo.implicit); checkM $ pure $ ((t1.inferImplicit 2 true).bindingBody!.bindingInfo! == BinderInfo.implicit); print t2; print $ t2.inferImplicit 2 false; checkM $ pure $ ((t2.inferImplicit 2 false).bindingInfo! == BinderInfo.implicit); checkM $ pure $ ((t2.inferImplicit 2 false).bindingBody!.bindingInfo! == BinderInfo.implicit); print $ t2.inferImplicit 1 false; checkM $ pure $ ((t2.inferImplicit 1 false).bindingInfo! == BinderInfo.implicit); checkM $ pure $ ((t2.inferImplicit 1 false).bindingBody!.bindingInfo! == BinderInfo.default); pure () #eval tst40 universe u structure A (α : Type u) := (x y : α) structure B (α : Type u) := (z : α) structure C (α : Type u) extends A α, B α := (w : Bool) def mkA (x y : Expr) : MetaM Expr := mkAppC `A.mk #[x, y] def mkB (z : Expr) : MetaM Expr := mkAppC `B.mk #[z] def mkC (x y z w : Expr) : MetaM Expr := do let a ← mkA x y; let b ← mkB z; mkAppC `C.mk #[a, b, w] def tst41 : MetaM Unit := do print "----- tst41 -----"; let c ← mkC (mkNatLit 1) (mkNatLit 2) (mkNatLit 3) boolTrue; print c; let x ← mkProjection c `x; check x; print x; let y ← mkProjection c `y; check y; print y; let z ← mkProjection c `z; check z; print z; let w ← mkProjection c `w; check w; print w; pure () set_option trace.Meta.isDefEq false set_option trace.Meta.isDefEq.delta false set_option trace.Meta.isDefEq.assign false #eval tst41 set_option pp.all false def tst42 : MetaM Unit := do print "----- tst42 -----"; let t ← mkListLit nat [mkRawNatLit 1, mkRawNatLit 2]; print t; check t; let t ← mkArrayLit nat [mkRawNatLit 1, mkRawNatLit 2]; print t; check t; (match t.arrayLit? with | some (_, xs) => do checkM $ pure $ xs.length == 2; (match xs[0]!.rawNatLit?, xs[1]!.rawNatLit? with | some 1, some 2 => pure () | _, _ => throwError "nat lits expected") | none => throwError "array lit expected") /-- trace: [Meta.debug] ----- tst42 ----- [Meta.debug] [1, 2] [Meta.debug] #[1, 2] -/ #guard_msgs in #eval tst42