lean4-htt/library/tools/super/subsumption.lean
Leonardo de Moura 66bc3c796a feat(frontends/lean/elaborator): add extra coercion resolution rule for monads
We also removed the notation (♯tac) since it is not needed anymore.

@gebner, the comment at elaborator.cpp explains why you had to use the ♯
notation. The workaround is a little bit hackish, but I think it is
worth it. We will use monad lifts in many different places.
2016-12-31 13:50:15 -08:00

92 lines
3.4 KiB
Text

/-
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
open tactic monad
namespace super
private meta def try_subsume_core : list clause.literal → list clause.literal → tactic unit
| [] _ := skip
| small large := first $ do
i ← small^.zip_with_index, j ← large^.zip_with_index,
return $ do
unify_lit i.1 j.1,
try_subsume_core (small^.remove_nth i.2) (large^.remove_nth j.2)
-- FIXME: this is incorrect if a quantifier is unused
meta def try_subsume (small large : clause) : tactic unit := do
small_open ← clause.open_metan small (clause.num_quants small),
large_open ← clause.open_constn large (clause.num_quants large),
guard $ small^.num_lits ≤ large^.num_lits,
try_subsume_core small_open.1^.get_lits large_open.1^.get_lits
meta def does_subsume (small large : clause) : tactic bool :=
(try_subsume small large >> return tt) <|> return ff
meta def does_subsume_with_assertions (small large : derived_clause) : prover bool := do
if small^.assertions^.subset_of large^.assertions then do
does_subsume small^.c large^.c
else
return ff
meta def any_tt {m : Type → Type} [monad m] (active : rb_map clause_id derived_clause) (pred : derived_clause → m bool) : m bool :=
active^.fold (return ff) $ λk a cont, do
v ← pred a, if v then return tt else cont
meta def any_tt_list {m : Type → Type} [monad m] {A} (pred : A → m bool) : list A → m bool
| [] := return ff
| (x::xs) := do v ← pred x, if v then return tt else any_tt_list xs
@[super.inf]
meta def forward_subsumption : inf_decl := inf_decl.mk 20 $
take given, do active ← get_active,
sequence' $ do a ← active^.values,
guard $ a^.id ≠ given^.id,
return $ do
ss ← does_subsume a^.c given^.c,
if ss
then remove_redundant given^.id [a]
else return ()
meta def forward_subsumption_pre : prover unit := preprocessing_rule $ λnew, do
active ← get_active, filter (λn, do
do ss ← any_tt active (λa,
if a^.assertions^.subset_of n^.assertions then do
does_subsume a^.c n^.c
else
-- TODO: move to locked
return ff),
return (bnot ss)) new
meta def subsumption_interreduction : list derived_clause → prover (list derived_clause)
| (c::cs) := do
-- TODO: move to locked
cs_that_subsume_c ← filter (λd, does_subsume_with_assertions d c) cs,
if ¬cs_that_subsume_c^.empty then
-- TODO: update score
subsumption_interreduction cs
else do
cs_not_subsumed_by_c ← filter (λd, lift bnot (does_subsume_with_assertions c d)) cs,
cs' ← subsumption_interreduction cs_not_subsumed_by_c,
return (c::cs')
| [] := return []
meta def subsumption_interreduction_pre : prover unit :=
preprocessing_rule $ λnew,
let new' := list.sort_on (λc : derived_clause, c^.c^.num_lits) new in
subsumption_interreduction new'
meta def keys_where_tt {m} {K V : Type} [monad m] (active : rb_map K V) (pred : V → m bool) : m (list K) :=
@rb_map.fold _ _ (m (list K)) active (return []) $ λk a cont, do
v ← pred a, rest ← cont, return $ if v then k::rest else rest
@[super.inf]
meta def backward_subsumption : inf_decl := inf_decl.mk 20 $ λgiven, do
active ← get_active,
ss ← keys_where_tt active (λa, does_subsume given^.c a^.c),
sequence' $ do id ← ss, guard (id ≠ given^.id), [remove_redundant id [given]]
end super