(* Title: Tools/intuitionistic.ML Author: Stefan Berghofer, TU Muenchen Simple intuitionistic proof search. *) signature INTUITIONISTIC = sig val prover_tac: Proof.context -> int option -> int -> tactic val method_setup: binding -> theory -> theory end; structure Intuitionistic: INTUITIONISTIC = struct (* main tactic *) local fun remdups_tac ctxt = SUBGOAL (fn (g, i) => let val prems = Logic.strip_assums_hyp g in REPEAT_DETERM_N (length prems - length (distinct op aconv prems)) (ematch_tac ctxt [Drule.remdups_rl] i THEN Tactic.eq_assume_tac i) end); fun REMDUPS tac ctxt = tac ctxt THEN_ALL_NEW remdups_tac ctxt; fun bires_tac ctxt = Tactic.biresolution_from_nets_tac ctxt Context_Rules.orderlist; fun safe_step_tac ctxt = Context_Rules.Swrap ctxt (eq_assume_tac ORELSE' bires_tac ctxt true (Context_Rules.netpair_bang ctxt)); fun unsafe_step_tac ctxt = Context_Rules.wrap ctxt (assume_tac ctxt APPEND' bires_tac ctxt false (Context_Rules.netpair_bang ctxt) APPEND' bires_tac ctxt false (Context_Rules.netpair ctxt)); fun step_tac ctxt i = REPEAT_DETERM1 (REMDUPS safe_step_tac ctxt i) ORELSE REMDUPS unsafe_step_tac ctxt i; fun intprover_tac ctxt gs d lim = SUBGOAL (fn (g, i) => if d > lim then no_tac else let val ps = Logic.strip_assums_hyp g; val c = Logic.strip_assums_concl g; in if member (fn ((ps1, c1), (ps2, c2)) => c1 aconv c2 andalso length ps1 = length ps2 andalso eq_set (op aconv) (ps1, ps2)) gs (ps, c) then no_tac else (step_tac ctxt THEN_ALL_NEW intprover_tac ctxt ((ps, c) :: gs) (d + 1) lim) i end); in fun prover_tac ctxt opt_lim = SELECT_GOAL (DEEPEN (2, the_default 20 opt_lim) (intprover_tac ctxt [] 0) 4 1); end; (* method setup *) local val introN = "intro"; val elimN = "elim"; val destN = "dest"; fun modifier name kind kind' att pos = Args.$$$ name |-- (kind >> K NONE || kind' |-- Parse.nat --| Args.colon >> SOME) >> (fn arg => Method.modifier (att arg) pos); val modifiers = [modifier destN Args.bang_colon Args.bang Context_Rules.dest_bang \<^here>, modifier destN Args.colon (Scan.succeed ()) Context_Rules.dest \<^here>, modifier elimN Args.bang_colon Args.bang Context_Rules.elim_bang \<^here>, modifier elimN Args.colon (Scan.succeed ()) Context_Rules.elim \<^here>, modifier introN Args.bang_colon Args.bang Context_Rules.intro_bang \<^here>, modifier introN Args.colon (Scan.succeed ()) Context_Rules.intro \<^here>, Args.del -- Args.colon >> K (Method.modifier Context_Rules.rule_del \<^here>)]; in fun method_setup name = Method.setup name (Scan.lift (Scan.option Parse.nat) --| Method.sections modifiers >> (fn opt_lim => fn ctxt => SIMPLE_METHOD' (Object_Logic.atomize_prems_tac ctxt THEN' prover_tac ctxt opt_lim))) "intuitionistic proof search"; end; end;