lean4-htt/library/tools/super/superposition.lean
2017-02-14 18:39:57 -08:00

133 lines
4.8 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) 2016 Gabriel Ebner. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner
-/
import .clause .prover_state .utils
open tactic monad expr
namespace super
def position := list
meta def get_rwr_positions : expr → list position
| (app a b) := [[]] ++
do arg ← list.zip_with_index (get_app_args (app a b)),
pos ← get_rwr_positions arg.1,
[arg.2 :: pos]
| (var _) := []
| e := [[]]
meta def get_position : expr → position → expr
| (app a b) (p::ps) :=
match list.nth (get_app_args (app a b)) p with
| some arg := get_position arg ps
| none := (app a b)
end
| e _ := e
meta def replace_position (v : expr) : expr → position → expr
| (app a b) (p::ps) :=
let args := get_app_args (app a b) in
match args^.nth p with
| some arg := app_of_list a^.get_app_fn $ args^.update_nth p $ replace_position arg ps
| none := app a b
end
| e [] := v
| e _ := e
variable gt : expr → expr → bool
variables (c1 c2 : clause)
variables (ac1 ac2 : derived_clause)
variables (i1 i2 : nat)
variable pos : list
variable ltr : bool
variable lt_in_termorder : bool
variable congr_ax : name
lemma {u v w} sup_ltr (F : Sort u) (A : Sort v) (a1 a2) (f : A → Sort w) : (f a1 → F) → f a2 → a1 = a2 → F :=
take hnfa1 hfa2 heq, hnfa1 (@eq.rec A a2 f hfa2 a1 heq^.symm)
lemma {u v w} sup_rtl (F : Sort u) (A : Sort v) (a1 a2) (f : A → Sort w) : (f a1 → F) → f a2 → a2 = a1 → F :=
take hnfa1 hfa2 heq, hnfa1 (@eq.rec A a2 f hfa2 a1 heq)
meta def is_eq_dir (e : expr) (ltr : bool) : option (expr × expr) :=
match is_eq e with
| some (lhs, rhs) := if ltr then some (lhs, rhs) else some (rhs, lhs)
| none := none
end
meta def try_sup : tactic clause := do
guard $ (c1^.get_lit i1)^.is_pos,
qf1 ← c1^.open_metan c1^.num_quants,
qf2 ← c2^.open_metan c2^.num_quants,
(rwr_from, rwr_to) ← (is_eq_dir (qf1.1^.get_lit i1)^.formula ltr)^.to_monad,
atom ← return (qf2.1^.get_lit i2)^.formula,
eq_type ← infer_type rwr_from,
atom_at_pos ← return $ get_position atom pos,
atom_at_pos_type ← infer_type atom_at_pos,
unify eq_type atom_at_pos_type,
unify rwr_from atom_at_pos transparency.none,
rwr_from' ← instantiate_mvars atom_at_pos,
rwr_to' ← instantiate_mvars rwr_to,
if lt_in_termorder
then guard (gt rwr_from' rwr_to')
else guard (¬gt rwr_to' rwr_from'),
rwr_ctx_varn ← mk_fresh_name,
abs_rwr_ctx ← return $
lam rwr_ctx_varn binder_info.default eq_type
(if (qf2.1^.get_lit i2)^.is_neg
then replace_position (mk_var 0) atom pos
else imp (replace_position (mk_var 0) atom pos) c2^.local_false),
lf_univ ← infer_univ c1^.local_false,
univ ← infer_univ eq_type,
atom_univ ← infer_univ atom,
op1 ← qf1.1^.open_constn i1,
op2 ← qf2.1^.open_constn c2^.num_lits,
hi2 ← (op2.2^.nth i2)^.to_monad,
new_atom ← whnf_no_delta $ app abs_rwr_ctx rwr_to',
new_hi2 ← return $ local_const hi2^.local_uniq_name `H binder_info.default new_atom,
new_fin_prf ←
return $ app_of_list (const congr_ax [lf_univ, univ, atom_univ]) [c1^.local_false, eq_type, rwr_from, rwr_to,
abs_rwr_ctx, (op2.1^.close_const hi2)^.proof, new_hi2],
clause.meta_closure (qf1.2 ++ qf2.2) $ (op1.1^.inst new_fin_prf)^.close_constn (op1.2 ++ op2.2^.update_nth i2 new_hi2)
meta def rwr_positions (c : clause) (i : nat) : list (list ) :=
get_rwr_positions (c^.get_lit i)^.formula
meta def try_add_sup : prover unit :=
(do c' ← try_sup gt ac1^.c ac2^.c i1 i2 pos ltr ff congr_ax,
inf_score 2 [ac1^.sc, ac2^.sc] >>= mk_derived c' >>= add_inferred)
<|> return ()
meta def superposition_back_inf : inference :=
take given, do active ← get_active, sequence' $ do
given_i ← given^.selected,
guard (given^.c^.get_lit given_i)^.is_pos,
option.to_monad $ is_eq (given^.c^.get_lit given_i)^.formula,
other ← rb_map.values active,
guard $ ¬given^.sc^.in_sos ¬other^.sc^.in_sos,
other_i ← other^.selected,
pos ← rwr_positions other^.c other_i,
-- FIXME(gabriel): ``sup_ltr fails to resolve at runtime
[do try_add_sup gt given other given_i other_i pos tt ``super.sup_ltr,
try_add_sup gt given other given_i other_i pos ff ``super.sup_rtl]
meta def superposition_fwd_inf : inference :=
take given, do active ← get_active, sequence' $ do
given_i ← given^.selected,
other ← rb_map.values active,
guard $ ¬given^.sc^.in_sos ¬other^.sc^.in_sos,
other_i ← other^.selected,
guard (other^.c^.get_lit other_i)^.is_pos,
option.to_monad $ is_eq (other^.c^.get_lit other_i)^.formula,
pos ← rwr_positions given^.c given_i,
[do try_add_sup gt other given other_i given_i pos tt ``super.sup_ltr,
try_add_sup gt other given other_i given_i pos ff ``super.sup_rtl]
@[super.inf]
meta def superposition_inf : inf_decl := inf_decl.mk 40 $
take given, do gt ← get_term_order,
superposition_fwd_inf gt given,
superposition_back_inf gt given
end super