Library bf_logic

Require Import base.
Require Import prelim.
Require Import lts_tau.
Require Import branch_bisim.
Require Import back_forth_bisim.
Require Import logic.

Module BF_LOGIC.
Import LTS_TAU.
Import BRANCH_BISIM.
Import BF_BISIM.
Section bf_logic. Context {Obs:ObservationSystem}.

  Inductive bf_mode : Type :=
    | dia : option O -> bf_mode
    | dia_back : option O -> bf_mode
    | box : option O -> bf_mode
    | box_back : option O -> bf_mode.

  Definition interp_bf_mode (m:bf_mode) (P:history -> Prop) (w:history) : Prop :=
      match m with
        | dia o =>
            exists h, step_run (hsys w) (hrun w) o h /\ P {| hsys := hsys w; hrun := h |}
        | dia_back o =>
            exists h, step_run (hsys w) h o (hrun w) /\ P {| hsys := hsys w; hrun := h |}
        | box o =>
            forall h, step_run (hsys w) (hrun w) o h -> P {| hsys := hsys w; hrun := h |}
        | box_back o =>
            forall h, step_run (hsys w) h o (hrun w) -> P {| hsys := hsys w; hrun := h |}
      end.

  Program Instance BackForth_LogicInput : LOGIC_INPUT :=
  { world := history
  ; accessable := hist_equiv back_forth
  ; mode := bf_mode
  ; atom := Empty_set
  ; interp_mode := interp_bf_mode
  ; interp_atom a := match a with end
  }.

  Import MuCalc.

  Lemma proof_dual1 : forall ob (P Q:cformula o),
    entails P (modality _ _ o (box ob) Q) <->
    entails (modality _ _ o (dia_back ob) P) Q.

  Lemma proof_dual2 : forall ob (P Q:cformula o),
    entails P (modality _ _ o (box_back ob) Q) <->
    entails (modality _ _ o (dia ob) P) Q.

  Section characteristic.
    Variable X:LTS.
    Let E0 := emptyE.
    Let E1 := extend emptyE (arr (run X) o).

    Definition CF_body (h:run X) (ob:option O) : formula E0 E1 o :=
       f_and (conj' (fun x':{ h' | step_run X h ob h'} => modality E0 E1 o (dia ob) (app (var E0 E1 None) (proj1_sig x'))))
      (f_and (conj' (fun x':{ h' | step_run X h' ob h} => modality E0 E1 o (dia_back ob) (app (var E0 E1 None) (proj1_sig x'))))
      (f_and (modality E0 E1 o (box ob) (disj' (fun x':{ h' | step_run X h ob h'} => (app (var E0 E1 None) (proj1_sig x')))))
             (modality E0 E1 o (box_back ob) (disj' (fun x':{ h' | step_run X h' ob h} => (app (var E0 E1 None) (proj1_sig x')))))
      )).

    Definition CF_main : formula E0 E0 (arr (run X) o) :=
      nu E0 E0 (arr (run X) o)
        (lam E0 E1 (run X) o (fun h:run X =>
          (conj' (fun ob:option O => CF_body h ob))
        )).

    Lemma characteristic_self : forall s,
      interp_cformula _ CF_main (s,tt) (hst s).

    Lemma characteristic_other : forall s w,
      interp_cformula _ CF_main (s,tt) w ->
      accessable (hst s) w.

  End characteristic.

  Definition CF (w:world) : cformula o :=
    app (CF_main (hsys w)) (hrun w).

  Theorem CF_is_characteristic : characteristic_formula CF.

  Theorem completeness : forall w w',
    accessable w w' <->
    (forall t (f:formula emptyE emptyE t) z,
      interp_cformula t f z w <-> interp_cformula t f z w').

  Theorem models_denotable : forall t (X:model t), exists f:cformula t,
    interp_cformula t f = X.

End bf_logic.
End BF_LOGIC.