/- 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 open monad tactic expr namespace super local attribute [instance] has_monad_lift_to_has_coe meta def on_left_at {m} [monad m] (c : clause) (i : ℕ) [has_monad_lift_t tactic m] -- f gets a type and returns a list of proofs of that type (f : expr → m (list (list expr × expr))) : m (list clause) := do op ← c^.open_constn (c^.num_quants + i), @guard tactic _ (op.1^.get_lit 0)^.is_neg _, new_hyps ← f (op.1^.get_lit 0)^.formula, return $ new_hyps^.map (λnew_hyp, (op.1^.inst new_hyp.2)^.close_constn (op.2 ++ new_hyp.1)) meta def on_left_at_dn {m} [monad m] [alternative m] (c : clause) (i : ℕ) [has_monad_lift_t tactic m] -- f gets a hypothesis of ¬type and returns a list of proofs of false (f : expr → m (list (list expr × expr))) : m (list clause) := do qf ← c^.open_constn c^.num_quants, op ← qf.1^.open_constn c^.num_lits, lci ← (op.2^.nth i)^.to_monad, @guard tactic _ (qf.1^.get_lit i)^.is_neg _, h ← mk_local_def `h $ imp (qf.1^.get_lit i)^.formula c^.local_false, new_hyps ← f h, return $ new_hyps^.map $ λnew_hyp, (((clause.mk 0 0 new_hyp.2 c^.local_false c^.local_false)^.close_const h)^.inst (op.1^.close_const lci)^.proof)^.close_constn (qf.2 ++ op.2^.remove_nth i ++ new_hyp.1) meta def on_right_at {m} [monad m] (c : clause) (i : ℕ) [has_monad_lift_t tactic m] -- f gets a hypothesis and returns a list of proofs of false (f : expr → m (list (list expr × expr))) : m (list clause) := do op ← c^.open_constn (c^.num_quants + i), @guard tactic _ ((op.1^.get_lit 0)^.is_pos) _, h ← mk_local_def `h (op.1^.get_lit 0)^.formula, new_hyps ← f h, return $ new_hyps^.map (λnew_hyp, (op.1^.inst (lambdas [h] new_hyp.2))^.close_constn (op.2 ++ new_hyp.1)) meta def on_right_at' {m} [monad m] (c : clause) (i : ℕ) [has_monad_lift_t tactic m] -- f gets a hypothesis and returns a list of proofs (f : expr → m (list (list expr × expr))) : m (list clause) := do op ← c^.open_constn (c^.num_quants + i), @guard tactic _ ((op.1^.get_lit 0)^.is_pos) _, h ← mk_local_def `h (op.1^.get_lit 0)^.formula, new_hyps ← f h, for new_hyps (λnew_hyp, do type ← infer_type new_hyp.2, nh ← mk_local_def `nh $ imp type c^.local_false, return $ (op.1^.inst (lambdas [h] (app nh new_hyp.2)))^.close_constn (op.2 ++ new_hyp.1 ++ [nh])) meta def on_first_right (c : clause) (f : expr → tactic (list (list expr × expr))) : tactic (list clause) := first $ do i ← list.range c^.num_lits, [on_right_at c i f] meta def on_first_right' (c : clause) (f : expr → tactic (list (list expr × expr))) : tactic (list clause) := first $ do i ← list.range c^.num_lits, [on_right_at' c i f] meta def on_first_left (c : clause) (f : expr → tactic (list (list expr × expr))) : tactic (list clause) := first $ do i ← list.range c^.num_lits, [on_left_at c i f] meta def on_first_left_dn (c : clause) (f : expr → tactic (list (list expr × expr))) : tactic (list clause) := first $ do i ← list.range c^.num_lits, [on_left_at_dn c i f] end super