From Undecidability.L Require Export L Encodings Interpreter Choose.
(** * Results obtained with self-interpreters *)
(** ** Step-indexed self-interpreter *)
(** *** Encoding of options *)
Definition none : term := .\"s", "n"; "n".
Definition some : term := .\"t", "s", "n"; "s" "t".
Hint Unfold some none : cbv.
Definition oenc t :=
match t with
| Some t => lambda(lambda (1 (tenc t)))
| None => none
end.

(* Specifications: *)
Lemma oenc_cls s: closed (oenc s).
Lemma oenc_lambda s: lam (oenc s).
Hint Resolve oenc_cls oenc_lambda: cbv.
Lemma some_correct s : some (tenc s) ≡ oenc (Some s).
Lemma some_correct_r s t t' : proc t -> proc t' -> oenc (Some s) t t' ≡ t (tenc s).
Lemma none_correct s t : proc s -> proc t  -> none s t ≡ t.
Lemma oenc_correct_some s v : lam v -> oenc (Some s) ≡ some v -> v ≡ tenc s.
Lemma oenc_inj o1 o2 : oenc o1 ≡ oenc o2 -> o1 = o2.
Lemma none_equiv_some v : ~ oenc None ≡ some v.
Definition EqN := rho (.\"EqN", "n", "m"; "n" ("m" !T !(lambda F)) (.\"n"; "m" !F (.\"m"; "EqN" "n" "m"))).