feat(library/init/meta): add contradiction tactic

This commit is contained in:
Leonardo de Moura 2016-06-16 18:17:14 -07:00
parent 67aa755a94
commit 301f3f93aa
4 changed files with 74 additions and 3 deletions

View file

@ -57,8 +57,14 @@ namespace tactic
variables {S A : Type}
open base_tactic_result
meta_definition fail (e : format) : base_tactic S unit :=
λ s, exception unit (λ u, e) s
meta_definition fail (e : string) : base_tactic S A :=
λ s, exception A (λ u, to_fmt e) s
meta_definition fail_fmt (e : format) : base_tactic S A :=
λ s, exception A (λ u, e) s
meta_definition failed : base_tactic S A :=
fail "failed"
meta_definition try (t : base_tactic S A) : base_tactic S unit :=
λ s, base_tactic_result.cases_on (t s)

View file

@ -0,0 +1,55 @@
/-
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import init.meta.tactic
open expr tactic option bool decidable environment
private meta_definition contra_A_not_A : list expr → list expr → tactic unit
| [] Hs := failed
| (H1 :: Rs) Hs :=
do t ← infer_type H1,
if is_not t = tt
then ((do H2 ← find_same_type (app_arg t) Hs,
tgt ← target,
pr ← mk_app "absurd" [tgt, H2, H1],
exact pr) <|> contra_A_not_A Rs Hs)
else contra_A_not_A Rs Hs
private meta_definition contra_false : list expr → tactic unit
| [] := failed
| (H :: Hs) :=
do t ← infer_type H,
if is_false t = tt
then do tgt ← target,
pr ← mk_app ("false" <.> "rec") [tgt, H],
exact pr
else contra_false Hs
private meta_definition contra_constructor_eq : list expr → tactic unit
| [] := failed
| (H :: Hs) :=
do t ← infer_type H,
match is_eq t with
| some (lhs, rhs) :=
do env ← get_env,
if is_constructor_app env lhs = tt ∧
is_constructor_app env rhs = tt ∧
const_name (get_app_fn lhs) ≠ const_name (get_app_fn rhs)
then do tgt ← target,
I_name ← return (name.get_prefix (const_name (get_app_fn lhs))),
pr ← mk_app (I_name <.> "no_confusion") [tgt, lhs, rhs, H],
exact pr
else contra_constructor_eq Hs
| none := contra_constructor_eq Hs
end
meta_definition tactic.contradiction : tactic unit :=
do ctx ← local_context,
(contra_false ctx <|>
contra_A_not_A ctx ctx <|>
contra_constructor_eq ctx <|>
fail "contradiction tactic failed")

View file

@ -6,4 +6,4 @@ Authors: Leonardo de Moura
prelude
import init.meta.name init.meta.options init.meta.format init.meta.rb_map
import init.meta.level init.meta.expr init.meta.base_tactic init.meta.environment
import init.meta.tactic
import init.meta.tactic init.meta.contradiction_tactic

View file

@ -135,4 +135,14 @@ meta_definition trace_result : tactic unit :=
do f ← format_result,
trace_fmt f
open bool
/- (find_same_type t es) tries to find in es an expression with type definitionally equal to t -/
meta_definition find_same_type : expr → list expr → tactic expr
| e [] := failed
| e (H :: Hs) :=
do t ← infer_type H,
b ← unify e t,
if b = tt then return H
else find_same_type e Hs
end tactic