(* QuickChick Prelude *)
Set Warnings "-extraction-opaque-accessed,-extraction".
Set Warnings "-notation-overridden,-parsing".
Set Bullet Behavior "Strict Subproofs".
(* End prelude *)
(** * Smallstep: Small-step Operational Semantics *)
Inductive tm : Type :=
| C : nat -> tm         (* Constant *)
| P : tm -> tm -> tm.   (* Plus *)
Derive (Arbitrary, Show) for tm.
Fixpoint evalF (t : tm) : nat :=
match t with
| C n => n
| P a1 a2 => evalF a1 + evalF a2
end.
Reserved Notation " t '\\' n " (at level 50, left associativity).
Inductive eval : tm -> nat -> Prop :=
| E_Const : forall n,
C n \\ n
| E_Plus : forall t1 t2 n1 n2,
t1 \\ n1 ->
t2 \\ n2 ->
P t1 t2 \\ (n1 + n2)
where " t '\\' n " := (eval t n).
Module SimpleArith1.
Reserved Notation " t '===>' t' " (at level 55).
Inductive step : tm -> tm -> Prop :=
| ST_PlusConstConst : forall n1 n2,
P (C n1) (C n2) ===> C (n1 + n2)
| ST_Plus1 : forall t1 t1' t2,
t1 ===> t1' ->
P t1 t2 ===> P t1' t2
| ST_Plus2 : forall n1 t2 t2',
t2 ===> t2' ->
P (C n1) t2 ===> P (C n1) t2'
where " t '===>' t' " := (step t t').
End SimpleArith1.
Definition relation (X: Type) := X->X->Prop.
Definition deterministic {X: Type} (R: relation X) :=
forall x y1 y2 : X, R x y1 -> R x y2 -> y1 = y2.
Module SimpleArith2.

(* Specifications: *)
Theorem step_deterministic:
deterministic step.