lean-ja / lean-by-example

コード例で学ぶ Lean 言語
https://lean-ja.github.io/lean-by-example/
MIT License
51 stars 7 forks source link

intro タクティク自作例 #1026

Open Seasawher opened 1 month ago

Seasawher commented 1 month ago
elab "my_intro" : tactic => do
  let mvarId ← getMainGoal
  let goalType ← getMainTarget

  let Expr.forallE _ pFrom pTo _ := goalType
    | throwError "Goal type is not of the form `a → b`"

  let handyMvarId ← withLocalDecl `hA BinderInfo.default pFrom (fun fvar => do
    -- 1. Create new `_`s with appropriate types.
    let mvarId1 ← mkFreshExprMVar pTo MetavarKind.syntheticOpaque `goal
    -- 2. Assign the main goal to the expression `fun hA => _`.
    mvarId.assign (← mkLambdaFVars #[fvar] mvarId1)
    -- just a handy way to return a handyRedMvarId for the next code
    return mvarId1.mvarId!
  )
  modify fun _ => { goals := [handyMvarId] }

example {p q : Prop} (hq : q) : p → q := by
  my_intro
  exact hq

example : Nat → Nat := by
  my_intro
  exact 0
Seasawher commented 1 month ago

識別子を引数に持つように変更

elab "my_intro" h:ident : tactic => do
  let mvarId ← getMainGoal
  let goalType ← getMainTarget

  let Expr.forallE _ pFrom pTo _ := goalType
    | throwError "Goal type is not of the form `a → b`"

  let handyMvarId ← withLocalDecl h.getId BinderInfo.default pFrom (fun fvar => do
    -- 1. Create new `_`s with appropriate types.
    let mvarId1 ← mkFreshExprMVar pTo MetavarKind.syntheticOpaque `goal
    -- 2. Assign the main goal to the expression `fun hA => _`.
    mvarId.assign (← mkLambdaFVars #[fvar] mvarId1)
    -- just a handy way to return a handyRedMvarId for the next code
    return mvarId1.mvarId!
  )
  modify fun _ => { goals := [handyMvarId] }

example {p q : Prop} (hq : q) : p → q := by
  my_intro hA
  exact hq

example : Nat → Nat := by
  my_intro hA
  exact 0