(*
Unidirectional dynamic transistor models
*)

(*
loadPath := "/homes/mjcg/Lectures/OGI/hol/words" :: !loadPath;

load "bossLib";
load "seqtranTheory";
load "seqtran";
*)

open Globals HolKernel Parse basicHol90Lib goalstackLib;
infixr 3 -->;
infix 9 by;
infix ++;
infix ## |-> THEN THENL THENC ORELSE ORELSEC THEN_TCL ORELSE_TCL;

open bossLib;
open pairTheory;
open seqtranTheory;
open seqtran;

val _ = new_theory "ShiftReg";

(* 2-phase shift register *)

val ShiftReg_def =
 Define
  `ShiftReg(i,out,ph1,ph2) =
     ?l1 l2 l3 l4 l5 l6 l7 l8 l9 l10 l11 l12 l13.
      Nswitch(ph1,i,l1) /\ Cap(l1,l2) /\
      Pwr l3 /\ Pswitch(l2,l3,l4) /\ Nswitch(l2,l6,l5) /\ Gnd l6 /\
      Join(l4,l5,l7) /\ Nswitch(ph2,l7,l8) /\ Cap(l8,l9) /\
      Pwr l10 /\ Pswitch(l9,l10,l11) /\ Nswitch(l9,l13,l12) /\ Gnd l13 /\
      Join(l11,l12,out)`;

(* runtime: 347.350s,    gctime: 17.670s,     systime: 0.130s. *)
val ShiftRegCorrectPh1 =
 store_thm
  ("ShiftRegCorrectPh1",
   ``ShiftReg(i,out,ph1,ph2) /\ Strong(i t) /\ 
     (ph1 t    = Hi) /\ (ph2 t    = Lo) /\
     (ph1(t+1) = Lo) /\ (ph2(t+1) = Hi) 
     ==> (out(t+1) = i t)``,
   RW_TAC arith_ss [ShiftReg_def,U_def,Join_def,
                    Pwr_def,Gnd_def,Nswitch_def,Pswitch_def,CapThm,
                    Strong_def,Float_def,ValDistinct]
    THEN ASM_REWRITE_TAC[ValDistinct]);

(* runtime: 817.910s,    gctime: 39.400s,     systime: 0.270s. *)
val ShiftRegCorrectPh2 =
 store_thm
  ("ShiftRegCorrectPh2",
   ``ShiftReg(i,out,ph1,ph2) /\ Strong(i t)
     /\ (ph1 t    = Hi) /\ (ph2 t    = Lo)
     /\ (ph1(t+1) = Lo) /\ (ph2(t+1) = Hi)
     /\ (ph1(t+2) = Hi) /\ (ph2(t+2) = Lo)
     ==> (out(t+2) = i t)``,
   RW_TAC std_ss [ShiftReg_def,U_def,Join_def,
                  Pwr_def,Gnd_def,Nswitch_def,Pswitch_def,CapThm,
                  Strong_def,Float_def,ValDistinct,DECIDE`t+2 = (t+1)+1`]
    THEN ASM_REWRITE_TAC[ValDistinct]);

(* runtime: 2.330s,    gctime: 0.090s,     systime: 0.010s. *)
val ShiftRegCorrectPh1_SIM =
 store_thm
  ("ShiftRegCorrectPh1_SIM",
   ``ShiftReg(i,out,ph1,ph2) /\ Strong(i t) /\ 
     (ph1 t    = Hi) /\ (ph2 t    = Lo) /\
     (ph1(t+1) = Lo) /\ (ph2(t+1) = Hi) 
     ==> (out(t+1) = i t)``,
   RW_TAC arith_ss [ShiftReg_def,Strong_def,Pwr_def,Gnd_def]
    THEN ASSUM_LIST(fn thl => MAP_EVERY ASSUME_TAC (mapfilter (Q.SPEC `t`) thl))
    THEN ASSUM_LIST(fn thl => MAP_EVERY ASSUME_TAC (mapfilter (Q.SPEC `t+1`) thl))
    THEN IMP_SIM_TAC
    THEN ASM_REWRITE_TAC[]);

(* runtime: 3.200s,    gctime: 0.150s,     systime: 0.010s. *)
val ShiftRegCorrectPh2_SIM =
 store_thm
  ("ShiftRegCorrectPh2_SIM",
   ``ShiftReg(i,out,ph1,ph2) /\ Strong(i t)
     /\ (ph1 t    = Hi) /\ (ph2 t    = Lo)
     /\ (ph1(t+1) = Lo) /\ (ph2(t+1) = Hi)
     /\ (ph1(t+2) = Hi) /\ (ph2(t+2) = Lo)
     ==> (out(t+2) = i t)``,
   RW_TAC std_ss [ShiftReg_def,Strong_def,Pwr_def,Gnd_def,DECIDE`t+2 = (t+1)+1`]
    THEN ASSUM_LIST(fn thl => MAP_EVERY ASSUME_TAC (mapfilter (Q.SPEC `t`) thl))
    THEN ASSUM_LIST(fn thl => MAP_EVERY ASSUME_TAC (mapfilter (Q.SPEC `t+1`) thl))
    THEN ASSUM_LIST(fn thl => MAP_EVERY ASSUME_TAC (mapfilter (Q.SPEC `t+1+1`) thl))
    THEN IMP_SIM_TAC
    THEN ASM_REWRITE_TAC[]);

val _ = export_theory();


