lean4-htt/library/init/meta/inductive_compiler.lean

132 lines
4.3 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.

/-
Copyright (c) 2017 Daniel Selsam. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Daniel Selsam
-/
prelude
import init.meta.tactic init.meta.simp_tactic init.meta.rewrite_tactic init.meta.converter init.function
namespace inductive_compiler
namespace tactic
open tactic list
private meta def simp_assumption (ls : simp_lemmas) (e : expr) : tactic (expr × expr) := do
(a, new_e, pf) ← ext_simplify_core () {} ls (λ u, failed)
(λ a s r p e, failed)
(λ a s r p e, do ⟨u, new_e, pr⟩ ← conv.apply_lemmas_core s assumption r e,
return ((), new_e, pr, tt))
`iff e,
return (new_e, pf)
private meta def simp_at_assumption (S : simp_lemmas := simp_lemmas.mk) (h : expr) (extra_lemmas : list expr := []) (cfg : simp_config := {}) : tactic unit :=
do when (expr.is_local_constant h = ff) (fail "tactic fsimp_at failed, the given expression is not a hypothesis"),
htype ← infer_type h,
S ← S^.append extra_lemmas,
(new_htype, heq) ← simp_assumption S htype,
assert (expr.local_pp_name h) new_htype,
mk_app `iff.mp [heq, h] >>= exact,
try $ clear h
private meta def fsimp (extra_lemmas : list expr := []) (cfg : simp_config := {}) : tactic unit :=
do S ← return (simp_lemmas.mk),
S ← S^.append extra_lemmas,
simplify_goal S cfg >> try triv >> try (reflexivity reducible)
private meta def at_end (e : expr) : → tactic (list (option expr))
| 0 := fail "at_end expected arity > 0"
| 1 := return [some e]
| (n+1) := at_end n >>= (λ xs, return (none :: xs))
private meta def heq_to_eq_or_id (n : name) (H : expr) : tactic expr := do
Ht ← infer_type H,
do {
(A, lhs, B, rhs) ← match_heq Ht,
unify A B,
heq ← mk_app `eq [lhs, rhs],
pr ← mk_app `eq_of_heq [H],
assertv n heq pr,
clear H,
get_local n }
<|>
return H
private meta def intros_simp (inj_simps : simp_lemmas) : expr → tactic (list expr)
| (expr.pi n bi b d) := do
H ← intro n,
-- H ← heq_to_eq_or_id n H,
try $ simp_at_assumption inj_simps H,
H ← get_local n,
tgt ← target,
rest ← intros_simp tgt,
return (H :: rest)
| e := do return []
private meta def prove_conjuncts_by_assumption : list expr → expr → tactic unit
| (pf :: pfs) ```(and %%α %%β) := do
split,
exact pf,
prove_conjuncts_by_assumption pfs β
| [pf] _ := exact pf
| _ _ := fail "expecting same number of proofs as conjuncts"
private meta def intros_and_subst : expr → tactic unit
| (expr.pi n bi b d) := do
H ← intro n,
H ← heq_to_eq_or_id n H,
Ht ← infer_type H,
try $ do {
match_eq Ht,
subst H },
target >>= intros_and_subst
| e := return ()
private meta def tgt_to_eq : tactic unit := do
tgt ← target,
try (do c ← mk_const `heq_of_eq, apply c)
meta def prove_nested_inj (inj_simps : simp_lemmas) (inner_ir_inj_arrow : name) : tactic unit := do
xs ← intros,
triv <|> solve1 (do
H_orig_eq ← return (ilast xs),
c ← mk_const inner_ir_inj_arrow,
inner_inj ← to_expr `(%%c %%H_orig_eq),
apply inner_inj,
pfs ← (target >>= intros_simp inj_simps),
target >>= prove_conjuncts_by_assumption pfs)
meta def prove_pack_inj (unpack unpack_pack : name) : tactic unit := do
target >>= intros_and_subst,
split,
-- prove easy direction first
swap,
solve1 (do H ← intro1, H ← heq_to_eq_or_id `H_rhs_eq H, fsimp [H]),
-- hard direction
H ← intro1,
H ← heq_to_eq_or_id `H_lhs_eq H,
tgt_to_eq,
Ht ← infer_type H,
(lhs, rhs) ← match_eq Ht,
arity ← return (expr.get_app_num_args lhs),
args1 ← at_end lhs arity,
args2 ← at_end rhs arity,
lhs' ← mk_mapp unpack args1,
rhs' ← mk_mapp unpack args2,
H_ty ← mk_app `eq [lhs', rhs'],
assert `H_up H_ty,
solve1 (fsimp [H]),
H_up ← get_local `H_up,
solve1 (do e_unpack_pack ← mk_const unpack_pack,
rewrite_at_core semireducible tt tt occurrences.all ff e_unpack_pack H_up,
H_up ← get_local `H_up,
rewrite_at_core semireducible tt tt occurrences.all ff e_unpack_pack H_up,
H_up ← get_local `H_up,
exact H_up)
end tactic
end inductive_compiler