Set Bullet Behavior "Strict Subproofs".
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition tqueue := Tstruct _queue noattr.
Definition tqueue_t := Tstruct _queue_t noattr.
Definition MAX := 10.
(* Ghost histories in the style of History-based Verification of Functional Behaviour of Concurrent Programs, Blom, Huisman, and Zharieva-Stojanovski (VerCors) Twente tech report, 2015 *)
Inductive hist_el {A} := QAdd (p : val) (v : A) | QRem (p : val) (v : A).
Notation hist A := (list (@hist_el A)).
Fixpoint consistent {A} (h : hist A) a b :=
match h with
| [] => a = b
| QAdd p v :: h' => consistent h' (a ++ [(p, v)]) b
| QRem p v :: h' => match a with [] => False | v' :: q' => v' = (p, v) /\ consistent h' q' b end
end.
Notation feasible h := (exists b, consistent h [] b).
Parameter ghost : forall (sh : share) {t} (f : share * hist t) (p : val), mpred.
(*Parameter ghost_factory : mpred.  Axiom ghost_alloc : forall Espec D P Q R C P', semax(Espec := Espec) D (PROPx P (LOCALx Q (SEPx (ghost_factory :: R)))) C P' -> semax D (PROPx P (LOCALx Q (SEPx R))) C P'. Axiom new_ghost : forall Espec D P Q R C P' t v, semax(Espec := Espec) D (PROPx P (LOCALx Q (SEPx (ghost_factory :: (EX p : val, ghost Tsh t v p) :: R)))) C P' -> semax D (PROPx P (LOCALx Q (SEPx (ghost_factory :: R)))) C P'. Axiom alloc_conflict : ghost_factory * ghost_factory |-- FF.*)
(* In effect, we want two different ways of splitting/combining history shares. One combines the histories as well; the other guarantees injectivity on histories. *)
Inductive list_incl {A} : list A -> list A -> Prop :=
| incl_nil l : list_incl [] l
| incl_skip l1 a l2 (Hincl : list_incl l1 l2) : list_incl l1 (a :: l2)
| incl_cons a l1 l2 (Hincl : list_incl l1 l2) : list_incl (a :: l1) (a :: l2).
Hint Constructors list_incl.
Inductive interleave {A} : list (list A) -> list A -> Prop :=
| interleave_nil ls (Hnil : Forall (fun l => l = []) ls) : interleave ls []
| interleave_cons ls i a l l' (Hcons : Znth i ls [] = a :: l) (Hrest : interleave (upd_Znth i ls l) l') :
interleave ls (a :: l').

Axiom hist_share_join : forall sh sh1 sh2 sh' t (h1 h2 : hist t) p, sepalg.join sh1 sh2 sh' ->
ghost sh (sh1, h1) p * ghost sh (sh2, h2) p = EX h' : hist t, !!(interleave [h1; h2] h') && ghost sh (sh', h') p.