Module Total <: FORWARD.
Inductive forward'
{state: Type}
{state_R: Relation state}:
MetaState state -> MetaState state -> Prop :=
| forward_Error:
forward' Error Error
| forward_NonTerminating:
forward' NonTerminating NonTerminating
| forward_Terminating:
forall x y, x <= y -> forward' (Terminating x) (Terminating y).
Definition forward {state: Type} {state_R: Relation state} := forward'.
End Total.
Inductive lift_relation {state: Type} (R: state -> MetaState state -> Prop):
MetaState state-> MetaState state -> Prop :=
| lift_relation_Error:
lift_relation R Error Error
| lift_relation_NonTerminating:
lift_relation R NonTerminating NonTerminating
| lift_relation_Terminating:
forall s ms, R s ms -> lift_relation R (Terminating s) ms.
Definition lift_Krelation {state: Type} {state_R: Relation state}: MetaState state -> MetaState state -> Prop := Total.forward.
Inductive lift_join
{state: Type}
{J_state: Join state}:
MetaState state -> MetaState state -> MetaState state -> Prop :=
| lift_join_Error1:
forall mx my, lift_join Error mx my
| lift_join_Error2:
forall mx my, lift_join mx Error my
| lift_join_NonTerminating1:
forall x, lift_join NonTerminating (Terminating x) NonTerminating
| lift_join_NonTerminating2:
forall x, lift_join (Terminating x) NonTerminating NonTerminating
| lift_join_NonTerminating3:
lift_join NonTerminating NonTerminating NonTerminating
| lift_join_Terminating:
forall x y z,
join x y z ->
lift_join (Terminating x) (Terminating y) (Terminating z).
Inductive strong_lift_join
{state: Type}
{J_state: Join state}:
MetaState state -> MetaState state -> MetaState state -> Prop :=
| strong_lift_join_Error1:
forall mx, strong_lift_join Error mx Error
| strong_lift_join_Error2:
forall mx, strong_lift_join mx Error Error
| strong_lift_join_NonTerminating1:
forall x, strong_lift_join NonTerminating (Terminating x) NonTerminating
| strong_lift_join_NonTerminating2:
forall x, strong_lift_join (Terminating x) NonTerminating NonTerminating
| strong_lift_join_NonTerminating3:
strong_lift_join NonTerminating NonTerminating NonTerminating
| strong_lift_join_Terminating:
forall x y z,
join x y z ->
strong_lift_join (Terminating x) (Terminating y) (Terminating z).
Definition lift_function {A B: Type} (f: A -> B): MetaState A -> MetaState B :=
fun ma =>
match ma with
| NonTerminating => NonTerminating
| Error => Error
| Terminating a => Terminating (f a)
end.
(* Instance MetaState_SA (state: Type) {SA: SeparationAlgebra state}: SeparationAlgebra (MetaState state). *)

Lemma lift_function_rev {A B: Type} (f: A -> B):
forall ma mb, lift_function f ma = mb ->
match mb with
| NonTerminating => ma = NonTerminating
| Error => ma = Error
| _ => True
end.