Require Import Eqdep Lia Framework FSParameters FileDiskLayer. (* LoggedDiskLayer TransactionCacheLayer TransactionalDiskLayer. *)
Require Import FileDiskNoninterference FileDiskRefinement.
Require Import ATCLayer FileDisk.TransferProofs ATC_Simulation ATC_AOE.
Require Import Not_Init HSS ATC_ORS ATC_TS_Common.

Import FileDiskLayer.
Set Nested Proofs Allowed.

Lemma ATC_TS_TransactionCache_get:
  forall n u V R,
  Termination_Sensitive u
  (Op
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (@P2 _ TransactionCacheOperation _ (@P1 (ListOperation (addr * value)) _ _ (Get (prod addr value)))))
  (Op
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (@P2 _ TransactionCacheOperation _ (@P1 (ListOperation (addr * value)) _ _ (Get (prod addr value)))))
(Simulation.Definitions.compile
   ATC_Refinement
   (Simulation.Definitions.compile
      FD.refinement
      (| Recover |)))
  V R
(ATC_reboot_list n).
Proof.
  unfold Termination_Sensitive, ATC_reboot_list;
  intros; destruct n;
  repeat invert_exec.
  invert_exec'' H9; repeat invert_exec.
  eexists (RFinished _ _); repeat econstructor.

  invert_exec'' H12;
  repeat invert_exec; simpl in *.
  edestruct ATC_TS_recovery; eauto.
  all: unfold AD_valid_state,
  refines_valid, FD_valid_state;
  intros; simpl; eauto.
  shelve.
  eexists (Recovered _); repeat econstructor; eauto.
  Unshelve.
  all: try solve [exact (fun _ _ => True)].
  all: simpl; eauto.
Qed.

Lemma ATC_TS_LoggedDisk_read:
  forall n u V R a1 a2,
  (a1 < data_length <-> a2 < data_length) ->
  Termination_Sensitive u
  (Op
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (@P2 _ TransactionCacheOperation _
     (@P2 _ (LoggedDiskOperation log_length data_length) _ (LoggedDiskLayer.Read a1))))
  (Op
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (@P2 _ TransactionCacheOperation _
     (@P2 _ (LoggedDiskOperation log_length data_length) _ (LoggedDiskLayer.Read a2))))
(Simulation.Definitions.compile
   ATC_Refinement
   (Simulation.Definitions.compile
      FD.refinement
      (| Recover |)))
  V R
(ATC_reboot_list n).
Proof.
  unfold Termination_Sensitive, ATC_reboot_list;
  intros; destruct n;
  repeat invert_exec.
  invert_exec'' H10; repeat invert_exec.
  eexists (RFinished _ _); repeat econstructor.
  lia.

  eexists (RFinished _ _);
  try solve [repeat econstructor; lia].

  invert_exec'' H13;
  repeat invert_exec; simpl in *.
  edestruct ATC_TS_recovery; eauto.
  all: unfold AD_valid_state,
  refines_valid, FD_valid_state;
  intros; simpl; eauto.
  shelve.
  eexists (Recovered _); repeat econstructor; eauto.
  Unshelve.
  all: try solve [exact (fun _ _ => True)].
  all: simpl; eauto.
Qed.

Lemma ATC_TS_LoggedDisk_write:
  forall n u V R l_a1 l_a2 l_v1 l_v2,
  (NoDup l_a1 <-> NoDup l_a2) ->
  (length l_a1 = length l_v1 <-> length l_a2 = length l_v2) ->
   (Forall (fun a : nat => a < data_length) l_a1 <-> Forall (fun a : nat => a < data_length) l_a2) ->
   (length (addr_list_to_blocks l_a1) + length l_v1 <= log_length <-> length (addr_list_to_blocks l_a2) + length l_v2 <= log_length ) ->
  Termination_Sensitive u
  (Op
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (@P2 _ TransactionCacheOperation _
     (@P2 _ (LoggedDiskOperation log_length data_length) _
     (LoggedDiskLayer.Write l_a1 l_v1))))
  (Op
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (@P2 _ TransactionCacheOperation _
     (@P2 _ (LoggedDiskOperation log_length data_length) _
     (LoggedDiskLayer.Write l_a2 l_v2))))
(Simulation.Definitions.compile
   ATC_Refinement
   (Simulation.Definitions.compile
      FD.refinement
      (| Recover |)))
  V R
(ATC_reboot_list n).
Proof.
  unfold Termination_Sensitive, ATC_reboot_list;
  intros; destruct n;
  repeat invert_exec.
  {
   invert_exec'' H13; repeat invert_exec.
   eexists (RFinished _ _); repeat econstructor;
   intuition eauto.

   eexists (RFinished _ _);
   do 4 econstructor.
   eapply LoggedDiskLayer.ExecWriteFail.
   intuition eauto.
   lia.
  }
  {
     invert_exec'' H16;
  repeat invert_exec; simpl in *.
  edestruct ATC_TS_recovery; eauto.
  all: unfold AD_valid_state,
  refines_valid, FD_valid_state;
  intros; simpl; eauto.
  shelve.
  eexists (Recovered _); repeat econstructor; eauto.
  repeat invert_exec; simpl in *.
  edestruct ATC_TS_recovery; eauto.
  all: unfold AD_valid_state,
  refines_valid, FD_valid_state;
  intros; simpl; eauto.
  shelve.
  eexists (Recovered _); repeat econstructor; eauto.
  all: intuition eauto.
  }
  Unshelve.
  all: try solve [exact (fun _ _ => True)].
  all: simpl; eauto.
Qed.

Lemma ATC_TS_Transaction_read:
    forall n u a1 a2,
    (a1 < data_length <-> a2 < data_length) ->
    Termination_Sensitive u
    (@lift_L2 AuthenticationOperation _ TransactionCacheLang _
        (Transaction.read a1))
    (@lift_L2 AuthenticationOperation _ TransactionCacheLang  _
        (Transaction.read a2))
  (Simulation.Definitions.compile
     ATC_Refinement
     (Simulation.Definitions.compile
        FD.refinement
        (| Recover |)))
  (refines_valid ATC_Refinement
     AD_valid_state)
  (fun s1 s2 =>
  Transaction.get_first (fst (snd s1)) a1 = None <-> Transaction.get_first (fst (snd s2)) a2 = None)
  (ATC_reboot_list n).
  Proof.
    unfold Transaction.read; intros.
    destruct (Compare_dec.lt_dec a1 data_length);
    destruct (Compare_dec.lt_dec a2 data_length); try lia.
    2: apply ATC_TS_ret.

    intros.
    eapply ATC_TS_compositional; simpl.
    intros; eapply ATC_TS_TransactionCache_get.

    intros.
    cleanup.
    repeat invert_exec.
    destruct_fresh (Transaction.get_first (fst (snd s1)) a1);
    destruct_fresh (Transaction.get_first (fst (snd s2)) a2);
    try solve [intuition congruence].
    setoid_rewrite D;
    setoid_rewrite D0; simpl.
    apply ATC_TS_ret.
    apply H2 in D0;
    setoid_rewrite D in D0; congruence.
    apply H2 in D;
    setoid_rewrite D in D0; congruence.

    setoid_rewrite D;
    setoid_rewrite D0; simpl.
    eapply ATC_TS_compositional; simpl; intros.
    eapply ATC_TS_LoggedDisk_read; eauto.
    apply ATC_TS_ret.
    instantiate (1:= fun _ _ => True); simpl; eauto.
    instantiate (1:= fun _ _ => True); simpl; eauto.
  Qed.

  Lemma ATC_TS_auth:
  forall u u1 u2 n V R,
  Termination_Sensitive u
  (Op
     (HorizontalComposition AuthenticationOperation
        TransactionCacheOperation)
        (@P1 AuthenticationOperation _ _ (Auth u1)))
  (Op
     (HorizontalComposition AuthenticationOperation
        TransactionCacheOperation)
        (@P1 AuthenticationOperation _ _ (Auth u2)))
  (RefinementLift.compile
     (HorizontalComposition AuthenticationOperation
        TransactionCacheOperation)
     (HorizontalComposition AuthenticationOperation
        (TransactionalDiskLayer.TDCore data_length))
     ATCLang AD
     (HC_Core_Refinement ATCLang AD
        Definitions.TDCoreRefinement) unit File.recover)
  V R (ATC_reboot_list n).
  Proof.
   unfold Termination_Sensitive, ATC_reboot_list;
   intros.
   destruct n; simpl in *.
   {
      repeat invert_exec.
      invert_exec'' H9; repeat invert_exec;
      destruct (user_dec u u2);
      eexists (RFinished _ _); try solve [repeat econstructor; eauto].
   }
   {
    repeat invert_exec.
    invert_exec'' H12; repeat invert_exec.
    simpl in *; edestruct ATC_TS_recovery.
    3: eauto.
    unfold refines_valid, AD_valid_state,
    FD_valid_state, refines_valid; simpl;
    intros; eauto.

    unfold refines_valid, AD_valid_state,
    FD_valid_state, refines_valid; simpl;
    intros; eauto.
    shelve.
    eexists (Recovered _); repeat econstructor; eauto.
   }
   Unshelve.
   all: try solve [exact (fun _ _ => True)].
   all: simpl; eauto.
Qed.

  Lemma ATC_TS_abort:
   forall n u R,
  Termination_Sensitive u
  (compile_core
     (HC_Core_Refinement ATCLang AuthenticatedDiskLayer.ADLang
        Definitions.TDCoreRefinement)
        (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Abort))
  (compile_core
     (HC_Core_Refinement ATCLang AuthenticatedDiskLayer.ADLang
        Definitions.TDCoreRefinement)
        (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Abort))
  (Simulation.Definitions.compile ATC_Refinement
     (Simulation.Definitions.compile FDRefinement
        (Op FileToFileDisk.Definitions.abs_core Recover)))
  (refines_valid ATC_Refinement AD_valid_state) R
  (ATC_reboot_list n).
  Proof.
     unfold Termination_Sensitive, ATC_reboot_list;
     intros.
     destruct n; simpl in *.
     {
        repeat invert_exec.
        invert_exec'' H9; repeat invert_exec.
        eexists (RFinished _ _); repeat econstructor; eauto.
     }
     {
      repeat invert_exec.
      invert_exec'' H12; repeat invert_exec.
      simpl in *; edestruct ATC_TS_recovery.
      3: eauto.
      unfold refines_valid, AD_valid_state,
      FD_valid_state, refines_valid; simpl;
      intros; eauto.

      unfold refines_valid, AD_valid_state,
      FD_valid_state, refines_valid; simpl;
      intros; eauto.
      shelve.
      eexists (Recovered _); repeat econstructor; eauto.
     }
     Unshelve.
     all: try solve [exact (fun _ _ => True)].
     all: simpl; eauto.
  Qed.

  Lemma ATC_TS_commit:
  forall n u,
 Termination_Sensitive u
 (compile_core
    (HC_Core_Refinement ATCLang AuthenticatedDiskLayer.ADLang
       Definitions.TDCoreRefinement)
       (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Commit))
 (compile_core
    (HC_Core_Refinement ATCLang AuthenticatedDiskLayer.ADLang
       Definitions.TDCoreRefinement)
       (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Commit))
 (Simulation.Definitions.compile ATC_Refinement
    (Simulation.Definitions.compile FDRefinement
       (Op FileToFileDisk.Definitions.abs_core Recover)))
 (refines_valid ATC_Refinement AD_valid_state)
 (fun s1 s2 => (Forall (fun a : nat => a < data_length)
 (dedup_last addr_dec (rev (map fst (fst (snd s1))))) <->
 Forall (fun a : nat => a < data_length)
 (dedup_last addr_dec (rev (map fst (fst (snd s2)))))) /\

 (length
(addr_list_to_blocks
(dedup_last addr_dec (rev (map fst (fst (snd s1)))))) +
length
(dedup_by_list addr_dec (rev (map fst (fst (snd s1))))
(rev (map snd (fst (snd s1))))) <= log_length <->
length
(addr_list_to_blocks
(dedup_last addr_dec (rev (map fst (fst (snd s2)))))) +
length
(dedup_by_list addr_dec (rev (map fst (fst (snd s2))))
(rev (map snd (fst (snd s2))))) <= log_length))
 (ATC_reboot_list n).
 Proof.
    intros; simpl.
    eapply ATC_TS_compositional.
    intros; apply ATC_TS_TransactionCache_get.
    2: intros; shelve.
    intros; repeat invert_exec.

    eapply ATC_TS_compositional.
    {
       intros; eapply ATC_TS_LoggedDisk_write;
       intuition eauto.

       eapply Transaction.dedup_last_NoDup.
       eapply Transaction.dedup_last_NoDup.

       eapply dedup_last_dedup_by_list_length_le.
       repeat rewrite rev_length, map_length; eauto.
       eapply dedup_last_dedup_by_list_length_le.
       repeat rewrite rev_length, map_length; eauto.
    }
    intros; eapply ATC_TS_abort.
    intros; shelve.
    Unshelve.
    all: try solve [exact (fun _ _ => True)].
    all: simpl; eauto.
Qed.

  Lemma ATC_TS_abort_then_ret:
  forall n u T (t1 t2: T) R,
  Termination_Sensitive u
  (RefinementLift.compile
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (HorizontalComposition AuthenticationOperation
        (TransactionalDiskLayer.TDCore data_length)) ATCLang AD
     (HC_Core_Refinement ATCLang AD Definitions.TDCoreRefinement)
     _ (Bind
     (Op
        (HorizontalComposition AuthenticationOperation
           (TransactionalDiskLayer.TDCore data_length))
        (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Abort))
     (fun _ : unit => Ret t1)))
  (RefinementLift.compile
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (HorizontalComposition AuthenticationOperation
        (TransactionalDiskLayer.TDCore data_length)) ATCLang AD
     (HC_Core_Refinement ATCLang AD Definitions.TDCoreRefinement)
     _ (Bind
     (Op
        (HorizontalComposition AuthenticationOperation
           (TransactionalDiskLayer.TDCore data_length))
           (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Abort))
     (fun _ : unit => Ret t2)))
  (RefinementLift.compile
     (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
     (HorizontalComposition AuthenticationOperation
        (TransactionalDiskLayer.TDCore data_length)) ATCLang AD
     (HC_Core_Refinement ATCLang AD Definitions.TDCoreRefinement) unit
     File.recover)
     (refines_valid ATC_Refinement
      AD_valid_state) R (ATC_reboot_list n).
   Proof.
      intros.
      eapply ATC_TS_compositional.
      intros; apply ATC_TS_abort.
      intros; apply ATC_TS_ret.
      instantiate (1:= fun _ _ => True); simpl; eauto.
   Qed.

   Lemma ATC_TS_commit_then_ret:
   forall n u T (t1 t2: T),
   Termination_Sensitive u
   (RefinementLift.compile
      (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
      (HorizontalComposition AuthenticationOperation
         (TransactionalDiskLayer.TDCore data_length)) ATCLang AD
      (HC_Core_Refinement ATCLang AD Definitions.TDCoreRefinement)
      _ (Bind
      (Op
         (HorizontalComposition AuthenticationOperation
            (TransactionalDiskLayer.TDCore data_length))
         (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Commit))
      (fun _ : unit => Ret t1)))
   (RefinementLift.compile
      (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
      (HorizontalComposition AuthenticationOperation
         (TransactionalDiskLayer.TDCore data_length)) ATCLang AD
      (HC_Core_Refinement ATCLang AD Definitions.TDCoreRefinement)
      _ (Bind
      (Op
         (HorizontalComposition AuthenticationOperation
            (TransactionalDiskLayer.TDCore data_length))
            (@P2 _ (TransactionalDiskLayer.TDCore data_length) _ TransactionalDiskLayer.Commit))
      (fun _ : unit => Ret t2)))
   (RefinementLift.compile
      (HorizontalComposition AuthenticationOperation TransactionCacheOperation)
      (HorizontalComposition AuthenticationOperation
         (TransactionalDiskLayer.TDCore data_length)) ATCLang AD
      (HC_Core_Refinement ATCLang AD Definitions.TDCoreRefinement) unit
      File.recover)
      (refines_valid ATC_Refinement
       AD_valid_state)
       (fun s1 s2 => (Forall (fun a : nat => a < data_length)
 (dedup_last addr_dec (rev (map fst (fst (snd s1))))) <->
 Forall (fun a : nat => a < data_length)
 (dedup_last addr_dec (rev (map fst (fst (snd s2)))))) /\

 (length
(addr_list_to_blocks
(dedup_last addr_dec (rev (map fst (fst (snd s1)))))) +
length
(dedup_by_list addr_dec (rev (map fst (fst (snd s1))))
(rev (map snd (fst (snd s1))))) <= log_length <->
length
(addr_list_to_blocks
(dedup_last addr_dec (rev (map fst (fst (snd s2)))))) +
length
(dedup_by_list addr_dec (rev (map fst (fst (snd s2))))
(rev (map snd (fst (snd s2))))) <= log_length))
       (ATC_reboot_list n).
    Proof.
       intros.
       eapply ATC_TS_compositional.
       intros; apply ATC_TS_commit.
       intros; apply ATC_TS_ret.
       instantiate (1:= fun _ _ => True); simpl; eauto.
    Qed.


(*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *)
From stdpp Require Import base strings gmap stringmap fin_maps.
From iris.base_logic Require Import upred derived.
From iris.base_logic.lib Require Import iprop own.
From iris.algebra Require Import ofe cmra gmap_view.
From iris.proofmode Require Import tactics.

From shack Require Import lang progdef subtype ok.
From shack Require Import eval heap modality interp typing.
From shack.soundness Require Import defs.

Section proofs.
  (* assume a given set of class definitions and their SDT annotations. *)
  Context `{SDTCVS: SDTClassVarianceSpec}.

  (* Iris semantic context *)
  Context `{!sem_heapGS Θ}.

  Lemma sub_soundness C cdef Δ kd Γ rigid Γ0 Γ1 c:
    wf_cdefs →
    wf_lty Γ →
    bounded_lty rigid Γ →
    Forall wf_constraint Δ →
    Forall (bounded_constraint rigid) Δ →
    pdefs !! C = Some cdef →
    lty_sub Δ kd Γ1 Γ0 →
    bounded_lty rigid Γ0 →
    cmd_has_ty C Δ kd rigid Γ c Γ1 →
    ∀ t0 t0def Σt0 σ0,
    pdefs !! t0 = Some t0def →
    length Σt0 = length t0def.(generics) →
    inherits_using t0 C σ0 →
    ∀ Σ st st' n,
    length Σ = rigid →
    rigid ≥ length cdef.(generics) →
    cmd_eval C st c st' n →
    let Σthis := interp_exact_tag interp_type t0 Σt0 in
    ⌜interp_list interp_nothing Σt0 σ0 ≡ take (length cdef.(generics)) Σ⌝ -∗
    □ interp_env_as_mixed Σt0 -∗
    □ interp_env_as_mixed Σ -∗
    □ Σinterp Σthis Σ Δ -∗

    □ (⌜wf_lty Γ⌝ →
       ⌜bounded_lty rigid Γ⌝ →
       ⌜Forall wf_constraint Δ⌝ →
       ⌜Forall (bounded_constraint rigid) Δ⌝ →
       ∀ Σ st st' n
       (_: length Σ = rigid)
       (_: rigid ≥ length (generics cdef))
       (_: cmd_eval C st c st' n),
       ⌜interp_list interp_nothing Σt0 σ0 ≡ take (length cdef.(generics)) Σ⌝ -∗
       □ interp_env_as_mixed Σt0 -∗
       □ interp_env_as_mixed Σ -∗
       □ Σinterp (interp_exact_tag interp_type t0 Σt0) Σ Δ -∗
       heap_models st.2 ∗
         interp_local_tys (interp_exact_tag interp_type t0 Σt0) Σ Γ st.1 -∗
       |=▷^n heap_models st'.2 ∗
         interp_local_tys (interp_exact_tag interp_type t0 Σt0) Σ Γ1 st'.1) -∗

    heap_models st.2 ∗ interp_local_tys Σthis Σ Γ st.1 -∗
    |=▷^n heap_models st'.2 ∗ interp_local_tys Σthis Σ Γ0 st'.1.
  Proof.
    move => wfpdefs wflty blty hΔ hΔb hcdef hsub hb h.
    move => t0 t0def Σt0 σ0 ht0def hlenΣt0 hin_t0_C.
    move => Σ st st' n hrigid hge hc Σthis.
    iIntros "%hΣeq #hΣt0 #hΣ #hΣΔ #HI H".
    iSpecialize ("HI" $! wflty blty hΔ hΔb).
    iSpecialize ("HI" $! Σ _ _ _ hrigid hge hc hΣeq with "hΣt0 hΣ hΣΔ H").
    iApply updN_mono_I; last done.
    iIntros "[Hh #Hrty]".
    iFrame.
    iAssert (□ interp_as_mixed Σthis)%I as "#hΣthis".
    { iModIntro; iIntros (w) "hw".
      iLeft; iRight; iRight.
      iExists t0, Σt0, t0def; iSplit; first done.
      by iApply (exact_subtype_is_inclusion_aux with "hΣt0 hw").
    }
    iDestruct (interp_local_tys_is_inclusion with "hΣthis hΣ hΣΔ Hrty") as "Hrty'" => //; try by apply wfpdefs.
    + apply cmd_has_ty_wf in h; try (assumption || by apply wfpdefs).
    + rewrite Forall_forall => i hi v.
      by apply _.
  Qed.
End proofs.


From Coq Require Import String List ZArith.
From compcert Require Import Coqlib Integers Floats AST Ctypes Cop Clight Clightdefs.
Import Clightdefs.ClightNotations.
Local Open Scope Z_scope.
Local Open Scope string_scope.
Local Open Scope clight_scope.

Module Info.
  Definition version := "3.10".
  Definition build_number := "".
  Definition build_tag := "".
  Definition build_branch := "".
  Definition arch := "x86".
  Definition model := "32sse2".
  Definition abi := "standard".
  Definition bitsize := 32.
  Definition big_endian := false.
  Definition source_file := "threads.c".
  Definition normalized := false.
End Info.

Definition _N : ident := $"N".
Definition _R : ident := $"R".
Definition _REPEAT : ident := $"REPEAT".
Definition _T : ident := $"T".
Definition __138 : ident := $"_138".
Definition __139 : ident := $"_139".
Definition __212 : ident := $"_212".
Definition __213 : ident := $"_213".
Definition __214 : ident := $"_214".
Definition __Bigint : ident := $"_Bigint".
Definition ___builtin_annot : ident := $"__builtin_annot".
Definition ___builtin_annot_intval : ident := $"__builtin_annot_intval".
Definition ___builtin_bswap : ident := $"__builtin_bswap".
Definition ___builtin_bswap16 : ident := $"__builtin_bswap16".
Definition ___builtin_bswap32 : ident := $"__builtin_bswap32".
Definition ___builtin_bswap64 : ident := $"__builtin_bswap64".
Definition ___builtin_clz : ident := $"__builtin_clz".
Definition ___builtin_clzl : ident := $"__builtin_clzl".
Definition ___builtin_clzll : ident := $"__builtin_clzll".
Definition ___builtin_ctz : ident := $"__builtin_ctz".
Definition ___builtin_ctzl : ident := $"__builtin_ctzl".
Definition ___builtin_ctzll : ident := $"__builtin_ctzll".
Definition ___builtin_debug : ident := $"__builtin_debug".
Definition ___builtin_expect : ident := $"__builtin_expect".
Definition ___builtin_fabs : ident := $"__builtin_fabs".
Definition ___builtin_fabsf : ident := $"__builtin_fabsf".
Definition ___builtin_fmadd : ident := $"__builtin_fmadd".
Definition ___builtin_fmax : ident := $"__builtin_fmax".
Definition ___builtin_fmin : ident := $"__builtin_fmin".
Definition ___builtin_fmsub : ident := $"__builtin_fmsub".
Definition ___builtin_fnmadd : ident := $"__builtin_fnmadd".
Definition ___builtin_fnmsub : ident := $"__builtin_fnmsub".
Definition ___builtin_fsqrt : ident := $"__builtin_fsqrt".
Definition ___builtin_membar : ident := $"__builtin_membar".
Definition ___builtin_memcpy_aligned : ident := $"__builtin_memcpy_aligned".
Definition ___builtin_read16_reversed : ident := $"__builtin_read16_reversed".
Definition ___builtin_read32_reversed : ident := $"__builtin_read32_reversed".
Definition ___builtin_sel : ident := $"__builtin_sel".
Definition ___builtin_sqrt : ident := $"__builtin_sqrt".
Definition ___builtin_unreachable : ident := $"__builtin_unreachable".
Definition ___builtin_va_arg : ident := $"__builtin_va_arg".
Definition ___builtin_va_copy : ident := $"__builtin_va_copy".
Definition ___builtin_va_end : ident := $"__builtin_va_end".
Definition ___builtin_va_start : ident := $"__builtin_va_start".
Definition ___builtin_write16_reversed : ident := $"__builtin_write16_reversed".
Definition ___builtin_write32_reversed : ident := $"__builtin_write32_reversed".
Definition ___cleanup : ident := $"__cleanup".
Definition ___compcert_i64_dtos : ident := $"__compcert_i64_dtos".
Definition ___compcert_i64_dtou : ident := $"__compcert_i64_dtou".
Definition ___compcert_i64_sar : ident := $"__compcert_i64_sar".
Definition ___compcert_i64_sdiv : ident := $"__compcert_i64_sdiv".
Definition ___compcert_i64_shl : ident := $"__compcert_i64_shl".
Definition ___compcert_i64_shr : ident := $"__compcert_i64_shr".
Definition ___compcert_i64_smod : ident := $"__compcert_i64_smod".
Definition ___compcert_i64_smulh : ident := $"__compcert_i64_smulh".
Definition ___compcert_i64_stod : ident := $"__compcert_i64_stod".
Definition ___compcert_i64_stof : ident := $"__compcert_i64_stof".
Definition ___compcert_i64_udiv : ident := $"__compcert_i64_udiv".
Definition ___compcert_i64_umod : ident := $"__compcert_i64_umod".
Definition ___compcert_i64_umulh : ident := $"__compcert_i64_umulh".
Definition ___compcert_i64_utod : ident := $"__compcert_i64_utod".
Definition ___compcert_i64_utof : ident := $"__compcert_i64_utof".
Definition ___compcert_va_composite : ident := $"__compcert_va_composite".
Definition ___compcert_va_float64 : ident := $"__compcert_va_float64".
Definition ___compcert_va_int32 : ident := $"__compcert_va_int32".
Definition ___compcert_va_int64 : ident := $"__compcert_va_int64".
Definition ___count : ident := $"__count".
Definition ___dummy : ident := $"__dummy".
Definition ___getreent : ident := $"__getreent".
Definition ___locale_t : ident := $"__locale_t".
Definition ___pthread_t : ident := $"__pthread_t".
Definition ___sFILE64 : ident := $"__sFILE64".
Definition ___sbuf : ident := $"__sbuf".
Definition ___sdidinit : ident := $"__sdidinit".
Definition ___sf : ident := $"__sf".
Definition ___sglue : ident := $"__sglue".
Definition ___stringlit_1 : ident := $"__stringlit_1".
Definition ___stringlit_2 : ident := $"__stringlit_2".
Definition ___tm : ident := $"__tm".
Definition ___tm_hour : ident := $"__tm_hour".
Definition ___tm_isdst : ident := $"__tm_isdst".
Definition ___tm_mday : ident := $"__tm_mday".
Definition ___tm_min : ident := $"__tm_min".
Definition ___tm_mon : ident := $"__tm_mon".
Definition ___tm_sec : ident := $"__tm_sec".
Definition ___tm_wday : ident := $"__tm_wday".
Definition ___tm_yday : ident := $"__tm_yday".
Definition ___tm_year : ident := $"__tm_year".
Definition ___value : ident := $"__value".
Definition ___wch : ident := $"__wch".
Definition ___wchb : ident := $"__wchb".
Definition __add : ident := $"_add".
Definition __asctime_buf : ident := $"_asctime_buf".
Definition __atexit : ident := $"_atexit".
Definition __atexit0 : ident := $"_atexit0".
Definition __base : ident := $"_base".
Definition __bf : ident := $"_bf".
Definition __blksize : ident := $"_blksize".
Definition __close : ident := $"_close".
Definition __cookie : ident := $"_cookie".
Definition __cvtbuf : ident := $"_cvtbuf".
Definition __cvtlen : ident := $"_cvtlen".
Definition __data : ident := $"_data".
Definition __dso_handle : ident := $"_dso_handle".
Definition __emergency : ident := $"_emergency".
Definition __errno : ident := $"_errno".
Definition __file : ident := $"_file".
Definition __flags : ident := $"_flags".
Definition __flags2 : ident := $"_flags2".
Definition __fnargs : ident := $"_fnargs".
Definition __fns : ident := $"_fns".
Definition __fntypes : ident := $"_fntypes".
Definition __freelist : ident := $"_freelist".
Definition __gamma_signgam : ident := $"_gamma_signgam".
Definition __getdate_err : ident := $"_getdate_err".
Definition __glue : ident := $"_glue".
Definition __h_errno : ident := $"_h_errno".
Definition __inc : ident := $"_inc".
Definition __ind : ident := $"_ind".
Definition __iobs : ident := $"_iobs".
Definition __is_cxa : ident := $"_is_cxa".
Definition __k : ident := $"_k".
Definition __l64a_buf : ident := $"_l64a_buf".
Definition __lb : ident := $"_lb".
Definition __lbfsize : ident := $"_lbfsize".
Definition __locale : ident := $"_locale".
Definition __localtime_buf : ident := $"_localtime_buf".
Definition __lock : ident := $"_lock".
Definition __maxwds : ident := $"_maxwds".
Definition __mblen_state : ident := $"_mblen_state".
Definition __mbrlen_state : ident := $"_mbrlen_state".
Definition __mbrtowc_state : ident := $"_mbrtowc_state".
Definition __mbsrtowcs_state : ident := $"_mbsrtowcs_state".
Definition __mbstate : ident := $"_mbstate".
Definition __mbtowc_state : ident := $"_mbtowc_state".
Definition __mult : ident := $"_mult".
Definition __nbuf : ident := $"_nbuf".
Definition __new : ident := $"_new".
Definition __next : ident := $"_next".
Definition __nextf : ident := $"_nextf".
Definition __niobs : ident := $"_niobs".
Definition __nmalloc : ident := $"_nmalloc".
Definition __offset : ident := $"_offset".
Definition __on_exit_args : ident := $"_on_exit_args".
Definition __p : ident := $"_p".
Definition __p5s : ident := $"_p5s".
Definition __r : ident := $"_r".
Definition __r48 : ident := $"_r48".
Definition __rand48 : ident := $"_rand48".
Definition __rand_next : ident := $"_rand_next".
Definition __read : ident := $"_read".
Definition __reent : ident := $"_reent".
Definition __result : ident := $"_result".
Definition __result_k : ident := $"_result_k".
Definition __seed : ident := $"_seed".
Definition __seek : ident := $"_seek".
Definition __seek64 : ident := $"_seek64".
Definition __sig_func : ident := $"_sig_func".
Definition __sign : ident := $"_sign".
Definition __signal_buf : ident := $"_signal_buf".
Definition __size : ident := $"_size".
Definition __stderr : ident := $"_stderr".
Definition __stdin : ident := $"_stdin".
Definition __stdout : ident := $"_stdout".
Definition __strtok_last : ident := $"_strtok_last".
Definition __ub : ident := $"_ub".
Definition __ubuf : ident := $"_ubuf".
Definition __unspecified_locale_info : ident := $"_unspecified_locale_info".
Definition __unused : ident := $"_unused".
Definition __unused_rand : ident := $"_unused_rand".
Definition __up : ident := $"_up".
Definition __ur : ident := $"_ur".
Definition __w : ident := $"_w".
Definition __wcrtomb_state : ident := $"_wcrtomb_state".
Definition __wcsrtombs_state : ident := $"_wcsrtombs_state".
Definition __wctomb_state : ident := $"_wctomb_state".
Definition __wds : ident := $"_wds".
Definition __write : ident := $"_write".
Definition __x : ident := $"_x".
Definition _acquire : ident := $"acquire".
Definition _arg : ident := $"arg".
Definition _argc : ident := $"argc".
Definition _args : ident := $"args".
Definition _argv : ident := $"argv".
Definition _atoi : ident := $"atoi".
Definition _atom_CAS : ident := $"atom_CAS".
Definition _atom_int : ident := $"atom_int".
Definition _atom_store : ident := $"atom_store".
Definition _b : ident := $"b".
Definition _closure : ident := $"closure".
Definition _d : ident := $"d".
Definition _do_tasks : ident := $"do_tasks".
Definition _done : ident := $"done".
Definition _dotprod : ident := $"dotprod".
Definition _dotprod_task : ident := $"dotprod_task".
Definition _dotprod_worker : ident := $"dotprod_worker".
Definition _drand48 : ident := $"drand48".
Definition _dtasks : ident := $"dtasks".
Definition _exit : ident := $"exit".
Definition _exit_thread : ident := $"exit_thread".
Definition _expected : ident := $"expected".
Definition _f : ident := $"f".
Definition _fprintf : ident := $"fprintf".
Definition _free_atomic : ident := $"free_atomic".
Definition _freelock : ident := $"freelock".
Definition _go : ident := $"go".
Definition _i : ident := $"i".
Definition _initialize_task : ident := $"initialize_task".
Definition _j : ident := $"j".
Definition _k : ident := $"k".
Definition _lock : ident := $"lock".
Definition _main : ident := $"main".
Definition _make_atomic : ident := $"make_atomic".
Definition _make_tasks : ident := $"make_tasks".
Definition _makelock : ident := $"makelock".
Definition _malloc : ident := $"malloc".
Definition _n : ident := $"n".
Definition _num_threads : ident := $"num_threads".
Definition _printf : ident := $"printf".
Definition _r : ident := $"r".
Definition _release : ident := $"release".
Definition _result : ident := $"result".
Definition _spawn : ident := $"spawn".
Definition _t : ident := $"t".
Definition _task : ident := $"task".
Definition _tasks : ident := $"tasks".
Definition _test : ident := $"test".
Definition _thrd_create : ident := $"thrd_create".
Definition _thrd_exit : ident := $"thrd_exit".
Definition _thread_worker : ident := $"thread_worker".
Definition _vec1 : ident := $"vec1".
Definition _vec2 : ident := $"vec2".
Definition _w : ident := $"w".
Definition _t'1 : ident := 128%positive.

Definition f_makelock := {|
  fn_return := (tptr (Tstruct _atom_int noattr));
  fn_callconv := cc_default;
  fn_params := nil;
  fn_vars := nil;
  fn_temps := ((_t'1, (tptr (Tstruct _atom_int noattr))) :: nil);
  fn_body :=
(Ssequence
  (Scall (Some _t'1)
    (Evar _make_atomic (Tfunction (Tcons tint Tnil)
                         (tptr (Tstruct _atom_int noattr)) cc_default))
    ((Econst_int (Int.repr 1) tint) :: nil))
  (Sreturn (Some (Etempvar _t'1 (tptr (Tstruct _atom_int noattr))))))
|}.

Definition f_freelock := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_lock, (tptr (Tstruct _atom_int noattr))) :: nil);
  fn_vars := nil;
  fn_temps := nil;
  fn_body :=
(Scall None
  (Evar _free_atomic (Tfunction
                       (Tcons (tptr (Tstruct _atom_int noattr)) Tnil) tvoid
                       cc_default))
  ((Etempvar _lock (tptr (Tstruct _atom_int noattr))) :: nil))
|}.

Definition f_acquire := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_lock, (tptr (Tstruct _atom_int noattr))) :: nil);
  fn_vars := ((_expected, tint) :: nil);
  fn_temps := ((_b, tint) :: (_t'1, tint) :: nil);
  fn_body :=
(Ssequence
  (Sset _b (Econst_int (Int.repr 0) tint))
  (Sloop
    (Ssequence
      (Sassign (Evar _expected tint) (Econst_int (Int.repr 0) tint))
      (Ssequence
        (Scall (Some _t'1)
          (Evar _atom_CAS (Tfunction
                            (Tcons (tptr (Tstruct _atom_int noattr))
                              (Tcons (tptr tint) (Tcons tint Tnil))) tint
                            cc_default))
          ((Etempvar _lock (tptr (Tstruct _atom_int noattr))) ::
           (Eaddrof (Evar _expected tint) (tptr tint)) ::
           (Econst_int (Int.repr 1) tint) :: nil))
        (Sset _b (Etempvar _t'1 tint))))
    (Sifthenelse (Ebinop Oeq (Etempvar _b tint)
                   (Econst_int (Int.repr 0) tint) tint)
      Sskip
      Sbreak)))
|}.

Definition f_release := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_lock, (tptr (Tstruct _atom_int noattr))) :: nil);
  fn_vars := nil;
  fn_temps := nil;
  fn_body :=
(Scall None
  (Evar _atom_store (Tfunction
                      (Tcons (tptr (Tstruct _atom_int noattr))
                        (Tcons tint Tnil)) tvoid cc_default))
  ((Etempvar _lock (tptr (Tstruct _atom_int noattr))) ::
   (Econst_int (Int.repr 0) tint) :: nil))
|}.

Definition f_spawn := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_f,
                 (tptr (Tfunction (Tcons (tptr tvoid) Tnil) tint cc_default))) ::
                (_args, (tptr tvoid)) :: nil);
  fn_vars := ((_t, (tptr (Tstruct ___pthread_t noattr))) :: nil);
  fn_temps := ((_t'1, tint) :: nil);
  fn_body :=
(Ssequence
  (Ssequence
    (Scall (Some _t'1)
      (Evar _thrd_create (Tfunction
                           (Tcons (tptr (tptr (Tstruct ___pthread_t noattr)))
                             (Tcons
                               (tptr (Tfunction (Tcons (tptr tvoid) Tnil)
                                       tint cc_default))
                               (Tcons (tptr tvoid) Tnil))) tint cc_default))
      ((Eaddrof (Evar _t (tptr (Tstruct ___pthread_t noattr)))
         (tptr (tptr (Tstruct ___pthread_t noattr)))) ::
       (Etempvar _f (tptr (Tfunction (Tcons (tptr tvoid) Tnil) tint
                            cc_default))) :: (Etempvar _args (tptr tvoid)) ::
       nil))
    (Sifthenelse (Ebinop One (Etempvar _t'1 tint)
                   (Econst_int (Int.repr 4) tint) tint)
      (Scall None (Evar _exit (Tfunction (Tcons tint Tnil) tvoid cc_default))
        ((Econst_int (Int.repr 1) tint) :: nil))
      Sskip))
  (Sreturn None))
|}.

Definition f_exit_thread := {|
  fn_return := tvoid;
  fn_callconv := cc_default;
  fn_params := ((_r, tint) :: nil);
  fn_vars := nil;
  fn_temps := nil;
  fn_body :=
(Scall None (Evar _thrd_exit (Tfunction (Tcons tint Tnil) tvoid cc_default))
  ((Etempvar _r tint) :: nil))
|}.

Definition composites : list composite_definition :=
(Composite ___pthread_t Struct (Member_plain ___dummy tschar :: nil) noattr ::
 nil).

Definition global_definitions : list (ident * globdef fundef type) :=
((___compcert_va_int32,
   Gfun(External (EF_runtime "__compcert_va_int32"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons (tptr tvoid) Tnil) tuint cc_default)) ::
 (___compcert_va_int64,
   Gfun(External (EF_runtime "__compcert_va_int64"
                   (mksignature (AST.Tint :: nil) AST.Tlong cc_default))
     (Tcons (tptr tvoid) Tnil) tulong cc_default)) ::
 (___compcert_va_float64,
   Gfun(External (EF_runtime "__compcert_va_float64"
                   (mksignature (AST.Tint :: nil) AST.Tfloat cc_default))
     (Tcons (tptr tvoid) Tnil) tdouble cc_default)) ::
 (___compcert_va_composite,
   Gfun(External (EF_runtime "__compcert_va_composite"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tint
                     cc_default)) (Tcons (tptr tvoid) (Tcons tuint Tnil))
     (tptr tvoid) cc_default)) ::
 (___compcert_i64_dtos,
   Gfun(External (EF_runtime "__compcert_i64_dtos"
                   (mksignature (AST.Tfloat :: nil) AST.Tlong cc_default))
     (Tcons tdouble Tnil) tlong cc_default)) ::
 (___compcert_i64_dtou,
   Gfun(External (EF_runtime "__compcert_i64_dtou"
                   (mksignature (AST.Tfloat :: nil) AST.Tlong cc_default))
     (Tcons tdouble Tnil) tulong cc_default)) ::
 (___compcert_i64_stod,
   Gfun(External (EF_runtime "__compcert_i64_stod"
                   (mksignature (AST.Tlong :: nil) AST.Tfloat cc_default))
     (Tcons tlong Tnil) tdouble cc_default)) ::
 (___compcert_i64_utod,
   Gfun(External (EF_runtime "__compcert_i64_utod"
                   (mksignature (AST.Tlong :: nil) AST.Tfloat cc_default))
     (Tcons tulong Tnil) tdouble cc_default)) ::
 (___compcert_i64_stof,
   Gfun(External (EF_runtime "__compcert_i64_stof"
                   (mksignature (AST.Tlong :: nil) AST.Tsingle cc_default))
     (Tcons tlong Tnil) tfloat cc_default)) ::
 (___compcert_i64_utof,
   Gfun(External (EF_runtime "__compcert_i64_utof"
                   (mksignature (AST.Tlong :: nil) AST.Tsingle cc_default))
     (Tcons tulong Tnil) tfloat cc_default)) ::
 (___compcert_i64_sdiv,
   Gfun(External (EF_runtime "__compcert_i64_sdiv"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tlong Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_udiv,
   Gfun(External (EF_runtime "__compcert_i64_udiv"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tulong Tnil)) tulong
     cc_default)) ::
 (___compcert_i64_smod,
   Gfun(External (EF_runtime "__compcert_i64_smod"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tlong Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_umod,
   Gfun(External (EF_runtime "__compcert_i64_umod"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tulong Tnil)) tulong
     cc_default)) ::
 (___compcert_i64_shl,
   Gfun(External (EF_runtime "__compcert_i64_shl"
                   (mksignature (AST.Tlong :: AST.Tint :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tint Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_shr,
   Gfun(External (EF_runtime "__compcert_i64_shr"
                   (mksignature (AST.Tlong :: AST.Tint :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tint Tnil)) tulong
     cc_default)) ::
 (___compcert_i64_sar,
   Gfun(External (EF_runtime "__compcert_i64_sar"
                   (mksignature (AST.Tlong :: AST.Tint :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tint Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_smulh,
   Gfun(External (EF_runtime "__compcert_i64_smulh"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tlong (Tcons tlong Tnil)) tlong
     cc_default)) ::
 (___compcert_i64_umulh,
   Gfun(External (EF_runtime "__compcert_i64_umulh"
                   (mksignature (AST.Tlong :: AST.Tlong :: nil) AST.Tlong
                     cc_default)) (Tcons tulong (Tcons tulong Tnil)) tulong
     cc_default)) ::
 (___builtin_bswap64,
   Gfun(External (EF_builtin "__builtin_bswap64"
                   (mksignature (AST.Tlong :: nil) AST.Tlong cc_default))
     (Tcons tulong Tnil) tulong cc_default)) ::
 (___builtin_bswap,
   Gfun(External (EF_builtin "__builtin_bswap"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tuint cc_default)) ::
 (___builtin_bswap32,
   Gfun(External (EF_builtin "__builtin_bswap32"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tuint cc_default)) ::
 (___builtin_bswap16,
   Gfun(External (EF_builtin "__builtin_bswap16"
                   (mksignature (AST.Tint :: nil) AST.Tint16unsigned
                     cc_default)) (Tcons tushort Tnil) tushort cc_default)) ::
 (___builtin_clz,
   Gfun(External (EF_builtin "__builtin_clz"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_clzl,
   Gfun(External (EF_builtin "__builtin_clzl"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_clzll,
   Gfun(External (EF_builtin "__builtin_clzll"
                   (mksignature (AST.Tlong :: nil) AST.Tint cc_default))
     (Tcons tulong Tnil) tint cc_default)) ::
 (___builtin_ctz,
   Gfun(External (EF_builtin "__builtin_ctz"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_ctzl,
   Gfun(External (EF_builtin "__builtin_ctzl"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tuint Tnil) tint cc_default)) ::
 (___builtin_ctzll,
   Gfun(External (EF_builtin "__builtin_ctzll"
                   (mksignature (AST.Tlong :: nil) AST.Tint cc_default))
     (Tcons tulong Tnil) tint cc_default)) ::
 (___builtin_fabs,
   Gfun(External (EF_builtin "__builtin_fabs"
                   (mksignature (AST.Tfloat :: nil) AST.Tfloat cc_default))
     (Tcons tdouble Tnil) tdouble cc_default)) ::
 (___builtin_fabsf,
   Gfun(External (EF_builtin "__builtin_fabsf"
                   (mksignature (AST.Tsingle :: nil) AST.Tsingle cc_default))
     (Tcons tfloat Tnil) tfloat cc_default)) ::
 (___builtin_fsqrt,
   Gfun(External (EF_builtin "__builtin_fsqrt"
                   (mksignature (AST.Tfloat :: nil) AST.Tfloat cc_default))
     (Tcons tdouble Tnil) tdouble cc_default)) ::
 (___builtin_sqrt,
   Gfun(External (EF_builtin "__builtin_sqrt"
                   (mksignature (AST.Tfloat :: nil) AST.Tfloat cc_default))
     (Tcons tdouble Tnil) tdouble cc_default)) ::
 (___builtin_memcpy_aligned,
   Gfun(External (EF_builtin "__builtin_memcpy_aligned"
                   (mksignature
                     (AST.Tint :: AST.Tint :: AST.Tint :: AST.Tint :: nil)
                     AST.Tvoid cc_default))
     (Tcons (tptr tvoid)
       (Tcons (tptr tvoid) (Tcons tuint (Tcons tuint Tnil)))) tvoid
     cc_default)) ::
 (___builtin_sel,
   Gfun(External (EF_builtin "__builtin_sel"
                   (mksignature (AST.Tint :: nil) AST.Tvoid
                     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|}))
     (Tcons tbool Tnil) tvoid
     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|})) ::
 (___builtin_annot,
   Gfun(External (EF_builtin "__builtin_annot"
                   (mksignature (AST.Tint :: nil) AST.Tvoid
                     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|}))
     (Tcons (tptr tschar) Tnil) tvoid
     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|})) ::
 (___builtin_annot_intval,
   Gfun(External (EF_builtin "__builtin_annot_intval"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tint
                     cc_default)) (Tcons (tptr tschar) (Tcons tint Tnil))
     tint cc_default)) ::
 (___builtin_membar,
   Gfun(External (EF_builtin "__builtin_membar"
                   (mksignature nil AST.Tvoid cc_default)) Tnil tvoid
     cc_default)) ::
 (___builtin_va_start,
   Gfun(External (EF_builtin "__builtin_va_start"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons (tptr tvoid) Tnil) tvoid cc_default)) ::
 (___builtin_va_arg,
   Gfun(External (EF_builtin "__builtin_va_arg"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default)) (Tcons (tptr tvoid) (Tcons tuint Tnil))
     tvoid cc_default)) ::
 (___builtin_va_copy,
   Gfun(External (EF_builtin "__builtin_va_copy"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default))
     (Tcons (tptr tvoid) (Tcons (tptr tvoid) Tnil)) tvoid cc_default)) ::
 (___builtin_va_end,
   Gfun(External (EF_builtin "__builtin_va_end"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons (tptr tvoid) Tnil) tvoid cc_default)) ::
 (___builtin_unreachable,
   Gfun(External (EF_builtin "__builtin_unreachable"
                   (mksignature nil AST.Tvoid cc_default)) Tnil tvoid
     cc_default)) ::
 (___builtin_expect,
   Gfun(External (EF_builtin "__builtin_expect"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tint
                     cc_default)) (Tcons tint (Tcons tint Tnil)) tint
     cc_default)) ::
 (___builtin_fmax,
   Gfun(External (EF_builtin "__builtin_fmax"
                   (mksignature (AST.Tfloat :: AST.Tfloat :: nil) AST.Tfloat
                     cc_default)) (Tcons tdouble (Tcons tdouble Tnil))
     tdouble cc_default)) ::
 (___builtin_fmin,
   Gfun(External (EF_builtin "__builtin_fmin"
                   (mksignature (AST.Tfloat :: AST.Tfloat :: nil) AST.Tfloat
                     cc_default)) (Tcons tdouble (Tcons tdouble Tnil))
     tdouble cc_default)) ::
 (___builtin_fmadd,
   Gfun(External (EF_builtin "__builtin_fmadd"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_fmsub,
   Gfun(External (EF_builtin "__builtin_fmsub"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_fnmadd,
   Gfun(External (EF_builtin "__builtin_fnmadd"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_fnmsub,
   Gfun(External (EF_builtin "__builtin_fnmsub"
                   (mksignature
                     (AST.Tfloat :: AST.Tfloat :: AST.Tfloat :: nil)
                     AST.Tfloat cc_default))
     (Tcons tdouble (Tcons tdouble (Tcons tdouble Tnil))) tdouble
     cc_default)) ::
 (___builtin_read16_reversed,
   Gfun(External (EF_builtin "__builtin_read16_reversed"
                   (mksignature (AST.Tint :: nil) AST.Tint16unsigned
                     cc_default)) (Tcons (tptr tushort) Tnil) tushort
     cc_default)) ::
 (___builtin_read32_reversed,
   Gfun(External (EF_builtin "__builtin_read32_reversed"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons (tptr tuint) Tnil) tuint cc_default)) ::
 (___builtin_write16_reversed,
   Gfun(External (EF_builtin "__builtin_write16_reversed"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default)) (Tcons (tptr tushort) (Tcons tushort Tnil))
     tvoid cc_default)) ::
 (___builtin_write32_reversed,
   Gfun(External (EF_builtin "__builtin_write32_reversed"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default)) (Tcons (tptr tuint) (Tcons tuint Tnil))
     tvoid cc_default)) ::
 (___builtin_debug,
   Gfun(External (EF_external "__builtin_debug"
                   (mksignature (AST.Tint :: nil) AST.Tvoid
                     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|}))
     (Tcons tint Tnil) tvoid
     {|cc_vararg:=(Some 1); cc_unproto:=false; cc_structret:=false|})) ::
 (_exit,
   Gfun(External (EF_external "exit"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons tint Tnil) tvoid cc_default)) ::
 (_thrd_create,
   Gfun(External (EF_external "thrd_create"
                   (mksignature (AST.Tint :: AST.Tint :: AST.Tint :: nil)
                     AST.Tint cc_default))
     (Tcons (tptr (tptr (Tstruct ___pthread_t noattr)))
       (Tcons (tptr (Tfunction (Tcons (tptr tvoid) Tnil) tint cc_default))
         (Tcons (tptr tvoid) Tnil))) tint cc_default)) ::
 (_thrd_exit,
   Gfun(External (EF_external "thrd_exit"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons tint Tnil) tvoid cc_default)) ::
 (_make_atomic,
   Gfun(External (EF_external "make_atomic"
                   (mksignature (AST.Tint :: nil) AST.Tint cc_default))
     (Tcons tint Tnil) (tptr (Tstruct _atom_int noattr)) cc_default)) ::
 (_atom_store,
   Gfun(External (EF_external "atom_store"
                   (mksignature (AST.Tint :: AST.Tint :: nil) AST.Tvoid
                     cc_default))
     (Tcons (tptr (Tstruct _atom_int noattr)) (Tcons tint Tnil)) tvoid
     cc_default)) ::
 (_atom_CAS,
   Gfun(External (EF_external "atom_CAS"
                   (mksignature (AST.Tint :: AST.Tint :: AST.Tint :: nil)
                     AST.Tint cc_default))
     (Tcons (tptr (Tstruct _atom_int noattr))
       (Tcons (tptr tint) (Tcons tint Tnil))) tint cc_default)) ::
 (_free_atomic,
   Gfun(External (EF_external "free_atomic"
                   (mksignature (AST.Tint :: nil) AST.Tvoid cc_default))
     (Tcons (tptr (Tstruct _atom_int noattr)) Tnil) tvoid cc_default)) ::
 (_makelock, Gfun(Internal f_makelock)) ::
 (_freelock, Gfun(Internal f_freelock)) ::
 (_acquire, Gfun(Internal f_acquire)) ::
 (_release, Gfun(Internal f_release)) :: (_spawn, Gfun(Internal f_spawn)) ::
 (_exit_thread, Gfun(Internal f_exit_thread)) :: nil).

Definition public_idents : list ident :=
(_exit_thread :: _spawn :: _release :: _acquire :: _freelock :: _makelock ::
 _free_atomic :: _atom_CAS :: _atom_store :: _make_atomic :: _thrd_exit ::
 _thrd_create :: _exit :: ___builtin_debug :: ___builtin_write32_reversed ::
 ___builtin_write16_reversed :: ___builtin_read32_reversed ::
 ___builtin_read16_reversed :: ___builtin_fnmsub :: ___builtin_fnmadd ::
 ___builtin_fmsub :: ___builtin_fmadd :: ___builtin_fmin ::
 ___builtin_fmax :: ___builtin_expect :: ___builtin_unreachable ::
 ___builtin_va_end :: ___builtin_va_copy :: ___builtin_va_arg ::
 ___builtin_va_start :: ___builtin_membar :: ___builtin_annot_intval ::
 ___builtin_annot :: ___builtin_sel :: ___builtin_memcpy_aligned ::
 ___builtin_sqrt :: ___builtin_fsqrt :: ___builtin_fabsf ::
 ___builtin_fabs :: ___builtin_ctzll :: ___builtin_ctzl :: ___builtin_ctz ::
 ___builtin_clzll :: ___builtin_clzl :: ___builtin_clz ::
 ___builtin_bswap16 :: ___builtin_bswap32 :: ___builtin_bswap ::
 ___builtin_bswap64 :: ___compcert_i64_umulh :: ___compcert_i64_smulh ::
 ___compcert_i64_sar :: ___compcert_i64_shr :: ___compcert_i64_shl ::
 ___compcert_i64_umod :: ___compcert_i64_smod :: ___compcert_i64_udiv ::
 ___compcert_i64_sdiv :: ___compcert_i64_utof :: ___compcert_i64_stof ::
 ___compcert_i64_utod :: ___compcert_i64_stod :: ___compcert_i64_dtou ::
 ___compcert_i64_dtos :: ___compcert_va_composite ::
 ___compcert_va_float64 :: ___compcert_va_int64 :: ___compcert_va_int32 ::
 nil).

Definition prog : Clight.program :=
  mkprogram composites global_definitions public_idents _main Logic.I.


Require Import Bool.
Require Import List.

From sflib Require Import sflib.
From Paco Require Import paco.

From PromisingLib Require Import Basic.
Require Import Event.
From PromisingLib Require Import Language.
Require Import Time.
Require Import View.
Require Import Cell.
Require Import Memory.
Require Import TView.
Require Import Thread.
Require Import Configuration.
Require Import Progress.

Require Import SimPromises.
Require Import Compatibility.
Require Import SimThread.

Require Import Syntax.
Require Import Semantics.

Set Implicit Arguments.

Lemma read_read_tview
      loc1 ts1 released1 ord1
      loc2 ts2 released2 ord2
      tview0
      (WF0: TView.wf tview0)
      (WF1: View.opt_wf released1)
      (WF2: View.opt_wf released2):
  TView.le
    (TView.read_tview
       (TView.read_tview tview0 loc2 ts2 released2 ord2)
       loc1 ts1 released1 ord1)
    (TView.read_tview
       (TView.read_tview tview0 loc1 ts1 released1 ord1)
       loc2 ts2 released2 ord2).
Proof.
  econs; aggrtac;
    (try by apply WF0);
    (try by condtac; aggrtac).
Qed.

Lemma read_write_tview
      loc1 ts1 released1 ord1
      loc2 ts2 ord2
      tview0 sc0
      (WF0: TView.wf tview0)
      (WF1: View.opt_wf released1):
  TView.le
    (TView.read_tview
       (TView.write_tview tview0 sc0 loc2 ts2 ord2)
       loc1 ts1 released1 ord1)
    (TView.write_tview
       (TView.read_tview tview0 loc1 ts1 released1 ord1)
       sc0 loc2 ts2 ord2).
Proof.
  econs; aggrtac;
    (try by apply WF0);
    (try by condtac; aggrtac).
  repeat condtac; aggrtac; try apply WF0.
Qed.

Lemma read_read_fence_tview
      loc1 ts1 released1 ord1
      ord2
      tview0
      (WF0: TView.wf tview0)
      (WF1: View.opt_wf released1):
  TView.le
    (TView.read_tview
       (TView.read_fence_tview tview0 ord2)
       loc1 ts1 released1 ord1)
    (TView.read_fence_tview
       (TView.read_tview tview0 loc1 ts1 released1 ord1)
       ord2).
Proof.
  econs; aggrtac;
    (try by apply WF0);
    (try by condtac; aggrtac).
  - repeat condtac; aggrtac; try apply WF0.
  - repeat condtac; aggrtac; try apply WF0.
  - repeat condtac; aggrtac; try apply WF0.
    destruct ord1; inv COND; inv COND1.
Qed.

Lemma read_write_fence_tview
      loc1 ts1 released1 ord1
      ord2
      tview0 sc0
      (WF0: TView.wf tview0)
      (WF1: View.opt_wf released1):
  TView.le
    (TView.read_tview
       (TView.write_fence_tview tview0 sc0 ord2)
       loc1 ts1 released1 ord1)
    (TView.write_fence_tview
       (TView.read_tview tview0 loc1 ts1 released1 ord1)
       sc0 ord2).
Proof.
  unfold TView.write_fence_tview, TView.write_fence_sc.
  econs; repeat (try condtac; aggrtac; try apply WF0).
Qed.

Lemma write_read_tview
      loc1 ts1 ord1
      loc2 ts2 released2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord1 Ordering.relaxed)
      (WF0: TView.wf tview0)
      (WF2: View.opt_wf released2):
  TView.le
    (TView.write_tview
       (TView.read_tview tview0 loc2 ts2 released2 ord2)
       sc0 loc1 ts1 ord1)
    (TView.read_tview
       (TView.write_tview tview0 sc0 loc1 ts1 ord1)
       loc2 ts2 released2 ord2).
Proof.
  econs; aggrtac;
    (try by apply WF0);
    (try by condtac; aggrtac).
  condtac; aggrtac. condtac.
  - destruct ord1; inv ORD1; inv COND0.
  - aggrtac; try apply WF0.
Qed.

Lemma write_write_tview
      loc1 ts1 ord1
      loc2 ts2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord1 Ordering.relaxed)
      (WF0: TView.wf tview0):
  TView.le
    (TView.write_tview
       (TView.write_tview tview0 sc0 loc2 ts2 ord2)
       sc0 loc1 ts1 ord1)
    (TView.write_tview
       (TView.write_tview tview0 sc0 loc1 ts1 ord1)
       sc0 loc2 ts2 ord2).
Proof.
  econs; repeat (try condtac; aggrtac).
  all: try by apply WF0.
Qed.

Lemma write_read_fence_tview
      loc1 ts1 ord1
      ord2
      tview0 sc0
      (ORD2: Ordering.le ord2 Ordering.relaxed)
      (WF0: TView.wf tview0):
  TView.le
    (TView.write_tview
       (TView.read_fence_tview tview0 ord2)
       sc0 loc1 ts1 ord1)
    (TView.read_fence_tview
       (TView.write_tview tview0 sc0 loc1 ts1 ord1)
       ord2).
Proof.
  econs; repeat (try condtac; aggrtac; try apply WF0).
Qed.

Lemma write_write_fence_tview
      loc1 ts1 ord1
      ord2
      tview0 sc0
      (ORD2: Ordering.le ord2 Ordering.acqrel)
      (WF0: TView.wf tview0):
  TView.le
    (TView.write_tview
       (TView.write_fence_tview tview0 sc0 ord2)
       (TView.write_fence_sc tview0 sc0 ord2)
       loc1 ts1 ord1)
    (TView.write_fence_tview
       (TView.write_tview tview0 sc0 loc1 ts1 ord1)
       sc0 ord2).
Proof.
  unfold TView.write_fence_tview, TView.write_fence_sc.
  econs; repeat (try condtac; aggrtac; try apply WF0).
Qed.

Lemma read_fence_read_tview
      ord1
      loc2 ts2 released2 ord2
      tview0
      (ORD2: Ordering.le ord2 Ordering.plain \/ Ordering.le Ordering.acqrel ord2)
      (WF0: TView.wf tview0):
  TView.le
    (TView.read_fence_tview
       (TView.read_tview tview0 loc2 ts2 released2 ord2)
       ord1)
    (TView.read_tview
       (TView.read_fence_tview tview0 ord1)
       loc2 ts2 released2 ord2).
Proof.
  econs; repeat (try condtac; aggrtac; try apply WF0).
  des; [|congr]. destruct ord2; inv ORD2; inv COND0.
Qed.

Lemma read_fence_write_tview
      ord1
      loc2 ts2 ord2
      tview0 sc0
      (WF0: TView.wf tview0):
  TView.le
    (TView.read_fence_tview
       (TView.write_tview tview0 sc0 loc2 ts2 ord2)
       ord1)
    (TView.write_tview
       (TView.read_fence_tview tview0 ord1)
       sc0 loc2 ts2 ord2).
Proof.
  econs; repeat (try condtac; aggrtac; try apply WF0).
Qed.

Lemma write_fence_read_tview
      ord1
      loc2 ts2 released2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord1 Ordering.relaxed)
      (WF0: TView.wf tview0)
      (WF2: View.opt_wf released2):
  TView.le
    (TView.write_fence_tview
       (TView.read_tview tview0 loc2 ts2 released2 ord2) sc0 ord1)
    (TView.read_tview
       (TView.write_fence_tview tview0 sc0 ord1)
       loc2 ts2 released2 ord2).
Proof.
  econs; aggrtac;
    (try by apply WF0);
    (repeat (condtac; aggrtac; try apply WF0)).
Qed.

Lemma write_fence_read_sc
      ord1
      loc2 ts2 released2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord1 Ordering.relaxed)
      (WF0: TView.wf tview0):
  TimeMap.le
    (TView.write_fence_sc
       (TView.read_tview tview0 loc2 ts2 released2 ord2) sc0 ord1)
    (TView.write_fence_sc tview0 sc0 ord1).
Proof.
  ii. unfold TView.write_fence_sc.
  repeat condtac; aggrtac.
Qed.

Lemma write_fence_write_tview
      ord1
      loc2 ts2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord1 Ordering.relaxed)
      (WF0: TView.wf tview0):
  TView.le
    (TView.write_fence_tview
       (TView.write_tview tview0 sc0 loc2 ts2 ord2)
       sc0 ord1)
    (TView.write_tview
       (TView.write_fence_tview tview0 sc0 ord1)
       sc0 loc2 ts2 ord2).
Proof.
  econs; aggrtac;
    (try by apply WF0);
    (repeat (condtac; aggrtac; try apply WF0)).
Qed.

Lemma write_fence_write_sc
      ord1
      loc2 ts2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord1 Ordering.relaxed)
      (WF0: TView.wf tview0):
  TimeMap.le
    (TView.write_fence_sc
       (TView.write_tview tview0 sc0 loc2 ts2 ord2)
       sc0 ord1)
    (TView.write_fence_sc tview0 sc0 ord1).
Proof.
  ii. unfold TView.write_fence_sc.
  repeat condtac; aggrtac.
Qed.

Lemma read_fence_write_fence_tview
      ord1
      ord2
      tview0 sc0
      (WF0: TView.wf tview0):
  TView.le
    (TView.read_fence_tview
       (TView.write_fence_tview tview0 sc0 ord2)
       ord1)
    (TView.write_fence_tview
       (TView.read_fence_tview tview0 ord1)
       sc0 ord2).
Proof.
  unfold TView.write_fence_tview, TView.write_fence_sc.
  econs; repeat (try condtac; aggrtac; try apply WF0).
  - rewrite <- TimeMap.join_r. apply WF0.
  - rewrite <- TimeMap.join_r. apply WF0.
  - rewrite <- TimeMap.join_r. apply WF0.
  - rewrite <- View.join_r. viewtac.
    rewrite <- TimeMap.join_r. apply WF0.
  - rewrite <- View.join_r. viewtac.
    rewrite <- TimeMap.join_r. apply WF0.
Qed.

Lemma read_write_tview_eq
      loc1 ts1 released1 ord1
      loc2 ts2 ord2
      tview0 sc0
      (ORD1: Ordering.le ord2 Ordering.relaxed)
      (WF0: TView.wf tview0)
      (WF1: View.opt_wf released1):
  (TView.read_tview
     (TView.write_tview tview0 sc0 loc2 ts2 ord2)
     loc1 ts1 released1 ord1) =
  (TView.write_tview
     (TView.read_tview tview0 loc1 ts1 released1 ord1)
     sc0 loc2 ts2 ord2).
Proof.
  apply TView.antisym.
  - apply read_write_tview; auto.
  - apply write_read_tview; auto.
Qed.