Instance list_Perm {P : Ghost} : Perm_alg (list (option G)).

(* Specifications: *)
(* up *)
Lemma nth_upto : forall m n d, (n < m)%nat -> nth n (upto m) d = Z.of_nat n.
Lemma nth_repeat : forall {A} n m (a : A), nth n (repeat a m) a = a.
Lemma list_incl_singleton : forall {A} n (a : A) l,
list_incl (list_singleton n a) l <-> nth n l None = Some a.
Lemma wsat_alloc : forall P, wsat * |> P |-- |==> wsat * EX i : _, invariant i P.
Lemma wsat_open : forall i P,
wsat * invariant i P * ghost_set g_en (Singleton i) |--
|==> wsat * |> P * ghost_list g_dis (list_singleton i (Some tt)).
(* up *)
Lemma replace_nth_same' : forall {A} n l (a d : A), nth n l d = a -> replace_nth n l a = l.
Lemma wsat_close : forall i P,
wsat * invariant i P * |> P * ghost_list g_dis (list_singleton i (Some tt)) |--
|==> wsat * ghost_set g_en (Singleton i).
Lemma invariant_dealloc : forall i P, invariant i P |-- |==> emp.
Lemma invariant_super_non_expansive : forall n N P,
approx n (invariant N P) = approx n (invariant N (approx n P)).
Lemma invariant_cored : forall i P, invariant i P |-- cored.
(* Consider putting rules for invariants and fancy updates in msl (a la ghost_seplog), and proofs in veric (a la own). *)
Lemma Setminus_self : forall {A} s, Setminus s s = Empty_set A.
Lemma Included_self : forall {A} s, @Included A s s.
Lemma ghost_set_empty : forall {A} g (s : Ensemble A),
ghost_set g s = ghost_set g s * ghost_set g (Empty_set A).
Lemma wsat_empty_eq : wsat = wsat * ghost_set g_en (Empty_set iname).
End Invariants.
Lemma make_wsat : emp |-- |==> EX inv_names : invG, wsat.