Module SimpleArith3.
Admitted.
End SimpleArith3.
Inductive value : tm -> Prop :=
| v_const : forall n, value (C n).
Instance dec_value t : Dec (value t).
constructor; unfold decidable.
destruct t.
- left; constructor; auto.
- right=> contra. inversion contra.
Defined.
Derive ArbitrarySizedSuchThat for (fun t => value t).
Reserved Notation " t '===>' t' " (at level 40).
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 v1 t2 t2',
value v1 ->                     (* <----- n.b. *)
t2 ===> t2' ->
P v1 t2 ===> P v1 t2'
where " t '===>' t' " := (step t t').
Admitted. (* OUT-OF-SCOPE *)
(* xistential rework - dummy step *)
Definition step_fun (t : tm) : option tm := Some t.
Instance dec_step (t : tm) : Dec (exists t', step t t') :=
{| dec := _ |}.
Definition normal_form {X:Type} (R:relation X) (t:X) : Prop :=
~ exists t', R t t'.
Admitted. (* QuickChick value_is_nf. *) (* Existential *)
Admitted. (* OUT-OF-SCOPE *)
(* Temp1,2,3,4 identical *)
Inductive multi {X:Type} (R: relation X) : relation X :=
| multi_refl  : forall (x : X), multi R x x
| multi_step : forall (x y z : X),
R x y ->
multi R y z ->
multi R x z.
Notation " t '===>*' t' " := (multi step t t') (at level 40).
Admitted. (* OUT-OF-SCOPE *)
Admitted. (* Existential *)
Definition step_normal_form := normal_form step.
Definition normal_form_of (t t' : tm) :=
(t ===>* t' /\ step_normal_form t').
(** We have already seen that, for our language, single-step reduction is deterministic -- i.e., a given term can take a single step in at most one way.  It follows from this that, if [t] can reach a normal form, then this normal form is unique.  In other words, we can actually pronounce [normal_form t t'] as "[t'] is _the_ normal form of [t]." *)
Admitted. (* Higher Order *)
Definition normalizing {X:Type} (R:relation X) :=
forall t, exists t',
(multi R) t t' /\ normal_form R t'.

Lemma multistep_congr_1 : forall t1 t1' t2,
t1 ===>* t1' ->
P t1 t2 ===>* P t1' t2.