Class Action: Type := {
  action: Type;
  trace := list action;
  traces := trace -> Prop
}.Class Action: Type := {
  action: Type;
  trace := list action;
  traces := trace -> Prop
}.Class Action: Type := {
  action: Type;
  trace := list action;
  traces := trace -> Prop
}.Class Action: Type := {
  action: Type;
  trace := list action;
  traces := trace -> Prop
}.Definition singleton_trace {Ac: Action} (a: action): trace := cons a nil.Definition singleton_traces {Ac: Action} (tr: trace): traces := eq tr.Definition trace_app {Ac: Action}: trace -> trace -> trace := @app _.Inductive traces_app {Ac: Action}: traces -> traces -> traces :=
  traces_app_intro: forall tr1 tr2 (Tr1 Tr2: traces), Tr1 tr1 -> Tr2 tr2 -> traces_app Tr1 Tr2 (trace_app tr1 tr2).Inductive traces_app {Ac: Action}: traces -> traces -> traces :=
  traces_app_intro: forall tr1 tr2 (Tr1 Tr2: traces), Tr1 tr1 -> Tr2 tr2 -> traces_app Tr1 Tr2 (trace_app tr1 tr2).Class Command2Traces (P: ProgrammingLanguage) (Ac: Action): Type := {
  cmd_denote: cmd -> traces
}.Class Command2Traces (P: ProgrammingLanguage) (Ac: Action): Type := {
  cmd_denote: cmd -> traces
}.Class ActionInterpret (state: Type) (Ac: Action): Type := {
  state_enable: action -> state -> MetaState state -> Prop (*;
  state_enable_pf: forall a s ms1 ms2, state_enable a s ms1 -> state_enable a s ms2 -> ms1 = ms2*)
}.Class ActionInterpret (state: Type) (Ac: Action): Type := {
  state_enable: action -> state -> MetaState state -> Prop (*;
  state_enable_pf: forall a s ms1 ms2, state_enable a s ms1 -> state_enable a s ms2 -> ms1 = ms2*)
}.Class TraceSemantics (P: ProgrammingLanguage) (state: Type) (Ac: Action): Type := {
  c2t :> Command2Traces P Ac;
  ac_sem :> ActionInterpret state Ac
}.Class TraceSemantics (P: ProgrammingLanguage) (state: Type) (Ac: Action): Type := {
  c2t :> Command2Traces P Ac;
  ac_sem :> ActionInterpret state Ac
}.Class TraceSemantics (P: ProgrammingLanguage) (state: Type) (Ac: Action): Type := {
  c2t :> Command2Traces P Ac;
  ac_sem :> ActionInterpret state Ac
}.Class Action_resource (Ac: Action) (Res: Resource) : Type := {
  Aacquire_res: resource -> action;
  Arelease_res: resource -> action;
}.Class Action_resource (Ac: Action) (Res: Resource) : Type := {
  Aacquire_res: resource -> action;
  Arelease_res: resource -> action;
}.Class Action_resource (Ac: Action) (Res: Resource) : Type := {
  Aacquire_res: resource -> action;
  Arelease_res: resource -> action;
}.Class NormalAction_resource (Ac: Action) (Res: Resource) {Acr: Action_resource Ac Res}: Type := {
  Aacquire_res_inv: forall r1 r2, Aacquire_res r1 = Aacquire_res r2 -> r1 = r2;
  Arelease_res_inv: forall r1 r2, Arelease_res r1 = Arelease_res r2 -> r1 = r2;
  Aacquire_Arelease_res: forall r1 r2, Aacquire_res r1 <> Arelease_res r2;
}.Class NormalAction_resource (Ac: Action) (Res: Resource) {Acr: Action_resource Ac Res}: Type := {
  Aacquire_res_inv: forall r1 r2, Aacquire_res r1 = Aacquire_res r2 -> r1 = r2;
  Arelease_res_inv: forall r1 r2, Arelease_res r1 = Arelease_res r2 -> r1 = r2;
  Aacquire_Arelease_res: forall r1 r2, Aacquire_res r1 <> Arelease_res r2;
}.Class NormalAction_resource (Ac: Action) (Res: Resource) {Acr: Action_resource Ac Res}: Type := {
  Aacquire_res_inv: forall r1 r2, Aacquire_res r1 = Aacquire_res r2 -> r1 = r2;
  Arelease_res_inv: forall r1 r2, Arelease_res r1 = Arelease_res r2 -> r1 = r2;
  Aacquire_Arelease_res: forall r1 r2, Aacquire_res r1 <> Arelease_res r2;
}.Class NormalAction_resource (Ac: Action) (Res: Resource) {Acr: Action_resource Ac Res}: Type := {
  Aacquire_res_inv: forall r1 r2, Aacquire_res r1 = Aacquire_res r2 -> r1 = r2;
  Arelease_res_inv: forall r1 r2, Arelease_res r1 = Arelease_res r2 -> r1 = r2;
  Aacquire_Arelease_res: forall r1 r2, Aacquire_res r1 <> Arelease_res r2;
}.Definition is_resource_action {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res} (r: resource) (a: action) := Aacquire_res r = a \/ Arelease_res r = a.Definition is_resources_action {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res} (a: action) := exists r, is_resource_action r a.Ltac solve_resource_action :=
  repeat
  match goal with
  | H: Aacquire_res ?r1 = Aacquire_res ?r2 |- _ => apply Aacquire_res_inv in H; subst
  | H: Arelease_res ?r1 = Arelease_res ?r2 |- _ => apply Arelease_res_inv in H; subst
  | H: Aacquire_res ?r1 = Arelease_res ?r2 |- _ => exfalso; apply Aacquire_Arelease_res in H; apply H
  | H: Arelease_res ?r1 = Aacquire_res ?r2 |- _ => exfalso; symmetry in H; apply Aacquire_Arelease_res in H; apply H
  | H: ~ is_resource_action ?r (Aacquire_res ?r) |- _ => exfalso; apply H; left; auto
  | H: ~ is_resource_action ?r (Arelease_res ?r) |- _ => exfalso; apply H; right; auto
  | H: ~ is_resources_action (Aacquire_res ?r) |- _ => exfalso; apply H; exists r; left; auto
  | H: ~ is_resources_action (Arelease_res ?r) |- _ => exfalso; apply H; exists r; right; auto
  end;
  repeat
  let HH := fresh "H" in
  match goal with
  | H: ~ is_resource_action ?r1 (Aacquire_res ?r2) |- _ =>
         specialize (fun (HH: r2 = r1) => H (or_introl (f_equal Aacquire_res (eq_sym HH))))
  | H: ~ is_resource_action ?r1 (Arelease_res ?r2) |- _ =>
         specialize (fun (HH: r2 = r1) => H (or_intror (f_equal Arelease_res (eq_sym HH))))
  end.Instance Res_Join (Res: Resource): Join resources := Pred_Join resource.Instance Res_SA (Res: Resource): SeparationAlgebra resources := Pred_SA resource.(* res_enable A1 A1' A2 := A1 ==> A1' while A2 is the environ *)
Inductive res_enable {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res}: action -> resources -> resources -> resources -> Prop :=
| res_enable_acq: forall r A1 A1' A2, join A1 (eq r) A1' -> ~ A2 r -> res_enable (Aacquire_res r) A1 A1' A2
| res_enable_rel: forall r A1 A1' A2, join A1' (eq r) A1 -> res_enable (Arelease_res r) A1 A1' A2
| res_enable_other: forall a A1 A2, ~ is_resources_action a -> res_enable a A1 A1 A2.(* res_enable A1 A1' A2 := A1 ==> A1' while A2 is the environ *)
Inductive res_enable {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res}: action -> resources -> resources -> resources -> Prop :=
| res_enable_acq: forall r A1 A1' A2, join A1 (eq r) A1' -> ~ A2 r -> res_enable (Aacquire_res r) A1 A1' A2
| res_enable_rel: forall r A1 A1' A2, join A1' (eq r) A1 -> res_enable (Arelease_res r) A1 A1' A2
| res_enable_other: forall a A1 A2, ~ is_resources_action a -> res_enable a A1 A1 A2.(* res_enable A1 A1' A2 := A1 ==> A1' while A2 is the environ *)
Inductive res_enable {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res}: action -> resources -> resources -> resources -> Prop :=
| res_enable_acq: forall r A1 A1' A2, join A1 (eq r) A1' -> ~ A2 r -> res_enable (Aacquire_res r) A1 A1' A2
| res_enable_rel: forall r A1 A1' A2, join A1' (eq r) A1 -> res_enable (Arelease_res r) A1 A1' A2
| res_enable_other: forall a A1 A2, ~ is_resources_action a -> res_enable a A1 A1 A2.(* res_enable A1 A1' A2 := A1 ==> A1' while A2 is the environ *)
Inductive res_enable {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res}: action -> resources -> resources -> resources -> Prop :=
| res_enable_acq: forall r A1 A1' A2, join A1 (eq r) A1' -> ~ A2 r -> res_enable (Aacquire_res r) A1 A1' A2
| res_enable_rel: forall r A1 A1' A2, join A1' (eq r) A1 -> res_enable (Arelease_res r) A1 A1' A2
| res_enable_other: forall a A1 A2, ~ is_resources_action a -> res_enable a A1 A1 A2.

(* Specifications: *)
Lemma res_enable_acq_inv {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res} {nAcr: NormalAction_resource Ac Res}: forall r A1 A1' A2, res_enable (Aacquire_res r) A1 A1' A2 -> join A1 (eq r) A1' /\ ~ A2 r.
Lemma res_enable_rel_inv {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res} {nAcr: NormalAction_resource Ac Res}: forall r A1 A1' A2, res_enable (Arelease_res r) A1 A1' A2 -> join A1' (eq r) A1.
Lemma res_enable_not_res_inv {Ac: Action} {Res: Resource} {Acr: Action_resource Ac Res} {nAcr: NormalAction_resource Ac Res}: forall a A1 A1' A2, ~ is_resources_action a -> res_enable a A1 A1' A2 -> A1 = A1'.