Provers/classical: stricter checks to ensure that supplied intro, dest and
authorpaulson
Tue, 03 Jan 2006 15:44:39 +0100
changeset 18557 60a0f9caa0a2
parent 18556 dc39832e9280
child 18558 48d5419fd191
Provers/classical: stricter checks to ensure that supplied intro, dest and elim rules are well-formed
NEWS
src/HOL/Auth/Guard/Extensions.thy
src/HOL/IMP/Transition.thy
src/HOL/Lambda/Eta.thy
src/Provers/classical.ML
--- a/NEWS	Tue Jan 03 15:43:54 2006 +0100
+++ b/NEWS	Tue Jan 03 15:44:39 2006 +0100
@@ -189,6 +189,9 @@
 attribute; classical elim/dest rules are now treated uniformly when
 manipulating the claset.
 
+* Provers/classical: stricter checks to ensure that supplied intro, dest and 
+elim rules are well-formed; dest and elim rules must have at least one premise.
+
 * Syntax: input syntax now supports dummy variable binding "%_. b",
 where the body does not mention the bound variable.  Note that dummy
 patterns implicitly depend on their context of bounds, which makes
--- a/src/HOL/Auth/Guard/Extensions.thy	Tue Jan 03 15:43:54 2006 +0100
+++ b/src/HOL/Auth/Guard/Extensions.thy	Tue Jan 03 15:44:39 2006 +0100
@@ -11,7 +11,7 @@
 
 header {*Extensions to Standard Theories*}
 
-theory Extensions imports Event begin
+theory Extensions imports "../Event" begin
 
 subsection{*Extensions to Theory @{text Set}*}
 
@@ -279,8 +279,8 @@
 analz (G Un H) = H - keysfor G Un (analz (G Un (H Int keysfor G)))"
 apply (rule eq)
 apply (erule analz.induct, blast)
-apply (simp, blast dest: Un_upper1)
-apply (simp, blast dest: Un_upper2)
+apply (simp, blast)
+apply (simp, blast)
 apply (case_tac "Key (invKey K):H - keysfor G", clarsimp)
 apply (drule_tac X=X in no_key_no_Crypt)
 by (auto intro: analz_sub)
@@ -587,7 +587,7 @@
 
 lemma known_used [rule_format]: "[| evs:p; Gets_correct p; one_step p |]
 ==> X:parts (knows A evs) --> X:used evs"
-apply (case_tac "A=Spy", blast dest: parts_knows_Spy_subset_used)
+apply (case_tac "A=Spy", blast)
 apply (induct evs)
 apply (simp add: used.simps, blast)
 apply (frule_tac ev=a and evs=evs in one_step_Cons, simp, clarify)
@@ -600,7 +600,7 @@
 lemma known_max_used [rule_format]: "[| evs:p; Gets_correct p; one_step p |]
 ==> X:parts (knows_max A evs) --> X:used evs"
 apply (case_tac "A=Spy")
-apply (simp, blast dest: parts_knows_Spy_subset_used)
+apply force
 apply (induct evs)
 apply (simp add: knows_max_def used.simps, blast)
 apply (frule_tac ev=a and evs=evs in one_step_Cons, simp, clarify)
--- a/src/HOL/IMP/Transition.thy	Tue Jan 03 15:43:54 2006 +0100
+++ b/src/HOL/IMP/Transition.thy	Tue Jan 03 15:44:39 2006 +0100
@@ -208,7 +208,7 @@
 lemma rel_pow_Suc_0 [simp]: "!!R::('a*'a) set. R^(Suc 0) = R" by simp
 lemmas [simp del] = relpow.simps
 (*>*)
-lemma evalc1_None_0 [simp, dest!]: "\<langle>s\<rangle> -n\<rightarrow>\<^sub>1 y = (n = 0 \<and> y = \<langle>s\<rangle>)"
+lemma evalc1_None_0 [simp]: "\<langle>s\<rangle> -n\<rightarrow>\<^sub>1 y = (n = 0 \<and> y = \<langle>s\<rangle>)"
   by (cases n) auto
 
 lemma SKIP_n: "\<langle>\<SKIP>, s\<rangle> -n\<rightarrow>\<^sub>1 \<langle>s'\<rangle> \<Longrightarrow> s' = s \<and> n=1"
--- a/src/HOL/Lambda/Eta.thy	Tue Jan 03 15:43:54 2006 +0100
+++ b/src/HOL/Lambda/Eta.thy	Tue Jan 03 15:44:39 2006 +0100
@@ -407,7 +407,7 @@
       by (blast dest: par_eta_elim_abs)
     from abs have "size r' < size t" by simp
     with abs(2) rr obtain t' where rt: "r => t'" and t': "t' \<Rightarrow>\<^sub>\<eta> r''"
-      by (blast dest: less)
+      by (blast dest: less(1))
     with s abs show ?thesis
       by (auto intro: eta_expand_red eta_expand_eta)
   next
@@ -419,7 +419,7 @@
     from app have "size q' < size t" and "size r' < size t" by simp_all
     with app(2,3) qq rr obtain t' t'' where "q => t'" and
       "t' \<Rightarrow>\<^sub>\<eta> q''" and "r => t''" and "t'' \<Rightarrow>\<^sub>\<eta> r''"
-      by (blast dest: less)
+      by (blast dest: less(1))
     with s app show ?thesis
       by (fastsimp intro: eta_expand_red eta_expand_eta)
   next
@@ -431,7 +431,7 @@
     from beta have "size q' < size t" and "size r' < size t" by simp_all
     with beta(2,3) qq rr obtain t' t'' where "q => t'" and
       "t' \<Rightarrow>\<^sub>\<eta> q''" and "r => t''" and "t'' \<Rightarrow>\<^sub>\<eta> r''"
-      by (blast dest: less)
+      by (blast dest: less(1))
     with s beta show ?thesis
       by (auto intro: eta_expand_red eta_expand_beta eta_expand_eta par_eta_subst)
   qed
@@ -448,8 +448,8 @@
   case (2 s' s'' s''')
   from 2 obtain t' where s': "s' => t'" and t': "t' \<Rightarrow>\<^sub>\<eta> s'''"
     by (auto dest: par_eta_beta)
-  from s' obtain t'' where s: "s => t''" and t'': "t'' -e>> t'"
-    by (blast dest: 2)
+  from s' obtain t'' where s: "s => t''" and t'': "t'' -e>> t'" using 2
+    by blast
   from par_eta_subset_eta t' have "t' -e>> s'''" ..
   with t'' have "t'' -e>> s'''" by (rule rtrancl_trans)
   with s show ?case by iprover
--- a/src/Provers/classical.ML	Tue Jan 03 15:43:54 2006 +0100
+++ b/src/Provers/classical.ML	Tue Jan 03 15:44:39 2006 +0100
@@ -262,12 +262,8 @@
 fun dup_intr th = zero_var_indexes (th RS classical);
 
 fun dup_elim th =
-  (case try (fn () =>
     rule_by_tactic (TRYALL (etac revcut_rl))
-      ((th RSN (2, revcut_rl)) |> assumption 2 |> Seq.hd)) () of
-    SOME th' => th'
-  | _ => error ("Bad format for elimination rule\n" ^ string_of_thm th));
-
+      ((th RSN (2, revcut_rl)) |> assumption 2 |> Seq.hd);
 
 (**** Classical rule sets ****)
 
@@ -342,10 +338,10 @@
 (*For use with biresolve_tac.  Combines intro rules with swap to handle negated
   assumptions.  Pairs elim rules with true. *)
 fun joinrules (intrs, elims) =
-  (map (pair true) (elims @ swapify intrs) @ map (pair false) intrs);
+  (map (pair true) (elims @ swapify intrs)) @ map (pair false) intrs;
 
 fun joinrules' (intrs, elims) =
-  (map (pair true) elims @ map (pair false) intrs);
+  map (pair true) elims @ map (pair false) intrs;
 
 (*Priority: prefer rules with fewest subgoals,
   then rules added most recently (preferring the head of the list).*)
@@ -419,6 +415,8 @@
   if mem_thm (th, safeEs) then
          (warning ("Ignoring duplicate safe elimination (elim!)\n" ^ string_of_thm th);
           cs)
+  else if has_fewer_prems 1 th then
+    	error("Ill-formed elimination rule\n" ^ string_of_thm th)
   else
   let
       val th' = classical_rule th
@@ -445,6 +443,9 @@
 
 (*Give new theorem a name, if it has one already.*)
 fun name_make_elim th =
+    if has_fewer_prems 1 th then
+    	error("Ill-formed destruction rule\n" ^ string_of_thm th)
+    else
     case Thm.name_of_thm th of
         "" => Tactic.make_elim th
       | a  => Thm.name_thm (a ^ "_dest", Tactic.make_elim th);
@@ -475,7 +476,9 @@
         safe0_netpair = safe0_netpair,
         safep_netpair = safep_netpair,
         xtra_netpair = insert' 1 (nI,nE) ([th], []) xtra_netpair}
-  end;
+  end
+  handle THM("RSN: no unifiers",_,_) => (*from dup_intr*)
+         error ("Ill-formed introduction rule\n" ^ string_of_thm th);
 
 fun addE th
   (cs as CS {safeIs, safeEs, hazIs, hazEs, swrappers, uwrappers,
@@ -483,6 +486,8 @@
   if mem_thm (th, hazEs) then
          (warning ("Ignoring duplicate elimination (elim)\n" ^ string_of_thm th);
           cs)
+  else if has_fewer_prems 1 th then
+    	error("Ill-formed elimination rule\n" ^ string_of_thm th)
   else
   let
       val th' = classical_rule th
@@ -571,7 +576,10 @@
         safe0_netpair = safe0_netpair,
         safep_netpair = safep_netpair,
         xtra_netpair = delete' ([th], []) xtra_netpair}
- else cs;
+ else cs
+ handle THM("RSN: no unifiers",_,_) => (*from dup_intr*)
+        error ("Ill-formed introduction rule\n" ^ string_of_thm th);
+
 
 fun delE th
          (cs as CS{safeIs, safeEs, hazIs, hazEs, swrappers, uwrappers,