(* QuickChick Prelude *)
Set Warnings "-extraction-opaque-accessed,-extraction".
Set Warnings "-notation-overridden,-parsing".
Set Bullet Behavior "Strict Subproofs".
(* End prelude *)
Inductive ty : Type :=
| TBool  : ty
| TArrow : ty -> ty -> ty.
Derive (Arbitrary, Show) for ty.
Derive (Sized, CanonicalSized) for ty.
Derive SizeMonotonic for ty using genSty.
Derive SizedMonotonic for ty.
Derive SizedCorrect for ty using genSty and SizeMonotonicty.
Instance eq_dec_ty (t1 t2 : ty) : Dec (t1 = t2).
constructor; unfold decidable; decide equality; auto. Defined.
Derive (Arbitrary, Show) for ascii.
Derive (Sized, CanonicalSized) for ascii.
Derive SizeMonotonic for ascii using genSascii.
Derive SizedMonotonic for ascii.
Derive SizedCorrect for ascii using genSascii and SizeMonotonicascii.
Derive (Arbitrary, Show) for string.
Derive (Sized, CanonicalSized) for string.
Derive SizeMonotonic for string using genSstring.
Derive SizedMonotonic for string.
Inductive id : Type :=
| Id : string -> id.
Derive (Arbitrary, Show) for id.
Derive (Sized, CanonicalSized) for id.
Derive SizeMonotonic for id using genSid.
Derive SizedMonotonic for id.
Derive SizedCorrect for id using genSid and SizeMonotonicid.
Instance eq_dec_id (x y : id) : Dec (x = y).
constructor; unfold decidable. repeat decide equality. Defined.
Definition beq_id x y :=
match x,y with
| Id n1, Id n2 => if string_dec n1 n2 then true else false
end.
Inductive trm : Type :=
| tvar : id -> trm
| tapp : trm -> trm -> trm
| tabs : id -> ty -> trm -> trm
| ttrue : trm
| tfalse : trm
| tif : trm -> trm -> trm -> trm.
Derive (Arbitrary, Show) for trm.
Derive (Sized, CanonicalSized) for trm.
Derive SizeMonotonic for trm using genStrm.
Derive SizedMonotonic for trm.
Derive SizedCorrect for trm using genStrm and SizeMonotonictrm.
Instance eq_dec_tm (t1 t2 : trm) : Dec (t1 = t2).
constructor; unfold decidable; repeat decide equality. Defined.
(* Leo: TODO: lowercase x - name clash *)
Inductive value : trm -> Prop :=
| v_abs : forall X T t,
value (tabs X T t)
| v_true :
value ttrue
| v_false :
value tfalse.
Derive ArbitrarySizedSuchThat for (fun tm => value tm).
Derive SizedProofEqs for (fun tm => value tm).
Derive SizeMonotonicSuchThatOpt for (fun tm => value tm).
Derive GenSizedSuchThatCorrect for (fun tm => value tm).
Derive GenSizedSuchThatSizeMonotonicOpt for (fun tm => value tm).
Instance dec_value t : Dec (value t).
constructor; unfold decidable; induction t;
try solve [left; constructor; auto];
try solve [right => contra; inversion contra; eauto].
Defined.
Hint Constructors value.
Reserved Notation "'[' x ':=' s ']' t" (at level 20).
Fixpoint subst (x:id) (s:trm) (t:trm) : trm :=
match t with
| tvar x' =>
if beq_id x x' then s else t
| tabs x' T t1 =>
tabs x' T (if beq_id x x' then t1 else ([x:=s] t1))
| tapp t1 t2 =>
tapp ([x:=s] t1) ([x:=s] t2)
| ttrue =>
ttrue
| tfalse =>
tfalse
| tif t1 t2 t3 =>
tif ([x:=s] t1) ([x:=s] t2) ([x:=s] t3)
end
where "'[' x ':=' s ']' t" := (subst x s t).
(* Inductive substi (s:trm) (x:id) : trm -> trm -> Prop := | s_var1 : substi s x (tvar x) s (* FILL IN HERE *)
.
Hint Constructors substi.

(* Specifications: *)
Theorem substi_correct : forall s x t t',
[x:=s]t = t' <-> substi s x t t'.