Admitted. (* QuickChick step_deterministic. *)
Inductive typ : Type :=
| TBool : typ
| TNat : typ.
Derive (Arbitrary, Show) for typ.
Derive (Sized, CanonicalSized) for typ.
Derive SizeMonotonic for typ using genStyp.
Derive SizedMonotonic for typ.
Derive SizedCorrect for typ using genStyp and SizeMonotonictyp.
Reserved Notation "'|-' t '\typ' T" (at level 40).
Inductive has_type : tm -> typ -> Prop :=
| T_True :
|- ttrue \typ TBool
| T_False :
|- tfalse \typ TBool
| T_If : forall t1 t2 t3 T,
|- t1 \typ TBool ->
|- t2 \typ T ->
|- t3 \typ T ->
|- tif t1 t2 t3 \typ T
| T_Zero :
|- tzero \typ TNat
| T_Succ : forall t1,
|- t1 \typ TNat ->
|- tsucc t1 \typ TNat
| T_Pred : forall t1,
|- t1 \typ TNat ->
|- tpred t1 \typ TNat
| T_Iszero : forall t1,
|- t1 \typ TNat ->
|- tiszero t1 \typ TBool
where "'|-' t '\typ' T" := (has_type t T).
Hint Constructors has_type.
Derive ArbitrarySizedSuchThat for (fun t => has_type t T).
Derive SizeMonotonicSuchThatOpt for (fun t => has_type t T).
Derive GenSizedSuchThatSizeMonotonicOpt for (fun t => has_type t T).
(* KNOWN DUG. The derivation of SizedProofEqs for has_type fails with type error. *)
(* Probably needs a type annotation somewhere to convince the typechecker *)
(* Derive SizedProofEqs for (fun t => has_type t T). Derive GenSizedSuchThatCorrect for (fun t => has_type t T). *)
(* Admitting such that the following work *)
Instance has_type_gen_correct T : SuchThatCorrect (fun t => has_type t T)
(@arbitraryST _ (fun t => has_type t T) _).
Admitted.
Instance dec_has_type (t : tm) (T : typ) : Dec (has_type t T).
constructor; unfold decidable.
move: T; induction t => T; destruct T; eauto;
try solve [right => contra; inversion contra; eauto].
- destruct (IHt1 TBool).
+ destruct (IHt2 TBool); destruct (IHt3 TBool); eauto;
right => contra; inversion contra; eauto.
+ right => contra; inversion contra; eauto.
- destruct (IHt1 TBool).
+ destruct (IHt2 TNat); destruct (IHt3 TNat); eauto;
right => contra; inversion contra; eauto.
+ right => contra; inversion contra; eauto.
- destruct (IHt TNat); eauto.
right => contra; inversion contra; eauto.
- destruct (IHt TNat); eauto.
right => contra; inversion contra; eauto.
- destruct (IHt TNat); eauto.
right => contra; inversion contra; eauto.
Defined.

(* Specifications: *)
Lemma bool_canonical : forall t,
|- t \typ TBool -> value t -> bvalue t.