Nominal-General/nominal_thmdecls.ML
changeset 1841 fcc660ece040
parent 1835 636de31888a6
child 1846 756982b4fe20
--- a/Nominal-General/nominal_thmdecls.ML	Wed Apr 14 16:05:58 2010 +0200
+++ b/Nominal-General/nominal_thmdecls.ML	Wed Apr 14 18:46:59 2010 +0200
@@ -39,6 +39,28 @@
 structure Nominal_ThmDecls: NOMINAL_THMDECLS =
 struct
 
+fun get_ps trm =
+  case trm of 
+     Const (@{const_name permute}, _) $ p $ (Bound _) => raise TERM ("get_ps", [trm])
+   | Const (@{const_name permute}, _) $ p $ _ => [p]
+   | t $ u => get_ps t @ get_ps u
+   | Abs (_, _, t) => get_ps t 
+   | _ => []
+
+fun put_p p trm =
+  case trm of 
+     Bound _ => trm
+   | Const _ => trm
+   | t $ u => put_p p t $ put_p p u
+   | Abs (x, ty, t) => Abs (x, ty, put_p p t)
+   | _ => mk_perm p trm
+
+(* tests whether the lists of ps all agree, and that there is at least one p *)
+fun is_bad_list [] = true
+  | is_bad_list [_] = false
+  | is_bad_list (p::q::ps) = if p = q then is_bad_list (q::ps) else true
+
+
 structure EqvtData = Generic_Data
 ( type T = thm Item_Net.T;
   val empty = Thm.full_rules;
@@ -62,45 +84,48 @@
 
 fun add_raw_thm thm = 
   case prop_of thm of
-    Const ("==", _) $ _ $ _ => EqvtRawData.map (Item_Net.update thm)
+    Const ("==", _) $ _ $ _ => EqvtRawData.map (Item_Net.update (zero_var_indexes thm))
   | _ => raise THM ("Theorem must be a meta-equality", 0, [thm]) 
 
 val del_raw_thm = EqvtRawData.map o Item_Net.remove;
 
-fun eq_transform_tac thm = REPEAT o FIRST' 
-  [CHANGED o simp_tac (HOL_basic_ss addsimps @{thms permute_minus_cancel}),
-   rtac (thm RS @{thm trans}),
-   rtac @{thm trans[OF permute_fun_def]} THEN' rtac @{thm ext}]
+fun eq_transform_tac thm = 
+let
+  val ss_thms = @{thms permute_minus_cancel permute_prod.simps split_paired_all}
+in
+  REPEAT o FIRST' 
+    [CHANGED o simp_tac (HOL_basic_ss addsimps ss_thms),
+     rtac (thm RS @{thm trans}),
+     rtac @{thm trans[OF permute_fun_def]} THEN' rtac @{thm ext}]
+end
 
 (* transform equations into the "p o c = c"-form *)
 fun transform_eq ctxt thm = 
 let
-  val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (prop_of thm))
-  val (p, t) = dest_perm lhs
-  val (c, args) = strip_comb t
-  val (c', args') = strip_comb rhs
-  val eargs = map Envir.eta_contract args 
-  val eargs' = map Envir.eta_contract args'
-  val p_str = fst (fst (dest_Var p))
-  val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq (mk_perm p c, c))
+  val ((p, t), rhs) = apfst dest_perm 
+    (HOLogic.dest_eq (HOLogic.dest_Trueprop (prop_of thm)))
+    handle TERM _ => error "Eqvt lemma is not of the form p \<bullet> c...  = c..."
+  val ps = get_ps rhs handle TERM _ => []  
+  val (c, c') = (head_of t, head_of rhs)
 in
   if c <> c' 
     then error "Eqvt lemma is not of the right form (constants do not agree)"
-  else if eargs' <> map (mk_perm p) eargs 
+  else if is_bad_list (p::ps)  
+    then error "Eqvt lemma is not of the right form (permutations do not agree)" 
+  else if not (rhs aconv (put_p p t))
     then error "Eqvt lemma is not of the right form (arguments do not agree)"
-  else if args = [] 
+  else if is_Const t 
     then thm
-  else Goal.prove ctxt [p_str] [] goal
-    (fn _ => eq_transform_tac thm 1)
+  else 
+    let 
+      val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq (mk_perm p c, c))
+      val ([goal', p'], ctxt') = Variable.import_terms false [goal, p] ctxt
+    in
+      Goal.prove ctxt [] [] goal' (fn _ => eq_transform_tac thm 1)
+      |> singleton (ProofContext.export ctxt' ctxt)
+    end
 end
 
-
-(* tests whether the lists of pis all agree, and that there is at least one p *)
-fun is_bad_list [] = true
-  | is_bad_list [_] = false
-  | is_bad_list (p::q::ps) = if p = q then is_bad_list (q::ps) else true
-
-
 fun imp_transform_tac thy p p' thm = 
 let
   val cp = Thm.cterm_of thy p
@@ -116,20 +141,19 @@
 let
   val thy = ProofContext.theory_of ctxt
   val (prem, concl) = pairself HOLogic.dest_Trueprop (Logic.dest_implies (prop_of thm))
-  val (c, prem_args) = strip_comb prem
-  val (c', concl_args) = strip_comb concl
-  val ps = map (fst o dest_perm) concl_args handle TERM _ => []  
+  val (c, c') = (head_of prem, head_of concl)
+  val ps = get_ps concl handle TERM _ => []  
   val p = try hd ps
 in
   if c <> c' 
     then error "Eqvt lemma is not of the right form (constants do not agree)"
   else if is_bad_list ps  
     then error "Eqvt lemma is not of the right form (permutations do not agree)" 
-  else if concl_args <> map (mk_perm (the p)) prem_args 
+  else if not (concl aconv (put_p (the p) prem)) 
     then error "Eqvt lemma is not of the right form (arguments do not agree)"
   else 
     let
-      val prem' = Const (@{const_name "permute"}, @{typ "perm => bool => bool"}) $ (the p) $ prem    
+      val prem' = mk_perm (the p) prem    
       val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq (prem', concl))
       val ([goal', p'], ctxt') = Variable.import_terms false [goal, the p] ctxt
     in