feat(library/tactic/inversion_tactic): improve 'cases' tactic for HoTT library

This commit adds support for hypotheses (h : C As idxs) where the indices idxs
are just local constants. Before this commit the indices idxs had to be hsets.
Now, they can be hsets or local constants.

The new tests demonstrate new examples that can be handled by the
improved tactic in the HoTT library
This commit is contained in:
Leonardo de Moura 2014-12-21 15:19:25 -08:00
parent 70f7ec3cf2
commit 5efadb09cc
2 changed files with 35 additions and 8 deletions

View file

@ -327,7 +327,7 @@ class inversion_tac {
// when A is a hset
// and then invoke intro_next_eq recursively.
//
// \remark \c type is the type of \c g after whnf
// \remark \c type is the type of \c g after some normalization
goal intro_next_eq_rec(goal const & g, expr const & type) {
lean_assert(is_pi(type));
buffer<expr> hyps;
@ -365,10 +365,9 @@ class inversion_tac {
// The idea is to reduce it to
// Ctx, H : a = b |- R
// This method is only used if the environment has a proof irrelevant Prop.
//
// \remark \c type is the type of \c g after whnf
goal intro_next_heq(goal const & g, expr const & type) {
goal intro_next_heq(goal const & g) {
lean_assert(m_proof_irrel);
expr const & type = g.get_type();
expr eq = binding_domain(type);
lean_assert(const_name(get_app_fn(eq)) == "heq");
buffer<expr> args;
@ -399,7 +398,7 @@ class inversion_tac {
// The idea is to reduce it to
// Ctx, H : a = b |- R
//
// \remark \c type is the type of \c g after whnf
// \remark \c type is the type of \c g after some normalization
goal intro_next_eq_simple(goal const & g, expr const & type) {
expr eq = binding_domain(type);
lean_assert(const_name(get_app_fn(eq)) == "eq");
@ -416,7 +415,7 @@ class inversion_tac {
}
goal intro_next_eq(goal const & g) {
expr const & type = m_tc->whnf(g.get_type()).first;
expr type = g.get_type();
if (!is_pi(type))
throw_ill_formed_goal();
expr eq = binding_domain(type);
@ -425,13 +424,20 @@ class inversion_tac {
throw_ill_formed_goal();
if (const_name(eq_fn) == "eq") {
expr const & lhs = app_arg(app_fn(eq));
if (!m_proof_irrel && is_eq_rec(lhs)) {
expr const & rhs = app_arg(eq);
expr new_lhs = m_tc->whnf(lhs).first;
expr new_rhs = m_tc->whnf(rhs).first;
if (lhs != new_lhs || rhs != new_rhs) {
eq = mk_app(app_fn(app_fn(eq)), new_lhs, new_rhs);
type = update_binding(type, eq, binding_body(type));
}
if (!m_proof_irrel && is_eq_rec(new_lhs)) {
return intro_next_eq_rec(g, type);
} else {
return intro_next_eq_simple(g, type);
}
} else if (m_proof_irrel && const_name(eq_fn) == "heq") {
return intro_next_heq(g, type);
return intro_next_heq(g);
} else {
throw_ill_formed_goal();
}

View file

@ -0,0 +1,21 @@
open eq.ops
theorem trans {A : Type} {a b c : A} (h₁ : a = b) (h₂ : b = c) : a = c :=
begin
cases h₁, cases h₂, apply rfl
end
theorem symm {A : Type} {a b : A} (h₁ : a = b) : b = a :=
begin
cases h₁, apply rfl
end
theorem congr {A B : Type} (f : A → B) {a₁ a₂ : A} (h : a₁ = a₂) : f a₁ = f a₂ :=
begin
cases h, apply rfl
end
definition inv_pV_2 {A : Type} {x y z : A} (p : x = y) (q : z = y) : (p ⬝ q⁻¹)⁻¹ = q ⬝ p⁻¹ :=
begin
cases p, cases q, apply rfl
end