Theory Wellformed

(*<*)
theory Wellformed
  imports  IVSubst BTVSubst
begin
  (*>*)

chapter ‹Wellformed Terms›

text ‹We require that expressions and values are well-formed. This includes a notion
of well-sortedness. We identify a sort with a basic type and
define the judgement as two clusters of mutually recursive
inductive predicates. Some of the proofs are across all of the predicates and
although they seemed at first to be daunting, they have all
worked out well.›

named_theorems ms_wb "Facts for helping with well-sortedness"

section ‹Definitions›

inductive wfV :: "Θ    Γ  v  b  bool" (" _ ; _ ; _ wf _ : _ " [50,50,50] 50)  and
  wfC :: "Θ    Γ  c  bool" (" _ ; _ ; _   wf _ " [50,50] 50)  and         
  wfG :: "Θ    Γ  bool" (" _ ; _  wf _ " [50,50] 50) and
  wfT :: "Θ    Γ  τ  bool" (" _ ; _ ; _   wf _ " [50,50] 50)  and
  wfTs :: "Θ    Γ  (string*τ) list  bool" (" _ ; _  ; _ wf _ " [50,50] 50)  and 
  wfTh :: "Θ  bool" ("   wf _ " [50] 50)  and
  wfB :: "Θ    b  bool" (" _ ; _  wf _ " [50,50] 50) and
  wfCE :: "Θ    Γ  ce  b  bool" ("  _ ; _ ; _ wf _ : _ " [50,50,50] 50) and
  wfTD :: "Θ  type_def  bool" (" _ wf _ " [50,50] 50)          
  where

wfB_intI:  "wf Θ  Θ;  wf B_int" 
| wfB_boolI:  "wf Θ  Θ;  wf B_bool" 
| wfB_unitI:  "wf Θ  Θ;  wf B_unit" 
| wfB_bitvecI:  "wf Θ  Θ;  wf B_bitvec" 
| wfB_pairI:  " Θ;  wf b1 ; Θ;  wf b2   Θ;  wf B_pair b1 b2" 

| wfB_consI:  "
   wf Θ; 
   (AF_typedef s dclist)  set Θ 
  
   Θ;  wf B_id s"

| wfB_appI:  " 
   wf Θ; 
   Θ;  wf b;
   (AF_typedef_poly s bv dclist)  set Θ 
  
   Θ;  wf B_app s b"

| wfV_varI: " Θ;  wf Γ ; Some (b,c) = lookup Γ x   Θ; ; Γ wf V_var x : b"
| wfV_litI: "Θ;  wf Γ   Θ; ; Γ wf V_lit l : base_for_lit l"

| wfV_pairI: "
   Θ; ; Γ wf v1 : b1 ; 
   Θ; ; Γ wf v2 : b2 
  
   Θ; ; Γ wf (V_pair v1 v2) : B_pair b1 b2"

| wfV_consI: "   
   AF_typedef s dclist  set Θ;
   (dc,  x : b'  | c )  set dclist ;
   Θ; ; Γ wf v : b' 
  
   Θ; ; Γ wf V_cons s dc v : B_id s"

| wfV_conspI: "   
    AF_typedef_poly s bv dclist  set Θ;
    (dc,  x : b'  | c )  set dclist ;
    Θ ;    wf b;
    atom bv  (Θ, , Γ, b , v);
    Θ; ; Γ wf v : b'[bv::=b]bb 
 
    Θ; ; Γ wf V_consp s dc b v : B_app s b"

| wfCE_valI : "             
    Θ; ; Γ wf v  : b 
  
    Θ; ; Γ  wf CE_val v  : b"

| wfCE_plusI: "               
    Θ; ; Γ wf v1 : B_int; 
    Θ; ; Γ wf v2 : B_int 
  
    Θ; ; Γ  wf CE_op Plus v1 v2 : B_int"

| wfCE_leqI:"
    Θ; ; Γ wf v1 : B_int; 
    Θ; ; Γ wf v2 : B_int 
 
    Θ; ; Γ wf CE_op LEq v1 v2 : B_bool"

| wfCE_eqI:"
    Θ; ; Γ wf v1 : b; 
    Θ; ; Γ wf v2 : b 
 
    Θ; ; Γ wf CE_op Eq v1 v2 : B_bool"

| wfCE_fstI: "               
    Θ; ; Γ wf v1 : B_pair b1 b2  
  
    Θ; ; Γ  wf CE_fst v1 : b1"

| wfCE_sndI: "             
    Θ; ; Γ wf v1 : B_pair b1 b2  
   
    Θ; ; Γ  wf CE_snd v1 : b2"

| wfCE_concatI: " 
    Θ; ; Γ wf v1 : B_bitvec ; 
    Θ; ; Γ wf v2 : B_bitvec 
  
    Θ; ; Γ  wf CE_concat v1 v2 : B_bitvec"

| wfCE_lenI: "                
    Θ; ; Γ wf v1 : B_bitvec 
  
    Θ; ; Γ  wf CE_len v1 : B_int"

| wfTI : " 
    atom z   (Θ, , Γ) ; 
    Θ;  wf b;
    Θ;  ; (z,b,C_true) #Γ Γ wf c 
  
    Θ; ; Γ wf  z : b | c "

| wfC_eqI: "  
                Θ; ; Γ  wf e1  : b ; 
                 Θ; ; Γ  wf e2  : b    
                Θ; ; Γ wf C_eq e1 e2" 
| wfC_trueI: " Θ;  wf Γ   Θ; ; Γ  wf C_true "
| wfC_falseI: " Θ;  wf Γ   Θ; ; Γ wf C_false "

| wfC_conjI: " Θ; ; Γ wf c1 ; Θ; ; Γ wf c2   Θ; ; Γ wf C_conj c1 c2"
| wfC_disjI: " Θ; ; Γ wf c1 ; Θ; ; Γ wf c2   Θ; ; Γ wf C_disj c1 c2"
| wfC_notI: "  Θ; ; Γ wf c1    Θ; ; Γ wf C_not c1"
| wfC_impI: "  Θ; ; Γ wf c1 ; 
                Θ; ; Γ  wf c2   Θ; ; Γ wf C_imp c1 c2"

| wfG_nilI: " wf Θ   Θ;  wf GNil"
| wfG_cons1I: "  c  { TRUE, FALSE } ; 
                  Θ;   wf Γ ; 
                  atom x  Γ ; 
                  Θ  ;  ; (x,b,C_true)#ΓΓ wf c ; wfB Θ  b  
                  Θ;   wf ((x,b,c)#ΓΓ)"
| wfG_cons2I: "  c  { TRUE, FALSE } ; 
                  Θ;   wf Γ ; 
                  atom x  Γ ;  
                  wfB Θ  b   
                   Θ;  wf ((x,b,c)#ΓΓ)"

| wfTh_emptyI: " wf []"

| wfTh_consI: "      
        (name_of_type tdef)  name_of_type ` set Θ ;
        wf Θ ; 
       Θ wf  tdef     wf tdef#Θ"

| wfTD_simpleI: "
        Θ ; {||} ; GNil wf lst
        
        Θ wf (AF_typedef s lst )"

| wfTD_poly: " 
        Θ ; {|bv|} ; GNil wf lst 
        
      Θ wf (AF_typedef_poly s bv lst)"

| wfTs_nil: "Θ;  wf Γ  Θ; ; Γ wf []::(string*τ) list"
| wfTs_cons: " Θ; ; Γ wf τ ; 
                dc  fst ` set ts;
                Θ; ; Γ wf ts::(string*τ) list   Θ; ; Γ wf ((dc,τ)#ts)"

inductive_cases wfC_elims:
  "Θ; ; Γ wf C_true"
  "Θ; ; Γ wf C_false"
  "Θ; ; Γ wf C_eq e1 e2"
  "Θ; ; Γ wf C_conj c1 c2"
  "Θ; ; Γ wf C_disj c1 c2"
  "Θ; ; Γ wf C_not c1"
  "Θ; ; Γ wf C_imp c1 c2"

inductive_cases wfV_elims:
  "Θ; ; Γ wf V_var x : b"
  "Θ; ; Γ wf V_lit l : b"
  "Θ; ; Γ wf V_pair v1 v2 : b"
  "Θ; ; Γ wf V_cons tyid dc v : b"
  "Θ; ; Γ wf V_consp tyid dc b v : b'"

inductive_cases wfCE_elims:
  " Θ; ; Γ wf CE_val v : b"
  " Θ; ; Γ wf CE_op Plus v1 v2 : b"
  " Θ; ; Γ wf CE_op LEq v1 v2 : b"
  " Θ; ; Γ wf CE_fst v1 : b"
  " Θ; ; Γ wf CE_snd v1 : b"
  " Θ; ; Γ wf CE_concat v1 v2 : b"
  " Θ; ; Γ wf CE_len v1 : b"
  " Θ; ; Γ wf CE_op opp v1 v2 : b"
  " Θ; ; Γ wf CE_op Eq v1 v2 : b"

inductive_cases wfT_elims:
  "Θ;  ; Γ wf τ::τ"
  "Θ;  ; Γ wf  z : b | c "

inductive_cases wfG_elims:
  "Θ;  wf GNil"
  "Θ;  wf (x,b,c)#ΓΓ"
  "Θ;  wf (x,b,TRUE)#ΓΓ"
  "Θ;  wf (x,b,FALSE)#ΓΓ"

inductive_cases wfTh_elims:
  " wf []"
  " wf td#Π"  

inductive_cases wfTD_elims:
  "Θ wf (AF_typedef s lst )"  
  "Θ wf (AF_typedef_poly s bv lst )" 

inductive_cases wfTs_elims:
  "Θ;  ; GNil wf ([]::((string*τ) list))"
  "Θ;  ; GNil wf ((t#ts)::((string*τ) list))"

inductive_cases wfB_elims:
  " Θ;  wf B_pair b1 b2" 
  " Θ;  wf B_id s"
  " Θ;  wf B_app s b"

equivariance wfV 

text ‹This setup of 'avoiding' is not complete and for some of lemmas, such as weakening,
do it the hard way›
nominal_inductive wfV 
  avoids   wfV_conspI: bv | wfTI: z
proof(goal_cases)
  case (1 s bv dclist Θ dc x b' c  b Γ v)

  moreover hence "atom bv   V_consp s dc b v" using v.fresh fresh_prodN pure_fresh by metis
  moreover have "atom bv  B_app s b" using b.fresh fresh_prodN pure_fresh 1 by metis
  ultimately show ?case using b.fresh v.fresh pure_fresh  fresh_star_def fresh_prodN by fastforce
next
  case (2 s bv dclist Θ dc x b' c  b Γ v)
  then show ?case by auto
next
  case (3 z Γ Θ  b c)
  then show ?case using τ.fresh fresh_star_def fresh_prodN by fastforce
next
  case (4 z Γ Θ  b c)
  then show ?case by auto
qed

inductive 
  wfE :: "Θ  Φ    Γ  Δ  e  b  bool" (" _ ; _ ; _ ; _ ; _ wf _ : _ " [50,50,50] 50)  and
  wfS :: "Θ  Φ    Γ  Δ  s  b  bool" (" _ ; _ ; _ ; _ ; _ wf _ : _ " [50,50,50] 50)  and
  wfCS :: "Θ  Φ    Γ  Δ   tyid  string  τ  branch_s  b  bool" (" _ ; _ ; _ ; _ ; _ ; _ ; _ ; _ wf _ : _ " [50,50,50,50,50] 50)  and
  wfCSS :: "Θ  Φ    Γ  Δ   tyid  (string * τ) list  branch_list  b  bool" (" _ ; _ ; _ ; _ ; _ ; _ ; _ wf _ : _ " [50,50,50,50,50] 50)  and       
  wfPhi :: "Θ  Φ  bool" (" _  wf _ " [50,50] 50)  and
  wfD :: "Θ    Γ  Δ  bool" (" _ ; _ ; _ wf _ " [50,50] 50) and       
  wfFTQ :: "Θ  Φ  fun_typ_q  bool"  (" _  ; _ wf _ " [50] 50) and
  wfFT :: "Θ  Φ    fun_typ  bool"  (" _ ; _ ; _ wf _ " [50] 50)  where

wfE_valI : "
   Θ wf Φ; 
   Θ; ; Γ wf Δ;
   Θ; ; Γ wf v  : b 
  
    Θ; Φ; ; Γ; Δ  wf AE_val v  : b"

| wfE_plusI: " 
   Θ wf Φ; 
   Θ; ; Γ wf Δ;
   Θ; ; Γ wf v1 : B_int; 
   Θ; ; Γ wf v2 : B_int 
  
   Θ; Φ; ; Γ; Δ  wf AE_op Plus v1 v2 : B_int"

| wfE_leqI:"   
   Θ wf Φ ;
   Θ; ; Γ wf Δ; 
   Θ; ; Γ wf v1 : B_int; 
   Θ; ; Γ wf v2 : B_int
  
   Θ; Φ; ; Γ; Δ  wf AE_op LEq v1 v2 : B_bool"

| wfE_eqI:"   
   Θ wf Φ ;
   Θ; ; Γ wf Δ; 
   Θ; ; Γ wf v1 : b; 
   Θ; ; Γ wf v2 : b;
   b  { B_bool, B_int, B_unit }
  
   Θ; Φ; ; Γ; Δ  wf AE_op Eq v1 v2 : B_bool"

| wfE_fstI: "  
   Θ wf Φ; 
   Θ; ; Γ wf Δ; 
   Θ; ; Γ wf v1 : B_pair b1 b2 
   
   Θ; Φ; ; Γ; Δ wf AE_fst v1 : b1"

| wfE_sndI: "  
   Θ wf Φ ; 
   Θ; ; Γ wf Δ;
   Θ; ; Γ wf v1 : B_pair b1 b2  
   
   Θ; Φ; ; Γ; Δ wf AE_snd v1 : b2"

| wfE_concatI: "
   Θ wf Φ ;
   Θ; ; Γ wf Δ; 
   Θ; ; Γ wf v1 : B_bitvec; 
   Θ; ; Γ wf v2 : B_bitvec 
  
   Θ ; Φ ;  ; Γ; Δ  wf AE_concat v1 v2 : B_bitvec"

| wfE_splitI: "
   Θ wf Φ ;
   Θ; ; Γ wf Δ; 
   Θ; ; Γ wf v1 : B_bitvec; 
   Θ; ; Γ wf v2 : B_int 
  
   Θ ; Φ ;  ; Γ; Δ  wf AE_split v1 v2 : B_pair B_bitvec B_bitvec"

| wfE_lenI: "
   Θ wf Φ ; 
   Θ; ; Γ wf Δ; 
   Θ; ; Γ wf v1 : B_bitvec 
  
   Θ; Φ; ; Γ; Δ  wf AE_len v1 : B_int"

| wfE_appI:  "
   Θ wf Φ ; 
   Θ; ; Γ wf Δ; 
   Some (AF_fundef f (AF_fun_typ_none (AF_fun_typ x b c τ s))) = lookup_fun Φ f ;  
   Θ; ; Γ wf v : b
    
   Θ; Φ; ; Γ; Δ wf AE_app f v : b_of τ"

| wfE_appPI:  "
    Θ wf Φ ; 
    Θ; ; Γ wf Δ; 
    Θ;   wf b'; 
    atom bv   (Φ, Θ, , Γ, Δ, b', v, (b_of τ)[bv::=b']b);
    Some (AF_fundef f (AF_fun_typ_some bv (AF_fun_typ x b c τ s))) = lookup_fun Φ f;  
    Θ; ; Γ wf v : (b[bv::=b']b)
    
    Θ; Φ; ; Γ; Δ wf (AE_appP f b' v) : ((b_of τ)[bv::=b']b)"

| wfE_mvarI: "  
   Θ wf Φ ; 
   Θ; ; Γ wf Δ; 
   (u,τ)  setD Δ 
  
   Θ; Φ; ; Γ; Δ wf AE_mvar u : b_of τ" 

| wfS_valI: " 
    Θ wf Φ ;  
    Θ; ; Γ wf v : b ; 
    Θ; ; Γ wf Δ 
   
    Θ; Φ; ; Γ; Δ wf (AS_val v) : b"

| wfS_letI: " 
    wfE Θ Φ  Γ Δ  e b'  ;
    Θ ; Φ ;  ; (x,b',C_true) #Γ Γ ; Δ wf s : b;
    Θ; ; Γ wf Δ ;
    atom x  (Φ, Θ, , Γ, Δ, e, b)
  
    Θ; Φ; ; Γ; Δ wf LET x = e IN s : b"

| wfS_assertI: " 
    Θ ; Φ ;  ; (x,B_bool,c) #Γ Γ ; Δ wf s : b;
    Θ; ; Γ wf c ;
    Θ; ; Γ wf Δ ;
    atom x  (Φ, Θ, , Γ, Δ, c, b, s)
  
    Θ; Φ; ; Γ; Δ wf ASSERT c IN  s : b"

| wfS_let2I: " 
   Θ; Φ; ; Γ; Δ  wf s1 : b_of τ  ; 
   Θ; ; Γ wf τ;
   Θ ; Φ ;  ; (x,b_of τ,C_true) #Γ Γ ; Δ wf s2 : b ;
   atom x  (Φ, Θ, , Γ, Δ, s1, b,τ)            
  
   Θ; Φ; ; Γ; Δ wf LET x : τ = s1 IN s2 : b"

| wfS_ifI: "  
   Θ; ; Γ wf v  : B_bool; 
   Θ; Φ; ; Γ; Δ wf s1 : b ; 
   Θ; Φ; ; Γ; Δ wf s2 : b 
 
   Θ; Φ; ; Γ; Δ wf IF v THEN s1 ELSE s2 : b"

| wfS_varI : " 
   wfT Θ  Γ  τ ;  
   Θ; ; Γ wf v  : b_of τ; 
   atom u  (Φ, Θ, , Γ, Δ, τ, v, b);
   Θ ; Φ ;  ; Γ ;  (u,τ)#ΔΔ wf s : b 
  
   Θ; Φ; ; Γ; Δ wf VAR u : τ = v IN s : b "

| wfS_assignI: " 
   (u,τ)  setD Δ ;   
   Θ; ; Γ wf Δ ;  
   Θ wf Φ ;
   Θ; ; Γ wf v  : b_of τ 
 
   Θ; Φ; ; Γ; Δ wf u ::= v : B_unit"

| wfS_whileI: " 
  Θ; Φ; ; Γ; Δ wf s1 : B_bool ; 
  Θ; Φ; ; Γ; Δ wf s2 : b
   
  Θ; Φ; ; Γ; Δ wf WHILE s1 DO { s2 } : b"

| wfS_seqI: "
  Θ; Φ; ; Γ; Δ wf s1 : B_unit ; 
  Θ; Φ; ; Γ; Δ wf s2 : b 
  
  Θ; Φ; ; Γ; Δ wf s1 ;; s2 : b"

| wfS_matchI: " 
  wfV Θ   Γ  v  (B_id tid) ;
  (AF_typedef tid dclist )  set Θ;
  wfD Θ   Γ  Δ ;  
  Θ wf Φ ;
  Θ ; Φ ;  ; Γ ;  Δ ; tid ; dclist wf cs : b 
  
  Θ; Φ; ; Γ; Δ wf AS_match v cs : b "

| wfS_branchI: " 
  Θ ; Φ ;  ; (x,b_of τ,C_true) #Γ Γ ;  Δ wf s : b ;
  atom x  (Φ, Θ, , Γ, Δ, Γ,τ);
  Θ; ; Γ wf Δ 
   
  Θ ; Φ ;  ; Γ ;  Δ ; tid ; dc ;  τ  wf  dc x  s : b"

| wfS_finalI: "       
  Θ; Φ; ; Γ; Δ ; tid ; dc ; t  wf cs : b    
    
  Θ ; Φ ;  ; Γ ;  Δ ; tid ; [(dc,t)] wf AS_final cs  : b "

| wfS_cons: "           
  Θ; Φ; ; Γ; Δ ; tid ; dc ; t  wf cs : b;
  Θ; Φ; ; Γ; Δ ; tid ; dclist wf css : b
    
  Θ ; Φ ;  ; Γ ;  Δ ; tid ; (dc,t)#dclist wf AS_cons cs css : b "

| wfD_emptyI: "Θ;  wf Γ  Θ  ;  ; Γ  wf []Δ"

| wfD_cons: " 
  Θ  ;  ; Γ  wf Δ::Δ ; 
  Θ  ;  ; Γ wf τ; 
  u  fst ` setD Δ 
  
  Θ; ; Γ wf ((u,τ) #Δ Δ)"

| wfPhi_emptyI: " wf Θ  Θ wf []"

| wfPhi_consI: " 
  f  name_of_fun ` set Φ; 
  Θ ; Φ  wf ft;
  Θ wf Φ
   
  Θ  wf ((AF_fundef f ft)#Φ)"  

| wfFTNone: " Θ ; Φ ; {||} wf ft   Θ ; Φ wf AF_fun_typ_none ft"
| wfFTSome: " Θ ; Φ ; {| bv |} wf ft   Θ ; Φ wf AF_fun_typ_some bv ft"

| wfFTI: "
  Θ ; B  wf b; 
  supp s  {atom x}  supp B ;
  supp c  { atom x } ;
  Θ ; B ; (x,b,c) #Γ GNil wf τ;
  Θ wf Φ        
  
  Θ ; Φ ; B wf (AF_fun_typ x b c τ s)"

inductive_cases wfE_elims:
  "Θ; Φ; ; Γ; Δ wf AE_val v : b"
  "Θ; Φ; ; Γ; Δ wf AE_op Plus v1 v2 : b"
  "Θ; Φ; ; Γ; Δ wf AE_op LEq v1 v2 : b"
  "Θ; Φ; ; Γ; Δ wf AE_fst v1 : b"
  "Θ; Φ; ; Γ; Δ wf AE_snd v1 : b"
  "Θ; Φ; ; Γ; Δ wf AE_concat v1 v2 : b"
  "Θ; Φ; ; Γ; Δ wf AE_len v1 : b"
  "Θ; Φ; ; Γ; Δ wf AE_op opp v1 v2 : b"
  "Θ; Φ; ; Γ; Δ wf AE_app f v: b"
  "Θ; Φ; ; Γ; Δ wf AE_appP f b' v: b"
  "Θ; Φ; ; Γ; Δ wf AE_mvar u : b"
  "Θ; Φ; ; Γ; Δ wf AE_op Eq v1 v2 : b"

inductive_cases wfCS_elims:
  "Θ; Φ; ; Γ; Δ ; tid ; dc ; t wf (cs::branch_s) : b"
  "Θ; Φ; ; Γ; Δ ; tid ; dc  wf (cs::branch_list) : b"

inductive_cases wfPhi_elims:
  " Θ  wf []"
  " Θ  wf ((AF_fundef f ft)#Π)"  
  " Θ  wf (fd#Φ::Φ)"  

declare[[ simproc del: alpha_lst]]

inductive_cases wfFTQ_elims:
  "Θ ; Φ  wf AF_fun_typ_none ft"
  "Θ ; Φ  wf AF_fun_typ_some bv ft"
  "Θ ; Φ  wf AF_fun_typ_some bv (AF_fun_typ x b c τ s)"

inductive_cases wfFT_elims:
  "Θ ; Φ ;   wf AF_fun_typ x b c τ s"

declare[[ simproc add: alpha_lst]]

inductive_cases wfD_elims:
  "Π ;  ; (Γ::Γ) wf []Δ"
  "Π ;  ; (Γ::Γ) wf (u,τ) #Δ Δ::Δ"

equivariance wfE 

nominal_inductive wfE 
  avoids   wfE_appPI: bv |  wfS_varI: u |  wfS_letI: x | wfS_let2I: x  | wfS_branchI: x | wfS_assertI: x

proof(goal_cases)
  case (1 Θ Φ  Γ Δ b' bv v τ f x b c s)
  moreover hence "atom bv   AE_appP f b' v" using pure_fresh fresh_prodN e.fresh  by auto
  ultimately show ?case using fresh_star_def by fastforce
next
  case (2 Θ Φ  Γ Δ b' bv v τ f x b c s)
  then show ?case by auto
next
  case (3 Φ Θ  Γ Δ e b' x s b)
  moreover hence "atom x  LET x = e IN s" using  fresh_prodN by auto
  ultimately show ?case using fresh_prodN fresh_star_def by fastforce 
next
  case (4 Φ Θ  Γ Δ e b' x s b)
  then show ?case by auto
next
  case (5 Θ Φ  x c Γ Δ s b)
  hence "atom x  ASSERT c IN s" using  s_branch_s_branch_list.fresh by auto
  then show ?case using fresh_prodN fresh_star_def 5 by fastforce 
next
  case (6 Θ Φ  x c Γ Δ s b)
  then show ?case by auto
next
  case (7 Φ Θ  Γ Δ s1 τ x s2 b)
  hence "atom x  τ  atom x  s1" using fresh_prodN by metis
  moreover hence "atom x  LET x : τ = s1 IN s2" 
    using  s_branch_s_branch_list.fresh(3)[of "atom x" x "τ" s1 s2 ] fresh_prodN by simp
  ultimately show ?case using fresh_prodN fresh_star_def 7 by fastforce 
next
  case (8 Φ Θ  Γ Δ s1 τ x s2 b)
  then show ?case by auto
next
  case (9 Θ  Γ τ v u Φ Δ b s)
  moreover hence " atom u  AS_var u τ v s" using fresh_prodN s_branch_s_branch_list.fresh by simp
  ultimately show ?case using fresh_star_def fresh_prodN s_branch_s_branch_list.fresh by fastforce
next
  case (10 Θ  Γ τ v u Φ Δ b s)
  then show ?case by auto
next
  case (11 Φ Θ  x τ Γ Δ s b tid dc)
  moreover have "atom x  (dc x  s)" using pure_fresh  s_branch_s_branch_list.fresh by auto
  ultimately show ?case using fresh_prodN fresh_star_def pure_fresh by fastforce 
next
  case (12 Φ Θ  x τ Γ Δ s b tid dc)
  then show ?case by auto
qed

inductive  wfVDs :: "var_def list  bool" where

wfVDs_nilI: "wfVDs []"

| wfVDs_consI: "
   atom u  ts;
   wfV ([]::Θ) {||}  GNil  v  (b_of τ);
   wfT ([]::Θ)  {||}  GNil  τ;
   wfVDs ts
  wfVDs  ((AV_def u τ v)#ts)"

equivariance wfVDs 
nominal_inductive wfVDs .  

end