Library liblayers.compat.CompatData

Require Import compcert.lib.Coqlib.
Require Import compcert.common.Memtype.
Require Import compcert.common.Globalenvs.
Require Import liblayers.logic.LayerData.
Require Import liblayers.compcertx.Stencil.
Require Import liblayers.compcertx.AbstractData.

Section WITH_MEMORY_MODEL.
Context `{Hmem: Mem.MemoryModel}.
Context `{Hstencil: Stencil}.

Abstract data and simulation relation blueprints


Class CompatDataOps data :=
  {
    empty_data : data;
    high_level_invariant: dataProp;
    low_level_invariant: blockdataProp;
    kernel_mode: dataProp
  }.

Class CompatData data `{data_ops: CompatDataOps data} :=
  {
    low_level_invariant_incr n d:
      (n )%positive
      low_level_invariant n d
      low_level_invariant d;
    empty_data_low_level_invariant:
       n, low_level_invariant n empty_data;
    empty_data_high_level_invariant:
      high_level_invariant empty_data
  }.

Although we do not need a memory model to define our CompatData, it is needed for LayerData, and so we include it here as well so that the coercion compatdata_layerdata can work properly.
Record compatdata {mem} `{mem_ops: !Mem.MemoryModelOps mem} :=
  {
    cdata_type : Type;
    cdata_ops : CompatDataOps cdata_type;
    cdata_prf : CompatData cdata_type
  }.

Global Existing Instance cdata_ops.
Global Existing Instance cdata_prf.

Definition cdata := Build_compatdata.
Global Arguments cdata {_ _} _ {_ _}.

Class CompatRelOps `{stencil_ops: StencilOps} (D1 D2: compatdata) :=
  {
    relate_AbData: stencilmeminjcdata_type D1cdata_type D2Prop;
    match_AbData: stencilcdata_type D1memmeminjProp;
    new_glbl: list AST.ident
  }.

Class CompatRel D1 D2 `{ops: !CompatRelOps D1 D2} :=
  {
    match_compose:
       s d1 m2 f m2´ j,
        match_AbData s d1 m2 f
        Mem.inject j m2 m2´
        inject_incr (Mem.flat_inj (genv_next s)) j
        match_AbData s d1 m2´ (compose_meminj f j);

    store_match_correct:
       s abd m0 m0´ f b2 v chunk,
        match_AbData s abd m0 f
        ( i b,
           In i new_glbl
           find_symbol s i = Some bb b2) →
        Mem.store chunk m0 b2 v = Some m0´
        match_AbData s abd m0´ f;

    alloc_match_correct:
       s abd m´0 m´1 f ofs sz b0 b´1,
        match_AbData s abd m´0 f
        Mem.alloc m´0 ofs sz = (m´1, b´1)
         b0 = Some (b´1, 0%Z)
        ( b : block, b b0 b = f b) →
        inject_incr f
        ( i b,
           In i new_glbl
           find_symbol s i = Some bb b0) →
        match_AbData s abd m´1 ;

    free_match_correct:
       s abd m0 m0´ f ofs sz b2,
        match_AbData s abd m0 f
        ( i b,
           In i new_glbl
           find_symbol s i = Some bb b2) →
        Mem.free m0 b2 ofs sz = Some m0´
        match_AbData s abd m0´ f;

    storebytes_match_correct:
       s abd m0 m0´ f b2 v ,
        match_AbData s abd m0 f
        ( i b,
           In i new_glbl
           find_symbol s i = Some bb b2) →
        Mem.storebytes m0 b2 v = Some m0´
        match_AbData s abd m0´ f;

    relate_incr:
       s abd abd´ f ,
        relate_AbData s f abd abd´
        inject_incr f
        relate_AbData s abd abd´
  }.

Class compatrel D1 D2 :=
  {
    crel_ops :> CompatRelOps D1 D2;
    crel_prf :> CompatRel D1 D2
  }.

Instance one_crel data1 data2
  `{CompatData data1}
  `{CompatData data2}
  `{!CompatRelOps (cdata data1) (cdata data2)}
  `{!CompatRel (cdata data1) (cdata data2)}:
  compatrel (cdata data1) (cdata data2) := {}.

Definition crel data1 data2
  `{CompatData data1}
  `{CompatData data2}
  `{!CompatRelOps (cdata data1) (cdata data2)}
  `{!CompatRel (cdata data1) (cdata data2)}:
  freerg compatrel (cdata data1) (cdata data2) :=
  freerg_inj _ _ _ (one_crel data1 data2).


Global Instance compat_rg: ReflexiveGraph compatdata (freerg compatrel).

Compatibility with the new framework


Instance compatdata_layerdata_ops data `{CompatDataOps data}:
  AbstractDataOps data :=
  {
    init_data := empty_data;
    data_inject ι d1 d2 := True;
    inv m d := high_level_invariant d low_level_invariant (Mem.nextblock m) d
  }.

Instance compatdata_layerdata_prf:
   data `{CompatDataOps data}, CompatData dataAbstractData data.
Proof.
  intros data data_ops Hdata; split.
  × split.
    apply empty_data_high_level_invariant.
    apply empty_data_low_level_invariant.
  × intros d.
    apply I.
  × intros ι ι´ d1 d2 d3 H12 H23.
    apply I.
  × intros ι1 ι2 d1 d2 Hd d1´ d2´ Hd´ H.
    apply I.
Qed.

Definition compatdata_layerdata (D: compatdata): layerdata :=
  {|
    ldata_type := cdata_type D
  |}.

End WITH_MEMORY_MODEL.

Coercion compatdata_layerdata : compatdata >-> layerdata.