Theory sym

Up to index of Isabelle/HOL/net

theory sym
imports net trajForm
begin

theory sym=net +trajForm:

constdefs
  bij_betw :: "['a => 'b, 'a set, 'b set] => bool"         (*bijective*)
    "bij_betw f A B == inj_on f A & f ` A = B"



constdefs nodes::"(entity set) => node set"
"nodes nl=={n. isDefinedIn n nl | (EX m. isDefinedIn m nl & n:set (fanins ((lookUp nl m))))}"

constdefs defAsOuts::"entity set => node set"
  "defAsOuts ns ≡ {n. isDefinedIn n ns}"
constdefs sym::"nodeFunType => entity set =>entity set=>bool"
  "sym f M  N == 
  bij f  & f ` (defAsOuts M) = (defAsOuts N) &
 (∀ m. isDefinedIn m M -->   isDefinedIn (f m) N   &             
  (let lx= (lookUp M  m) in
   let ly= (lookUp N (f m)) in
  (case ( lx)  of
   Input x => ly= Input ( f x)|
   Delay out data  => (ly= Delay (f out) (f data) )|
   Gate out inps tab =>  ( ly= Gate (f out) (map f inps) tab))))"

consts applySym2Form::"(node=>node)=>trajForm=>trajForm"
primrec 
  "applySym2Form f (Is1 n )=Is1 (f n) "
  "applySym2Form f (Is0 n )=Is0 (f n) "
  "applySym2Form f (A andT B)=(applySym2Form f A) andT (applySym2Form f B)"
  "applySym2Form f (P ->T F0)=P ->T (applySym2Form f F0)"
  "applySym2Form f (Next F0)=Next (applySym2Form f F0)"
  "applySym2Form f (chaos)=chaos"

constdefs applySym2State::"(node=>node)=>state=>state"
  "applySym2State f s n==s (f n)"

constdefs applySym2Seq::"(node=>node)=>stateSeq=>stateSeq"
  "applySym2Seq f sq t==applySym2State f (sq t) "

constdefs isSwap::"(node =>node)=>bool"
  "isSwap f == ∀ a b. f a=b --> f b=a"
lemma swapIdemponent:"isSwap f ==> f (f a)=a"
apply(unfold isSwap_def)
apply auto
done


lemma swapState:"isSwap f ==> applySym2State f (applySym2State f s) = s"
 apply(rule ext)
apply(unfold applySym2State_def)
apply(subgoal_tac "f (f x)=x")
apply(auto dest:swapIdemponent)
done




lemma swapSeq:"isSwap f ==> applySym2Seq f (applySym2Seq f sq)= sq"
apply(rule ext)
apply(unfold applySym2Seq_def)
by(rule swapState)


(*lemma symNetList:
  assumes a1:"M:netlistss"
  shows "sym f M N --> N:netlistss" (is "?P1 f M N --> ?P2 N")
using a1 
proof induct
  let ?nl="{}"
  show "?P1 f ?nl N-->?P2 N"
  proof
    assume b1:"?P1 f ?nl N"
    show "?P2 N"
    proof -
      have "nodes {}= {}" sorry 
      then have "nodes N={}"
        apply(cut_tac b1)
        apply(unfold sym_def)
        apply auto
        done
      then have "N={}" 
        apply(unfold nodes_def)
        apply simp
        sorry
      then show ?thesis
        apply -
        apply (simp,rule nilNetList)
        done
    qed
  qed
next*)
lemma defSqSym:
  
  shows "ALL B. B=applySym2Form f A -->isSwap f-->
  defSqOfTrForm B= applySym2Seq f (defSqOfTrForm A)" (is "ALL B. ?P A B")

proof(induct_tac A)
  fix n
  let ?A="(Is1 n)"
  show "ALL B. ?P ?A B"
  proof(rule allI,(rule impI)+)
    fix B
    assume 
      a2:"B = applySym2Form f ?A" and a3:"isSwap f"
    show " defSqOfTrForm B = applySym2Seq f (defSqOfTrForm ?A)"
    proof -
      from a2 have "B=Is1 (f n)" by simp
      then have b1:"defSqOfTrForm B=(λ t m. (if (t=0 & m=f n) then T else X))" by simp
      then show ?thesis
        apply simp
        apply(rule ext)
        apply(unfold applySym2Seq_def )
        apply(rule ext)+
        apply(unfold applySym2State_def )
        apply(cut_tac a3)
        apply(subgoal_tac " (m = f n) =(f m=n)")
        apply force
        apply(unfold isSwap_def) thm equalityI
        apply(rule iffI)
        apply blast
        apply(rule sym)
        apply blast
        done
    qed
  qed
next
  fix n
  let ?A="(Is0 n)"
  show "ALL B. ?P ?A B"
  proof(rule allI,(rule impI)+)
    fix B
    assume
      a2:"B = applySym2Form f ?A" and a3:"isSwap f"
    show " defSqOfTrForm B = applySym2Seq f (defSqOfTrForm ?A)"
    proof -
      from a2 have "B=Is0 (f n)" by simp
      then have b1:"defSqOfTrForm B=(λ t m. (if (t=0 & m=f n) then F else X))" by simp
      then show ?thesis
        apply simp
        apply(rule ext)
        apply(unfold applySym2Seq_def )
        apply(rule ext)+
        apply(unfold applySym2State_def )
        apply(cut_tac a3)
        apply(subgoal_tac " (m = f n) =(f m=n)")
        apply force
        apply(unfold isSwap_def) thm equalityI
        apply(rule iffI)
        apply blast
        apply(rule sym)
        apply blast
        done
    qed
  qed
next
  fix trajForm1 trajForm2
  assume b0:"ALL B. ?P trajForm1 B" and
  b1:"ALL B. ?P trajForm2 B"
  
  let ?A="(trajForm1 andT trajForm2 )"
  show "ALL B. ?P ?A B"
  proof(rule allI,(rule impI)+)
    fix B
    assume
      a2:"B = applySym2Form f ?A" and a3:"isSwap f"
    show " defSqOfTrForm B = applySym2Seq f (defSqOfTrForm ?A)"
    proof(rule ext)+
      fix t n
      show "defSqOfTrForm B t n=applySym2Seq f (defSqOfTrForm (trajForm1 andT trajForm2)) t n"
      proof -
        from a2 have c0:"B= (applySym2Form f trajForm1)andT (applySym2Form f trajForm2)"
          by simp
        
        

        from b0 have c1a:"(defSqOfTrForm (applySym2Form f trajForm1)  t n)= 
          applySym2Seq f (defSqOfTrForm trajForm1) t n"
          apply(cut_tac a3)
          apply(drule_tac x="applySym2Form f trajForm1" in spec)
          apply auto
          done
          
        from b1 have c1b:"(defSqOfTrForm (applySym2Form f trajForm2)  t n)= 
          applySym2Seq f (defSqOfTrForm trajForm2) t n"
          apply(cut_tac a3)
          apply(drule_tac x="applySym2Form f trajForm2" in spec)
          apply auto
          done

        
        have c1:"defSqOfTrForm B t n= lub (defSqOfTrForm (applySym2Form f trajForm1)  t n)
          (defSqOfTrForm (applySym2Form f trajForm2) t n)"
          by(cut_tac c0,  simp)

        also have c2:"…=
          lub (applySym2Seq f (defSqOfTrForm trajForm1) t n) (applySym2Seq f (defSqOfTrForm trajForm2) t n)"
          by (cut_tac c1 c1a c1b ,simp)

        also have "…=lub (defSqOfTrForm trajForm1 t (f n) ) (defSqOfTrForm trajForm2 t (f n) )"
          apply(simp add: applySym2Seq_def applySym2State_def)
          done
        also have "…=defSqOfTrForm (trajForm1 andT trajForm2) t (f n)"
          by simp
        also have "…=applySym2Seq f (defSqOfTrForm (trajForm1 andT trajForm2)) t n"
          by (simp add: applySym2Seq_def applySym2State_def)
        ultimately show ?thesis
          by auto

      qed
    qed
  qed
next
  fix P trajForm1
  assume b0:"ALL B. ?P trajForm1 B" 
  
  let ?A="(P ->T trajForm1 )"
  show "ALL B. ?P ?A B"
  proof(rule allI,(rule impI)+)
    fix B
    assume
      a2:"B = applySym2Form f ?A" and a3:"isSwap f"
    show " defSqOfTrForm B = applySym2Seq f (defSqOfTrForm ?A)"
    proof(rule ext)+
      fix t n
      show "defSqOfTrForm B t n=applySym2Seq f (defSqOfTrForm (?A)) t n"
      proof -
        from a2 have c0:"B= (P ->T(applySym2Form f trajForm1))"
          by simp
        from b0 have c1a:"(defSqOfTrForm (applySym2Form f trajForm1)  t n)= 
          applySym2Seq f (defSqOfTrForm trajForm1) t n"
          apply(cut_tac a3)
          apply(drule_tac x="applySym2Form f trajForm1" in spec)
          apply auto
          done
        
        have c1:"defSqOfTrForm B t n=
          (let v=(defSqOfTrForm (applySym2Form f trajForm1) t n) in
          (P-->(fst v), P--> (snd v))) "
          by(cut_tac c0,  simp)
        also have c2:"…=
          (let v= applySym2Seq f (defSqOfTrForm trajForm1) t n in
          (P-->(fst v), P--> (snd v))) "
          by(cut_tac c1 c1a  ,simp)
        also have c2:"…=
          (let v= (defSqOfTrForm trajForm1) t (f n) in
          (P-->(fst v), P--> (snd v))) "
          by(simp add: applySym2Seq_def applySym2State_def)
        also have "…=defSqOfTrForm  (?A) t (f n)"
          by simp
        also have "…=applySym2Seq f (defSqOfTrForm ?A) t n"
          by (simp add: applySym2Seq_def applySym2State_def)
        ultimately show ?thesis
          by auto
      qed
    qed
  qed
        
next
  fix  trajForm1
  assume b0:"ALL B. ?P trajForm1 B" 
  
  let ?A="(Next trajForm1 )"
  show "ALL B. ?P ?A B"
  proof(rule allI,(rule impI)+)
    fix B
    assume
      a2:"B = applySym2Form f ?A" and a3:"isSwap f"
    show " defSqOfTrForm B = applySym2Seq f (defSqOfTrForm ?A)"
    proof(rule ext)+
      fix t n
      show "defSqOfTrForm B t n=applySym2Seq f (defSqOfTrForm (?A)) t n"
      proof -
        from a2 have c0:"B= (Next (applySym2Form f trajForm1))"
          by simp
        from b0 have c1a:"(defSqOfTrForm (applySym2Form f trajForm1)  (t - 1) n)= 
          applySym2Seq f (defSqOfTrForm trajForm1) (t - 1) n"
          apply(cut_tac a3)
          apply(drule_tac x="applySym2Form f trajForm1" in spec)
          apply auto
          done
        
        have c1:"defSqOfTrForm B t n=
          (let v=(defSqOfTrForm (applySym2Form f trajForm1) (t - 1) n) in
          if (t~=0) then v else X)"
          apply(cut_tac c0,  simp)
          done
        also have c2:"…=
          (let v=applySym2Seq f (defSqOfTrForm trajForm1) (t - 1) n in
          if (t~=0) then v else X)"
          by(cut_tac c1 c1a  ,simp)
        also have c2:"…=
          (let v= (defSqOfTrForm trajForm1) (t - 1) (f n) in
          if (t~=0) then v else X)"
          by(simp add: applySym2Seq_def applySym2State_def)
        also have "…=defSqOfTrForm  (?A) t (f n)"
          by simp
        also have "…=applySym2Seq f (defSqOfTrForm ?A) t n"
          by (simp add: applySym2Seq_def applySym2State_def)
        ultimately show ?thesis
          by auto
      qed
    qed
  qed
next
  let ?A="(chaos )"
  show "ALL B. ?P ?A B"
  proof(rule allI,(rule impI)+)
    fix B
    assume
      a2:"B = applySym2Form f ?A" and a3:"isSwap f"
    show " defSqOfTrForm B = applySym2Seq f (defSqOfTrForm ?A)"
    proof(rule ext)+
      fix t n
      show "defSqOfTrForm B t n=applySym2Seq f (defSqOfTrForm (?A)) t n"
      proof -
        from a2 have c0:" B = chaos"
          by simp
        then have c1:"defSqOfTrForm B t n=X"
          by simp
        have c2:"applySym2Seq f (defSqOfTrForm (?A)) t n=X"
        proof(simp add: applySym2Seq_def applySym2State_def)qed
        with c1 show "defSqOfTrForm B t n=applySym2Seq f (defSqOfTrForm (?A)) t n"
          by simp
      qed
    qed
  qed
qed

lemma symNetTolatch:
  assumes a1:"isDelayNames  N n" and
  a2:"sym f M N" and
  a3:"M:netlists" and
  a4:"N:netlists" and
  a5:"isSwap f" 
  shows "isDelayNames M (f n) "
proof(unfold isDelayNames_def)
  from a4 a1 have b1:"isDefinedIn n N" 
  proof(rule_tac latchNameInNet) qed
  from a1 have "EX l data. (Delay n data)=l & l:N"
    by(unfold isDelayNames_def)
  then obtain lN dataN where b1a:" (Delay n dataN)=lN & lN:N"
    by auto
  then have b1b:"lookUp N n=(Delay n dataN)"
    apply(rule_tac lookUpIsTheDev)
    by auto
  from b1 have b2:"EX m. isDefinedIn m M& n=f m"
    apply(cut_tac a2,unfold sym_def  defAsOuts_def image_def)
    apply auto
    done
  then obtain m where b3:"isDefinedIn m M& n=f m" by blast
  
  from b3 have b4:"EX l. (l::entity):M &fanout l=m" 
    apply(unfold isDefinedIn_def,simp)
    by blast
  then obtain l where b5:"(l::entity):M & fanout l=m" by blast
  have b6:"f n=m"
    apply(cut_tac b3 a5,simp)
    by (rule swapIdemponent)
  show "∃l data. Delay (f n) data = l ∧ l ∈ M" (is "?P l")
  proof( cases  l)
    fix na
    let ?l="Input na"
    assume c1:"l =?l"
    show "?P ?l"
    proof -
      let ?l0="lookUp M m"
      have c2:"?l0=Input (f n)"
        apply(rule lookUpIsTheDev)
        apply(assumption)
        apply(cut_tac b6 c1 ,simp)
        apply(cut_tac b5,simp)
        by auto
      then have "lookUp N (f (f n)) = Input (f (f n))"
        apply(cut_tac b3 a2, unfold sym_def)
        apply(erule conjE)+
        apply(drule_tac x="m" in spec)
        apply auto
        apply(simp add:Let_def)
        apply(subgoal_tac "(f (f (f m)))= f m")
        apply simp
        by (rule swapIdemponent)
      then have "lookUp N n = Input n"
        apply(subgoal_tac "( (f (f n )))=  n")
        apply simp
        by (rule swapIdemponent)
      with b1b show "?P ?l" 
        by auto
    qed
  next
    fix na inps tab
    let ?l="Gate na inps tab"
    assume c1:"l =?l"
    show "?P ?l"
    proof -
      let ?l0="lookUp M m"
      have c2:"?l0=Gate (f n) inps tab"
        apply(rule lookUpIsTheDev)
        apply(assumption)
        apply(cut_tac b6 c1 ,simp)
        apply(cut_tac b5,simp)
        by auto
      then have "lookUp N (f (f n)) = Gate  (f (f n)) (map f inps) tab"
        apply(cut_tac b3 a2, unfold sym_def)
        apply(erule conjE)+
        apply(drule_tac x="m" in spec)
        apply auto
        apply(simp add:Let_def)
        apply(subgoal_tac "(f (f (f m)))= f m")
        apply simp
        by (rule swapIdemponent)
      then have "lookUp N n = Gate n (map f inps) tab"
        apply(subgoal_tac "( (f (f n )))=  n")
        apply simp
        by (rule swapIdemponent)
      with b1b show "?P ?l" 
        by auto
      
    qed
  next
    fix na dataa
    let ?l="Delay  na dataa"
    assume c1:"l =?l"
    show "?P ?l"
    proof(cut_tac c1 b5 b6,auto) qed
      
  qed
qed

lemma symNetTolatch2:
  assumes a1:"isDelayNames  M m" and
  a2:"sym f M N" and
  a3:"M:netlists" and
  a4:"N:netlists" and
  a5:"isSwap f" 
  shows "isDelayNames N (f m) "
proof(unfold isDelayNames_def)
  from a3 a1 have b1:"isDefinedIn m M" 
  proof(rule_tac latchNameInNet) qed
  from a1 have "EX l data. (Delay m data)=l & l:M"
    by(unfold isDelayNames_def)
  then obtain lM dataM where b1a:" (Delay m dataM)=lM & lM:M"
    by auto
  then have b1b:"lookUp M m=(Delay m dataM)"
    apply(rule_tac lookUpIsTheDev)
    by auto
  from b1 have b2:"EX n. isDefinedIn n N& n=f m"
    apply(cut_tac a2,unfold sym_def  defAsOuts_def image_def)
    apply auto
    done
  then obtain n where b3:"isDefinedIn n N& n=f m" by blast
  from b3 have b4:"EX l. (l::entity):N&fanout l=n" 
    apply(unfold isDefinedIn_def,simp)
    by blast
  then obtain l where b5:"(l::entity):N & fanout l=n" by blast
  have b6:"f n=m"
    apply(cut_tac b3 a5,simp)
    by (rule swapIdemponent)
  show "∃l data. Delay (f m) data = l ∧ l ∈ N" (is "?P l")
  proof( cases  lM)
    fix na
    let ?l="Input na"
    assume c1:"lM =?l"
    show "?P ?l"
    proof -
      let ?l0="lookUp M m"
      have c2:"?l0=Input m"
        apply(rule lookUpIsTheDev)
        
        apply(assumption)
        by(cut_tac b1a c1 ,simp)
      
      with b1b show "?P ?l" 
        by auto
    qed
  next
    fix na inps tab
    let ?l="Gate na inps tab"
    assume c1:"lM =?l"
    show "?P ?l"
    proof -
      let ?l0="lookUp M m"
      have c2:"?l0=Gate (f n) inps tab"
        apply(rule lookUpIsTheDev)
        apply(assumption)
        apply(cut_tac b1a c1 ,simp)
        done
      with b1b show "?P ?l" 
        by auto
    qed
  next
    fix na dataa
    let ?l="Delay  na dataa"
    assume c1:"lM =?l"
    show "?P ?l"
    proof - 
      let ?l0="lookUp M m"
      have c2:"?l0=Delay (m) dataa"
        apply(rule lookUpIsTheDev)
        apply(assumption)
        apply(cut_tac b1a c1 ,simp)
        done 
      have c3:"(lookUp N (f m))=Delay (f m) (f dataa)"
        apply(cut_tac a2 b1b,unfold sym_def)
        apply(cut_tac b1 c2,simp add:Let_def)
        apply auto
        done
      
      show ?thesis
        proof(rule_tac x="Delay (f m) (f dataa)" in exI,
              rule_tac x=" (f dataa)" in exI,simp)
          have " ( EX! enttr.(enttr):N 
                             &((enttr)= Input n |
                               ( EX data .(enttr)=Delay n data )|
                               (EX inps tab.( enttr)= Gate n inps tab)))" (is "EX! enttr. ?P enttr")
            apply(cut_tac b3, rule nodeNameIsUniqueInNet)
            by auto
          then obtain enttr where d1:"?P enttr & (ALL enttr0. ?P enttr0 --> enttr=enttr0)"
            by blast
            
            thm theI2
          have "lookUp N (f m): N"
            apply(cut_tac b3 d1, unfold lookUp_def)
            apply(rule_tac a="enttr" in  theI2)
            apply simp
            apply auto
            done
        
          then show "Delay (f m) (f dataa) ∈ N"
            apply(cut_tac c3,simp)
            done
        qed
      qed
    qed
      
  qed

lemma memMap:" x mem (map f inps) -->(  EX y. x=f y & y mem inps)"
  apply(induct_tac inps)
  apply simp
  apply auto
done

lemma memMap:" x mem (map f inps) ==>(  EX y. x=f y & y mem inps)"
  apply(cut_tac memMap[where x="x" and f="f" and inps="inps" ])
  apply simp
done

lemma defSqSym:
  assumes a1:"B = applySym2Form f A" and
  a2:"isSwap f"
  shows "defSqOfTrForm B= applySym2Seq f (defSqOfTrForm A)"
  apply -
  apply(cut_tac defSqSym[where f="f" and A="A"])
  apply(cut_tac a1 a2,auto)
  done

lemma arith1:" 0< x ==> EX n. x= Suc n" by arith


lemma symListAux:
"ALL stateLs. length stateLs = length inps --> isSwap f -->
  pair0 mem zip (map f inps) stateLs -->(f (fst pair0), snd pair0) mem  zip inps stateLs"(is "?P inps")
proof(induct inps,simp)
  fix a inps
  assume a1:"?P inps"
  show "?P (a#inps)"
  proof(rule allI,(rule impI)+)
    fix stateLs
    assume b1:"length stateLs = length (a # inps)" and
    b2:"pair0 mem zip (map f (a # inps)) stateLs" and
    b3:"isSwap f"
    show " (f (fst pair0), snd pair0) mem zip (a # inps) stateLs"
    proof -
      have d1:"0<length (a # inps)" by simp
          
          with b1 have "0<length stateLs" by simp
          then have d2:"EX y ys. stateLs = y # ys"
            apply -
            apply(subgoal_tac "EX n. length  stateLs=Suc n")
            apply(simp add:length_Suc_conv )
            by(rule arith1)
          from d2 obtain st1 and stl where d4:"stateLs =st1 # stl"
            by blast

          from this and b1 have d4a:"length stl=length inps"
            by simp

          let ?pair="(f (fst pair0), snd pair0)"
          from d4 b2 have "(f a, st1)=pair0 | pair0 mem (zip (map f inps) stl)"
            apply simp
            apply(case_tac "(f a, st1) = pair0")
            apply auto
            done
          
          moreover
          {assume e1:"(f a, st1)=pair0"
            have "?pair=(a, st1)" 
              apply(cut_tac e1 b3)
              apply auto
              by(rule swapIdemponent)
            then have ?thesis
              apply(cut_tac d4,simp)
              done
          }
           moreover
          {assume e1:" pair0 mem (zip (map f inps) stl)"  
            from a1 e1 d4a b3 d4 have ?thesis
              apply(drule_tac x="stl" in spec)
              apply auto
              done
          }
          ultimately show ?thesis by blast
        qed
      qed
    qed
lemma symListAux:
"[| length stateLs = length inps ; isSwap f ;
  pair0 mem zip (map f inps) stateLs |]==>(f (fst pair0), snd pair0) mem  zip inps stateLs"
  apply(cut_tac symListAux[where inps="inps" and ?pair0.0="pair0"])
  apply auto
done

lemma rclosureSym:
assumes 
  a1:"M:netlists" and
  a2:"pair:rclosure M s"  and 
  a3:"isSwap f" and
  a4:"sym f M N" and 
  a5:"N:netlists"
  
shows
  "((f (fst pair)), snd pair):rclosure N (applySym2State f s)" (is "?P pair")
using a2
proof(induct)
  fix x
  assume b1:"Input x ∈ M"
  let ?pair="(x, s x)"
  show "?P ?pair"
  proof(simp)
    have b2:"isDefinedIn x M"
      apply(cut_tac b1,unfold isDefinedIn_def)
      apply(rule_tac x="Input x" in bexI)
      by auto
    then have b3:"isDefinedIn (f x) N"
      apply(cut_tac a4,simp)
      apply(unfold sym_def)
      apply simp
      done
    have b4:"lookUp M x=Input x"
      apply(rule lookUpIsTheDev)
      by auto
    
    have b5:"(lookUp N (f x))=Input (f x)"
      apply(cut_tac b2 b4 a4)
      apply(unfold sym_def)
      apply auto
      apply(drule_tac x="x" in spec)
      apply(simp add:Let_def)+
      done
    let ?n="f x"
    have b6:"( EX! enttr.(enttr):N 
                             &((enttr)= Input ?n |
                               ( EX data .(enttr)=Delay ?n data )|
                               (EX inps tab.( enttr)= Gate ?n inps tab)))" (is "EX! enttr. ?Q enttr")
      apply(rule  nodeNameIsUniqueInNet)
      apply assumption
      apply(cut_tac b3,assumption)
      done thm theI
    
    have b7:"?Q (THE x.?Q x)"
      apply(cut_tac b6,rule theI')
      by assumption

    then have b8:"?Q (lookUp N ?n)"
      apply(unfold lookUp_def)
      apply(simp add:Let_def)
      done
    have "f (f x)=x"
      apply(cut_tac a3,unfold isSwap_def,simp)
      done
    then have b9:"s x=(applySym2State f s) (f x)"
      by(unfold applySym2State_def, simp)
    with b5 b8 b9 have b10:"Input (f x) :N" by ( simp)
    with b9 show "(f x, s x) ∈ rclosure N (applySym2State f s)"
      proof(simp,rule_tac stAddInput)
      qed
    qed
  next
    fix data n
    assume b1:" Delay n data ∈ M"
    let ?pair="(n, s n)"
    show "?P ?pair"
    proof(simp)
    have b2:"isDefinedIn n M"
      apply(cut_tac b1,unfold isDefinedIn_def)
      apply(rule_tac x=" Delay n data" in bexI)
      by auto
    then have b3:"isDefinedIn (f n) N"
      apply(cut_tac a4,simp)
      apply(unfold sym_def)
      apply simp
      done
    have b4:"lookUp M n= Delay n data"
      apply(rule lookUpIsTheDev)
      by auto
    
    have b5:"(lookUp N (f n))= Delay (f n) (f data)"
      apply(cut_tac b2 b4 a4)
      apply(unfold sym_def)
      apply auto
      apply(drule_tac x="n" in spec)
      apply(simp add:Let_def)+
      done
    let ?n="f n"
    have b6:"( EX! enttr.(enttr):N 
                             &((enttr)= Input ?n |
                               ( EX data .(enttr)=Delay ?n data )|
                               (EX inps tab.( enttr)= Gate ?n inps tab)))" (is "EX! enttr. ?Q enttr")
      apply(rule  nodeNameIsUniqueInNet)
      apply assumption
      apply(cut_tac b3,assumption)
      done thm theI
    
    have b7:"?Q (THE x.?Q x)"
      apply(cut_tac b6,rule theI')
      by assumption

    then have b8:"?Q (lookUp N ?n)"
      apply(unfold lookUp_def)
      apply(simp add:Let_def)
      done
    have "f (f n)=n"
      apply(cut_tac a3,unfold isSwap_def,simp)
      done
    then have b9:"s n=(applySym2State f s) (f n)"
      by(unfold applySym2State_def, simp)
    with b5 b8 b9 have b10:"Delay (f n) (f data) :N" by ( simp)
    with b9 show "(f n, s n) ∈ rclosure N (applySym2State f s)"
      proof(simp,rule_tac stAddDelay)
      qed
    qed
  next
    fix inps n stateLs tab
    assume b1:"Gate n inps tab ∈ M" and b0a:"length stateLs = length inps" and
    b0c:"∀l. l ∈ set tab --> length l = length inps" and
    b0d:"∀pair0. pair0 mem zip inps stateLs -->
                pair0 ∈ rclosure M s ∧ (f (fst pair0), snd pair0) ∈ rclosure N (applySym2State f s)"
    let ?pair=" (n, lub (funOfTab tab stateLs) (s n))"
    let ?l="Gate n inps tab "
    let ?l'="Gate (f n) (map f inps) tab "
    show "?P ?pair"
    proof(simp)
      have b2:"isDefinedIn n M"
      apply(cut_tac b1,unfold isDefinedIn_def)
      apply(rule_tac x="?l" in bexI)
      by auto
    then have b3:"isDefinedIn (f n) N"
      apply(cut_tac a4,simp)
      apply(unfold sym_def)
      apply simp
      done
    have b4:"lookUp M n= ?l"
      apply(rule lookUpIsTheDev)
      by auto
    
    have b5:"(lookUp N (f n))=?l'"
      apply(cut_tac b2 b4 a4)
      apply(unfold sym_def)
      apply auto
      apply(drule_tac x="n" in spec)
      apply(simp add:Let_def)+
      done
    let ?n="f n"
    have b6:"( EX! enttr.(enttr):N 
                             &((enttr)= Input ?n |
                               ( EX data .(enttr)=Delay ?n data )|
                               (EX inps tab.( enttr)= Gate ?n inps tab)))" (is "EX! enttr. ?Q enttr")
      apply(rule  nodeNameIsUniqueInNet)
      apply assumption
      apply(cut_tac b3,assumption)
      done thm theI
    
    have b7:"?Q (THE x.?Q x)"
      apply(cut_tac b6,rule theI')
      by assumption

    then have b8:"?Q (lookUp N ?n)"
      apply(unfold lookUp_def)
      apply(simp add:Let_def)
      done
    have "f (f n)=n"
      apply(cut_tac a3,unfold isSwap_def,simp)
      done
    then have b9:"s n=(applySym2State f s) (f n)"
      by(unfold applySym2State_def, simp)
    with b5 b8 b9 have b10:"?l' :N" by ( simp)
    with b9 show "(f n,lub (funOfTab tab stateLs)  (s n)) ∈ rclosure N (applySym2State f s)"
      proof(simp,rule_tac inps="(map f inps)" in stAddGate,
          simp)
        show "length stateLs = length (map f inps)"
          apply(cut_tac b0a,simp)
          done
        show "∀l. l ∈ set tab --> length l = length (map f inps)"
           apply(cut_tac b0c,simp)
          done
        show "∀pair0. pair0 mem zip (map f inps) stateLs --> pair0 ∈ rclosure N (applySym2State f s)"
          proof(rule allI,rule impI)
            fix pair0
            assume c1:" pair0 mem zip (map f inps) stateLs"
            let ?pair="(f (fst pair0), snd pair0)"
            have c5:" ?pair mem  zip inps stateLs"
              apply(rule symListAux)
              by assumption
            from this b0d show " pair0 ∈ rclosure N (applySym2State f s)"
              apply(drule_tac x="?pair" in spec)
              apply auto
              apply(subgoal_tac " pair0=(f (f (fst pair0)), snd pair0)")
             
              apply auto
              apply(subgoal_tac " f (f (fst pair0))=(fst pair0)")
              apply simp
              by(rule swapIdemponent)
          qed
        qed
      qed
    qed

lemma fclosureSym:
assumes 
  a1:"M:netlists" and
  a2:"isDefinedIn n M" and
  a3:"isSwap f" and
  a4:"sym f M N" and 
  a5:"N:netlists"
  
shows
  "fclosure M s n=fclosure N (applySym2State f s) (f n)"
proof -
let ?pair0="(n,fclosure M s n)"
let ?pairN="((f n), fclosure N (applySym2State f s) (f n))"
have b1:"?pair0: rclosure M s"
  by(rule fclosureIsrclosure)
have b2:"?pairN: rclosure N  (applySym2State f s)"
  apply(rule fclosureIsrclosure)
  apply assumption
  apply(cut_tac a4 a3 a2)
  apply(unfold sym_def)
  by blast
have "((f (fst ?pair0)), snd ?pair0):rclosure N (applySym2State f s)"
  apply(cut_tac b1,rule rclosureSym)
  by auto
then have b3:"((f n), fclosure M s n):rclosure N (applySym2State f s)"
  by simp
let ?pair1="((f n), fclosure M s n)"
from b3 a4 a3 a2 show ?thesis thm sym
  apply -
  apply(rule_tac HOL.sym)
  apply(subgoal_tac "fclosure N (applySym2State f s) (f n)=snd ?pair1")
  apply simp
  apply(rule_tac pair="?pair1" in fclosureVal)
  apply assumption
  apply auto
  apply(unfold sym_def)
  by blast
qed

lemma fclosureSym':
assumes 
  a1:"M:netlists" and
  a3:"isSwap f" and
  a4:"sym f M N" and 
  a5:"N:netlists"
  
shows
  "fclosure M s n=fclosure N (applySym2State f s) (f n)" (is "?Consq") 
proof(case_tac "isDefinedIn n M")
  assume b1:"isDefinedIn n M"
  show "?Consq"
  proof(rule fclosureSym) qed
next
  assume b1:"~isDefinedIn n M"
  show "?Consq"
  proof -
    from b1 have c1:"fclosure M s n=s n"
    proof(simp add:fclosure_def) qed
    have c2:"~isDefinedIn (f n) N"
    proof(rule_tac ccontr,simp)
      assume d1:"isDefinedIn (f n) N"
      have "EX m. m : defAsOuts M & f n=f m"
      proof(cut_tac d1 a4,
          unfold sym_def image_def defAsOuts_def,
          auto)
      qed
      then obtain x where d2:" x: defAsOuts M & f n=f x"
        by blast
      with a4 have "n =x"
      proof(unfold sym_def bij_def inj_on_def,blast)qed
      with a3 d2 have "isDefinedIn n M"
      proof(simp add:swapIdemponent defAsOuts_def)qed
      with b1 show False
        by simp
    qed
    with a3 have c3:" fclosure N (applySym2State f s) (f n)=
      s n"
    proof( simp add:fclosure_def applySym2State_def swapIdemponent) 
    qed
    with c1 show "fclosure M s n = fclosure N (applySym2State f s) (f n)"
      by simp      
  qed
qed
lemma fclosureSym:
assumes 
  a1:"M:netlists" and
  a3:"isSwap f" and
  a4:"sym f M N" and 
  a5:"N:netlists"
  
shows
  "(fclosure M s) = applySym2State f (fclosure N (applySym2State f s) )"
proof(rule ext ,unfold applySym2State_def, rule fclosureSym')
qed


lemma symFseq:
assumes  a1:"M :netlists" and a2:"τ0=  applySym2Seq f τ " 
  and a3:"isSwap f " and a4:"sym f M N" and
  a5:"N:netlists" 
shows "fSeq M τ=  applySym2Seq f (fSeq N τ0 ) "  
proof(rule ext)
  fix t 
  show "fSeq M τ t = applySym2Seq f (fSeq N τ0) t" (is "?P t")
  proof(induct  t)
    show "?P 0"
    proof(cut_tac a2,unfold applySym2Seq_def ,simp)
      show "fclosure M (τ 0) = applySym2State f (fclosure N (applySym2Seq f τ 0))"
      proof( unfold applySym2Seq_def , rule fclosureSym) qed
    qed
  next
    fix t0
    assume b1:"?P t0"
    show "?P (Suc t0)"
    proof(cut_tac a2,unfold applySym2Seq_def,simp add:Let_def)
      let ?sM=" (λx. if isDelayNames M x
          then let l = lookUp M x; inps = fanins l; v1 = lub (τ (Suc t0) x) (fSeq M τ t0 (hd inps)) in v1
          else τ (Suc t0) x)"
      let ?sN="(λx. if isDelayNames N x
            then let l = lookUp N x; inps = fanins l;
                     v1 = lub (applySym2Seq f τ (Suc t0) x) (fSeq N (applySym2Seq f τ) t0 (hd inps))
                 in v1
        else applySym2Seq f τ (Suc t0) x)"
      have "?sN =(applySym2State f ?sM)"
      proof(rule ext,unfold applySym2State_def)
        fix x
        let ?LHS="(if isDelayNames N x
         then let l = lookUp N x; inps = fanins l;
                  v1 = lub (applySym2Seq f τ (Suc t0) x) (fSeq N (applySym2Seq f τ) t0 (hd inps))
              in v1
         else applySym2Seq f τ (Suc t0) x)"
        let ?RHS="(if isDelayNames M (f x)
         then let l = lookUp M (f x); inps = fanins l;
                  v1 = lub (τ (Suc t0) (f x)) (fSeq M τ t0 (hd inps))
              in v1
         else τ (Suc t0) (f x))"
        have "isDelayNames N x | ~isDelayNames N x" by simp
        moreover
        {assume c1:"isDelayNames N x"
         have c2:"isDelayNames M (f x)" 
            by(rule symNetTolatch)
         have c3:"EX data l. l=Delay x data &l:N"  
           by(cut_tac c1,unfold isDelayNames_def,auto)
         have c4:"EX data l. l=Delay (f x) data &l:M" 
           by(cut_tac c2,unfold isDelayNames_def,auto)
         from c4 obtain dataM lM where c5:"lM=Delay (f x) dataM & lM:M" by blast
         from c3 obtain dataN lN where c6:"lN=Delay x dataN & lN:N" by blast
         from c5 a1 have c7:"lookUp M (f x) =Delay (f x) dataM " 
           apply(rule_tac lookUpIsTheDev)
           by auto
         from c5 have c5a:"isDefinedIn (f x) M" 
           apply (unfold isDefinedIn_def,auto)
           apply(rule_tac x="Delay (f x) dataM" in bexI)
           by auto
         from c6 a5 have c8:"lookUp N ( x) =Delay ( x) dataN " 
           apply(rule_tac lookUpIsTheDev)
           by auto
         have c9:" dataM=f dataN" 
           apply(cut_tac a4 c5a c7 c8,unfold sym_def)
           apply(erule conjE)+
           apply(drule_tac x="f x" in spec)
           apply auto
           apply(simp add:Let_def)
           apply(subgoal_tac " dataN = f dataM")
           prefer 2
           apply (subgoal_tac "f (f x)=x")
           apply simp
           apply(rule swapIdemponent)
           apply assumption
           apply simp
           by(rule sym,rule swapIdemponent)
         have c10:"?LHS =
                   lub (applySym2Seq f τ (Suc t0) x) (fSeq N (applySym2Seq f τ) t0 (dataN))
              " 
           apply(cut_tac c1 c8,simp add:Let_def) done
         have c11:"?RHS =
                   lub (τ (Suc t0) (f x)) (fSeq M τ t0 (f dataN))
              "
           apply(cut_tac c2 c7 c9,simp add:Let_def) done  
         have c12:"(applySym2Seq f τ (Suc t0) x) =(τ (Suc t0) (f x))"
           apply(unfold applySym2Seq_def)
           apply(unfold applySym2State_def)
           by simp

         have c13:"(fSeq N (applySym2Seq f τ) t0 (dataN))=
                 (fSeq M τ t0 (f dataN))"
         proof(rule sym)
            
            have  d1:"fSeq M τ t0 (f dataN)= applySym2Seq f (fSeq N (applySym2Seq f τ)) t0 (f dataN)"
               apply(cut_tac a2 b1)
               apply simp 
               done
            also have "…=(fSeq N (applySym2Seq f τ)) t0 (f (f dataN))"
              apply(unfold applySym2Seq_def)
              apply(unfold applySym2State_def)
              by simp
            also have "…=(fSeq N (applySym2Seq f τ) t0 (dataN))"
              apply(subgoal_tac "f (f dataN)=dataN")
              apply simp
              by(rule swapIdemponent)
            ultimately show " fSeq M τ t0 (f dataN) = fSeq N (applySym2Seq f τ) t0 dataN"
              by auto
          qed
          from c10 c11 have "?LHS =?RHS"  apply - apply auto
            apply(cut_tac c12)
            apply simp
            apply(cut_tac c13)
            apply simp
            done
          }
          moreover
          {assume c1:"~isDelayNames N x"
            have c2:"~isDelayNames M (f x)"
            proof(rule ccontr)
              assume d1:" ¬ ¬ isDelayNames M (f x)"
              have d2: "isDelayNames N (f (f x))" thm symNetTolatch2
              proof(cut_tac d1,simp, rule_tac m="f x" in symNetTolatch2 ) qed
              then have d3:"isDelayNames N ( x)"
                apply(subgoal_tac "f (f x)=x")
                apply(simp)
                apply(rule swapIdemponent)
                by assumption
              
              with c1 show False by simp
            qed
            
            have "?LHS =?RHS"
            proof(cut_tac c1 c2, simp,unfold  applySym2Seq_def applySym2State_def,simp)
            qed
          }
          ultimately show "?LHS =?RHS" by blast
        qed
     
         then show  "fclosure M ?sM=applySym2State f  (fclosure N ?sN)" thm rclosureSym
          proof(simp,  rule_tac fclosureSym) qed
    qed
  qed
qed
        
lemma symTraj:
assumes a1:" M: netlists" and a3:"isSwap f " and a4:"sym f M N" and
  a5:"N:netlists"
shows " defTrajOfCirc (applySym2Form f A) N = applySym2Seq f (defTrajOfCirc A M )"
proof(unfold defTrajOfCirc_def)
    have "defSqOfTrForm (applySym2Form f A)= applySym2Seq f (defSqOfTrForm A)"
    proof(rule defSqSym,auto)qed            
    then have "fSeq M (defSqOfTrForm A)=applySym2Seq f (fSeq N (defSqOfTrForm (applySym2Form f A)))"
      by(rule_tac symFseq)
    then have "applySym2Seq f (fSeq M (defSqOfTrForm A))=
      applySym2Seq f (applySym2Seq f (fSeq N (defSqOfTrForm (applySym2Form f A))))"
      by simp
    also have "…=fSeq N (defSqOfTrForm (applySym2Form f A))"
      by(rule swapSeq)
    ultimately show "fSeq N (defSqOfTrForm (applySym2Form f A)) =
      applySym2Seq f (fSeq M (defSqOfTrForm A))"
    proof(rule_tac sym,auto)qed
qed

lemma SqsubsetImpSwapSqsubset:
assumes a4:"sq1  \<sqsubseteq>sq sq2"
shows "applySym2Seq f sq1 \<sqsubseteq>sq applySym2Seq f sq2"
proof(cut_tac a4, unfold stateSqLeq_def stateLeq_def 
    applySym2Seq_def applySym2State_def,blast )
qed


lemma SwapSqsubsetImpSqsubset:
assumes a3:"isSwap f " and a4:"applySym2Seq f sq1 \<sqsubseteq>sq applySym2Seq f sq2"
shows "sq1  \<sqsubseteq>sq sq2"
proof(cut_tac a4, unfold stateSqLeq_def stateLeq_def 
    applySym2Seq_def applySym2State_def,(rule allI)+ )
  fix t n 
  assume b1:"∀t n. sq1 t (f n) \<sqsubseteq>  sq2 t (f n)"
   from b1  show "sq1 t n \<sqsubseteq>  sq2 t n"
  proof(drule_tac x="t" in spec,
      drule_tac x="f n" in spec,
      subgoal_tac "(f (f n) )=n",simp,
      rule_tac swapIdemponent)
  qed
qed  

lemma symReduction:
assumes a1:" M: netlists" and a3:"isSwap f " and a4:"sym f M N" and
  a5:"N:netlists" and a6:"isClosed M" and a7:"isClosed N"
shows "(cktSat M ( A \<leadsto> C))= (cktSat N ((applySym2Form f A) \<leadsto> (applySym2Form f C)))"(is "?A=?B")
proof
  assume b1:"?A"
  show "?B"
  proof(rule fundmental1)  
    show "defSqOfTrForm (applySym2Form f C) \<sqsubseteq>sq  defTrajOfCirc (applySym2Form f A) N"(is "?LHS \<sqsubseteq>sq?RHS")
    proof -
      have c1:" ?LHS=applySym2Seq f  (defSqOfTrForm C)"
        apply(rule   defSqSym)
        by auto
      have c2:"?RHS=applySym2Seq f  (defTrajOfCirc A M)"
        by(rule   symTraj)
      with c1 b1 show "?LHS \<sqsubseteq>sq?RHS"
      proof(simp,rule_tac SqsubsetImpSwapSqsubset,          rule_tac fundmental2)
      qed
    qed
  qed
next
  assume b1:"?B"
  show "?A"
  proof(rule fundmental1)  
    have c0:"defSqOfTrForm (applySym2Form f C) \<sqsubseteq>sq  defTrajOfCirc (applySym2Form f A) N"(is "?LHS \<sqsubseteq>sq?RHS")
    proof(rule fundmental2)qed
    have c1:" ?LHS=applySym2Seq f  (defSqOfTrForm C)"
      apply(rule   defSqSym)
      by auto
    have c2:"?RHS=applySym2Seq f  (defTrajOfCirc A M)"
      by(rule   symTraj)
    with c0 c1 c2 b1
    show " defSqOfTrForm C \<sqsubseteq>sq  defTrajOfCirc A M"
    proof(simp,rule_tac SwapSqsubsetImpSqsubset)
    qed
  qed
qed

lemma symReduction1:
assumes a1:" M: netlists" and a3:"isSwap f " and a4:"sym f M N" and
  a5:"N:netlists" and a6:"isClosed M" and a7:"isClosed N" and
  a6:"(cktSat M ( A \<leadsto> C))"
shows " (cktSat N ((applySym2Form f A) \<leadsto> (applySym2Form f C)))"
proof(cut_tac a1 a3 a4 a5 a6  symReduction,force)
qed
end

lemma swapIdemponent:

  isSwap f ==> f (f a) = a

lemma swapState:

  isSwap f ==> applySym2State f (applySym2State f s) = s

lemma swapSeq:

  isSwap f ==> applySym2Seq f (applySym2Seq f sq) = sq

lemma defSqSym:

B. B = applySym2Form f A -->
      isSwap f --> defSqOfTrForm B = applySym2Seq f (defSqOfTrForm A)

lemma symNetTolatch:

  [|isDelayNames N n; sym.sym f M N; M ∈ netlists; N ∈ netlists; isSwap f|]
  ==> isDelayNames M (f n)

lemma symNetTolatch2:

  [|isDelayNames M m; sym.sym f M N; M ∈ netlists; N ∈ netlists; isSwap f|]
  ==> isDelayNames N (f m)

lemma memMap:

  x mem map f inps --> (∃y. x = f yy mem inps)

lemma memMap:

  x mem map f inps ==> ∃y. x = f yy mem inps

lemma defSqSym:

  [|B = applySym2Form f A; isSwap f|]
  ==> defSqOfTrForm B = applySym2Seq f (defSqOfTrForm A)

lemma arith1:

  0 < x ==> ∃n. x = Suc n

lemma symListAux:

stateLs.
     length stateLs = length inps -->
     isSwap f -->
     pair0.0 mem zip (map f inps) stateLs -->
     (f (fst pair0.0), snd pair0.0) mem zip inps stateLs

lemma symListAux:

  [|length stateLs = length inps; isSwap f; pair0.0 mem zip (map f inps) stateLs|]
  ==> (f (fst pair0.0), snd pair0.0) mem zip inps stateLs

lemma rclosureSym:

  [|M ∈ netlists; pair ∈ rclosure M s; isSwap f; sym.sym f M N; N ∈ netlists|]
  ==> (f (fst pair), snd pair) ∈ rclosure N (applySym2State f s)

lemma fclosureSym:

  [|M ∈ netlists; isDefinedIn n M; isSwap f; sym.sym f M N; N ∈ netlists|]
  ==> fclosure M s n = fclosure N (applySym2State f s) (f n)

lemma fclosureSym':

  [|M ∈ netlists; isSwap f; sym.sym f M N; N ∈ netlists|]
  ==> fclosure M s n = fclosure N (applySym2State f s) (f n)

lemma fclosureSym:

  [|M ∈ netlists; isSwap f; sym.sym f M N; N ∈ netlists|]
  ==> fclosure M s = applySym2State f (fclosure N (applySym2State f s))

lemma symFseq:

  [|M ∈ netlists; τ0.0 = applySym2Seq f τ; isSwap f; sym.sym f M N; N ∈ netlists|]
  ==> fSeq M τ = applySym2Seq f (fSeq N τ0.0)

lemma symTraj:

  [|M ∈ netlists; isSwap f; sym.sym f M N; N ∈ netlists|]
  ==> defTrajOfCirc (applySym2Form f A) N = applySym2Seq f (defTrajOfCirc A M)

lemma SqsubsetImpSwapSqsubset:

  sq1.0 \<sqsubseteq>sq  sq2.0 ==>
  applySym2Seq f sq1.0 \<sqsubseteq>sq  applySym2Seq f sq2.0

lemma SwapSqsubsetImpSqsubset:

  [|isSwap f; applySym2Seq f sq1.0 \<sqsubseteq>sq  applySym2Seq f sq2.0|]
  ==> sq1.0 \<sqsubseteq>sq  sq2.0

lemma symReduction:

  [|M ∈ netlists; isSwap f; sym.sym f M N; N ∈ netlists; isClosed M; isClosed N|]
  ==> cktSat M (A \<leadsto> C) =
      cktSat N (applySym2Form f A \<leadsto> applySym2Form f C)

lemma symReduction1:

  [|M ∈ netlists; isSwap f; sym.sym f M N; N ∈ netlists; isClosed M; isClosed N;
   cktSat M (A \<leadsto> C)|]
  ==> cktSat N (applySym2Form f A \<leadsto> applySym2Form f C)