|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LEAN/metam.lean.html
-- http://anggtwu.net/LEAN/metam.lean
-- (find-angg "LEAN/metam.lean")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun e () (interactive) (find-angg "LEAN/metam.lean"))
-- (find-leanmetadoc "md/main/04_metam#tactic-communication-via-metavariables")
import Lean
open Lean Lean.Expr Lean.Meta
example {α} (a : α) (f : α → α) (h : ∀ a, f a = a) : f (f a) = a := by
apply Eq.trans
apply h
apply h
#eval show MetaM Unit from do
-- Create two fresh metavariables of type `Nat`.
let mvar1 ← mkFreshExprMVar (Expr.const ``Nat []) (userName := `mvar1)
let mvar2 ← mkFreshExprMVar (Expr.const ``Nat []) (userName := `mvar2)
-- Create a fresh metavariable of type `Nat → Nat`. The `mkArrow` function
-- creates a function type.
let mvar3 ← mkFreshExprMVar (← mkArrow (.const ``Nat []) (.const ``Nat []))
(userName := `mvar3)
-- Define a helper function that prints each metavariable.
let printMVars : MetaM Unit := do
IO.println s!" meta1: {← instantiateMVars mvar1}"
IO.println s!" meta2: {← instantiateMVars mvar2}"
IO.println s!" meta3: {← instantiateMVars mvar3}"
IO.println "Initially, all metavariables are unassigned:"
printMVars
-- Assign `mvar1 : Nat := ?mvar3 ?mvar2`.
mvar1.mvarId!.assign (.app mvar3 mvar2)
IO.println "After assigning mvar1:"
printMVars
-- Assign `mvar2 : Nat := 0`.
mvar2.mvarId!.assign (.const ``Nat.zero [])
IO.println "After assigning mvar2:"
printMVars
-- Assign `mvar3 : Nat → Nat := Nat.succ`.
mvar3.mvarId!.assign (.const ``Nat.succ [])
IO.println "After assigning mvar3:"
printMVars
-- Initially, all metavariables are unassigned:
-- meta1: ?_uniq.1
-- meta2: ?_uniq.2
-- meta3: ?_uniq.3
-- After assigning mvar1:
-- meta1: ?_uniq.3 ?_uniq.2
-- meta2: ?_uniq.2
-- meta3: ?_uniq.3
-- After assigning mvar2:
-- meta1: ?_uniq.3 Nat.zero
-- meta2: Nat.zero
-- meta3: ?_uniq.3
-- After assigning mvar3:
-- meta1: Nat.succ Nat.zero
-- meta2: Nat.zero
-- meta3: Nat.succ
def myAssumption (mvarId : MVarId) : MetaM Bool := do
-- Check that `mvarId` is not already assigned.
mvarId.checkNotAssigned `myAssumption
-- Use the local context of `mvarId`.
mvarId.withContext do
-- The target is the type of `mvarId`.
let target ← mvarId.getType
-- For each hypothesis in the local context:
for ldecl in ← getLCtx do
-- If the hypothesis is an implementation detail, skip it.
if ldecl.isImplementationDetail then
continue
-- If the type of the hypothesis is definitionally equal to the target
-- type:
if ← isDefEq ldecl.type target then
-- Use the local hypothesis to prove the goal.
mvarId.assign ldecl.toExpr
-- Stop and return true.
return true
-- If we have not found any suitable local hypothesis, return false.
return false
def someNumber : Nat := (· + 2) $ 3
#print Nat
#print someNumber
#reduce someNumber
#eval someNumber
#eval Expr.const ``someNumber []
-- Lean.Expr.const `someNumber []
#eval reduce (Expr.const ``someNumber [])
-- Lean.Expr.lit (Lean.Literal.natVal 5)
def traceConstWithTransparency (md : TransparencyMode) (c : Name) :
MetaM Format := do
ppExpr (← withTransparency md $ reduce (.const c []))
@[irreducible] def irreducibleDef : Nat := 1
def defaultDef : Nat := irreducibleDef + 1
abbrev reducibleDef : Nat := defaultDef + 1
#print defaultDef
#print reducibleDef
-- Local Variables:
-- coding: utf-8-unix
-- End: