lean4-htt/tests/lean/run/isabelle.lean

112 lines
2.9 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Isabelle style tactics.
This test is based on a file created by Gabriel Ebner.
-/
universe variables u
inductive lazy_list (α : Type u) : Type u
| nil {} : lazy_list
| cons : α → thunk (lazy_list) → lazy_list
namespace lazy_list
variables {α β : Type u}
def singleton : α → lazy_list α
| a := cons a nil
def append : lazy_list α → thunk (lazy_list α) → lazy_list α
| nil l := l ()
| (cons h t) l := cons h (@append (t ()) l)
def join : lazy_list (lazy_list α) → lazy_list α
| nil := nil
| (cons h t) := append h (join (t ()))
def map (f : α → β) : lazy_list α → lazy_list β
| nil := nil
| (cons h t) := cons (f h) (map (t ()))
def for (l : lazy_list α) (f : α → β) : lazy_list β :=
map f l
def of_list : list α → lazy_list α
| [] := nil
| (h::t) := cons h (of_list t)
end lazy_list
meta def lazy_tactic (α : Type u) :=
tactic_state → lazy_list (α × tactic_state)
namespace lazy_tactic
open lazy_list
meta def of_tactic {α : Type u} (t : tactic α) : lazy_tactic α :=
λ s, match t s with
| result.success a new_s := lazy_list.singleton (a, new_s)
| result.exception f e s := lazy_list.nil
end
meta instance {α : Type} : has_coe (tactic α) (lazy_tactic α) :=
⟨of_tactic⟩
protected meta def return {α} (a : α) : lazy_tactic α :=
λ s, lazy_list.singleton (a, s)
protected meta def bind {α β} : lazy_tactic α → (α → lazy_tactic β) → lazy_tactic β :=
λ t₁ t₂ s, join (for (t₁ s) (λ ⟨a, new_s⟩, t₂ a new_s))
protected meta def orelse {α} (t₁ t₂ : lazy_tactic α) : lazy_tactic α :=
λ s, append (t₁ s) (t₂ s)
protected meta def failure {α} : lazy_tactic α :=
λ s, nil
meta instance : monad lazy_tactic :=
unsafe_monad_from_pure_bind @lazy_tactic.return @lazy_tactic.bind
meta instance : alternative lazy_tactic :=
{ lazy_tactic.monad with
failure := @lazy_tactic.failure,
orelse := @lazy_tactic.orelse }
meta def choose {α} (xs : list α) : lazy_tactic α :=
λ s, of_list $ xs^.map (λ a, (a, s))
meta def run {α} (t : lazy_tactic α) : tactic α :=
λ s, match t s with
| nil := tactic.failed s
| cons (a, new_s) ss := result.success a new_s
end
open tactic
private meta def try_constructors : list name → lazy_tactic unit
| [] := failure
| (c::cs) := (mk_const c >>= apply >> skip : tactic unit) <|> try_constructors cs
/- Backtracking version of constructor -/
meta def constructor : lazy_tactic unit :=
do t ← target,
cs ← get_constructors_for t,
try_constructors cs
end lazy_tactic
open lazy_tactic
example (p q : Prop) : q → p q :=
by run $ do
tactic.intros,
constructor,
tactic.trace_state,
tactic.assumption
meta def naive_instantiation : lazy_tactic unit :=
let vals := [``(1),``(2),``(3)] in do
x ← choose vals,
y ← choose vals,
e ← tactic.to_expr ``(nat.add_comm %%x %%y),
tactic.trace e,
tactic.exact e
lemma ex : 1 + 3 = 3 + 1 :=
by naive_instantiation^.run