Library ProgramAssertions

Instructions and structures representing programs.
@author Patryk Czarnik

Require Import Common.
Require Import ValuesNTypes.
Require Import ProgramStructures.
Require Import Program.
Require Import RuntimeStructures.
Require Import Sem_Frame.
Require Import Relations.

Program assertions

Module Type PROGRAM_ASSERTIONS.

Included modules

  Declare Module M_Sem_Frame : SEM_FRAME.

  Import M_Sem_Frame.
  Import M_AllStructures.
  Import M_Program.M_ProgramStructures.M_ValuesAndTypes.
  Import M_Program.M_ProgramStructures.
  Import M_Program.
  Import M_RuntimeStructures.

  Open Local Scope type_scope.

Frame-level assertions

An assertion is a property of a state, here a frame.
  Definition TCodeAssertion := TFrameProp.

A set of annotations assigned to instructions (or rather "places") within a method body.
  Parameter TCodeAssertions: Type.

Returns assertion assigned to a given position in method body, if any.
Returns assertion from a given position enriched with a statement that the given position is the current point of execution.
  Definition getPositionedAssertion (asserts: TCodeAssertions) (pc: TPC) : TCodeAssertion :=
    fun frame
    match getCodeAssertion asserts pc with
    | NoneFalse
    | Some assertframeGetPC frame = pc (assert frame)
    end.

A method body is "described" if assertions are specified for (positions of) all instructions.
  Definition codeDescribed (code: TCode) (asserts: TCodeAssertions) :=
     pc,
      ( instr, getInstruction code pc = Some instr)
        
      ( assert, getCodeAssertion asserts pc = Some assert).

Helper lemma about getPositionedAssertion.
  Lemma positionedAssertionPc: asserts pc frame,
    getPositionedAssertion asserts pc frame
    frameGetPC frame = pc.
  Proof.
    intros.
    unfold getPositionedAssertion in H.
    destruct (getCodeAssertion asserts pc); tauto.
  Qed.

A given state (at frame level) is described by (at least) one of assertions.
  Definition frameDescribed (asserts: TCodeAssertions) (frame: TFrame) :=
     pc,
    getPositionedAssertion asserts pc frame.

A given state (at frame level) is described by the assertion corresponding to the position pointed by the state.
  Definition frameDescribed2 (asserts: TCodeAssertions) (frame: TFrame) :=
    getPositionedAssertion asserts (frameGetPC frame) frame.

The two formulations of "being described" are equivalent.
  Lemma frameDescribed_equiv: asserts frame,
    frameDescribed asserts frame frameDescribed2 asserts frame.
  Proof.
    unfold frameDescribed, frameDescribed2.
    intros.
    split.
    intros.
    destruct H as [pc H].
    replace pc with (frameGetPC frame) in ×.
    assumption.
    eapply positionedAssertionPc.
    eassumption.

    intros.
     (frameGetPC frame).
    assumption.
  Qed.

Logic to prove partial correctness

A property expressing that a given set of assertions is sound wrt a given method body:
Any step from any described state yields to a state which is also described.
  Definition singleTransitions (code: TCode) (asserts: TCodeAssertions) :=
     frame1 frame2,
      frameDescribed asserts frame1
      stepFrame code frame1 frame2
      frameDescribed asserts frame2.

If a method is properly specified (in the sense of singleTransitions, than any reachable state is "proper" (described by an appropriate assertion).
  Theorem multiTransitions: code asserts frame1 frame2,
    singleTransitions code asserts
    frameDescribed asserts frame1
    stepsFrame code frame1 frame2
    frameDescribed asserts frame2.
  Proof.
    intros code asserts frame1 frame2 HSingleTrans HFrame1 HSteps.
    apply clos_rt_rtn1 in HSteps.
    induction HSteps.
    apply HFrame1.

    eapply HSingleTrans.
    apply IHHSteps.
    apply H.
  Qed.
End PROGRAM_ASSERTIONS.

Creating programs with assertions

Module of this type enables creating assertion sets from lists.
Module Type PROGRAM_ASSERTIONS_W_CONSTRUCTORS.
  Include PROGRAM_ASSERTIONS.
  Require Import List.
  Import M_Sem_Frame.
  Import M_AllStructures.
  Import M_Program.M_ProgramStructures.M_ValuesAndTypes.
  Import M_Program.M_ProgramStructures.
  Import M_Program.
  Import M_RuntimeStructures.

  Open Local Scope type_scope.

Creates a code block annotation containing the given assertions in the given order.
PC relates directly to the position of assertion on the list.
  Axiom PgetInstructionIffNth: li pc,
    getCodeAssertion (assertionsFromList li) pc =
    nth_error li (pcToPosition pc).

  Lemma frameDescribed_inRange: li frame,
    frameDescribed (assertionsFromList li) frame
    pcToPosition (frameGetPC frame) < length li.
  Proof.
    unfold frameDescribed.
    unfold getPositionedAssertion.
    intros.
    destruct H as [pc H].
    rewrite PgetInstructionIffNth in H.
    case_eq (nth_error li (pcToPosition pc)).
    intros a Heq.
    rewrite Heq in H.
    eapply Pnth_error_length.
    rewrite (proj1 H).
    eassumption.
    intros Heq.
    rewrite Heq in H.
    contradiction.
  Qed.
End PROGRAM_ASSERTIONS_W_CONSTRUCTORS.