Exercise session 3 — Solutions

🏠 Go back to the course homepage.

From Stdlib Require Import List.
Import ListNotations.

Set Default Goal Selector "!".

EXERCISE

Prove the following statements using proof terms. If it's too hard to do directly, you can use the interactive mode together with the refine tactic.

ex1 is defined
ex2 is defined

We give you this type for "lower than" (lt).

lt is defined
lt_ind is defined
lt_sind is defined

EXERCISE

Prove the following lemma interactively using intros and apply.


forall n m : nat, lt n m -> lt n (4 + m)

forall n m : nat, lt n m -> lt n (4 + m)
n, m: nat
h: lt n m

lt n (4 + m)
n, m: nat
h: lt n m

lt n (S (S (S m)))
n, m: nat
h: lt n m

lt n (S (S m))
n, m: nat
h: lt n m

lt n (S m)
n, m: nat
h: lt n m

lt n m
apply h.
lt_plus_4 is defined

Note we make lt_S easier to use by making n, m implicit.

Arguments lt_S {n m}.

EXERCISE

Prove the following with a proof term.

lt_plus_4' is defined

EXERCISE

Prove the following with a proof term. Hint: Use Print "\/" if needed.

or_comm is defined

EXERCISE

Prove the following with a proof term.

ex3 is defined

We can also write it this way:

ex3_alt is defined

EXERCISE

If you have trouble with this one, try to use refine to fill the term interactively.

Russel is defined

Impredicative encodings

Thanks to impredicativity of Prop (the ability to quantify over propositions within propositions) it is possible to define most connectives using only forall and -> (no inductive definitions).

For instance, one can define False as follows:

iFalse is defined

EXERCISE

Show that iFalse is equivalent to False.


False <-> iFalse

False <-> iFalse

False -> iFalse

iFalse -> False

False -> iFalse
contradiction.

iFalse -> False
h: iFalse

False
apply h.
iFalse_iff is defined

EXERCISE

Define the impredicative encoding of True and show it equivalent to True.

iTrue is defined

True <-> iTrue

True <-> iTrue

True -> iTrue

iTrue -> True

True -> iTrue

iTrue
h: iFalse

iFalse
assumption.

iTrue -> True

True
constructor.
iTrue_iff is defined

EXERCISE

Now do the same thing for conjunction, disjunction and the existential quantifier.

If you look at the solution you should see that they are in a sense connected to the elimination rule of the corresponding connective. Note that you can get it basically by using Print and_ind.

For conjunction, the idea is that having a proof of A /\ B is that same as being able to prove any X as long as A -> B -> X holds, in other words as long as X is provable assuming A and B.

Another way of seeing it is that if you have h : iAnd P Q then apply h should be equivalent to destruct h' with h' : P /\ Q.

iAnd is defined

forall P Q : Prop, P /\ Q <-> iAnd P Q

forall P Q : Prop, P /\ Q <-> iAnd P Q
P, Q: Prop

P /\ Q <-> iAnd P Q
P, Q: Prop

P /\ Q -> iAnd P Q
P, Q: Prop
iAnd P Q -> P /\ Q
P, Q: Prop

P /\ Q -> iAnd P Q
P, Q: Prop
hP: P
hQ: Q

iAnd P Q
P, Q: Prop
hP: P
hQ: Q
X: Prop
h: P -> Q -> X

X
P, Q: Prop
hP: P
hQ: Q
X: Prop
h: P -> Q -> X

P
P, Q: Prop
hP: P
hQ: Q
X: Prop
h: P -> Q -> X
Q
all: assumption.
P, Q: Prop

iAnd P Q -> P /\ Q
P, Q: Prop
h: iAnd P Q

P /\ Q
P, Q: Prop
h: iAnd P Q

P -> Q -> P /\ Q
P, Q: Prop
h: iAnd P Q
hP: P
hQ: Q

P /\ Q
P, Q: Prop
h: iAnd P Q
hP: P
hQ: Q

P
P, Q: Prop
h: iAnd P Q
hP: P
hQ: Q
Q
all: assumption.
iAnd_iff is defined

For disjunction it's similar, but with two branches.

iOr is defined

forall P Q : Prop, P \/ Q <-> iOr P Q

forall P Q : Prop, P \/ Q <-> iOr P Q
P, Q: Prop

P \/ Q <-> iOr P Q
P, Q: Prop

P \/ Q -> iOr P Q
P, Q: Prop
iOr P Q -> P \/ Q
P, Q: Prop

P \/ Q -> iOr P Q
P, Q: Prop
h: P \/ Q
X: Prop
hP: P -> X
hQ: Q -> X

X
P, Q: Prop
H: P
X: Prop
hP: P -> X
hQ: Q -> X

X
P, Q: Prop
H: Q
X: Prop
hP: P -> X
hQ: Q -> X
X
P, Q: Prop
H: P
X: Prop
hP: P -> X
hQ: Q -> X

X
P, Q: Prop
H: P
X: Prop
hP: P -> X
hQ: Q -> X

P
assumption.
P, Q: Prop
H: Q
X: Prop
hP: P -> X
hQ: Q -> X

X
P, Q: Prop
H: Q
X: Prop
hP: P -> X
hQ: Q -> X

Q
assumption.
P, Q: Prop

iOr P Q -> P \/ Q
P, Q: Prop
h: iOr P Q

P \/ Q
P, Q: Prop
h: iOr P Q

P -> P \/ Q
P, Q: Prop
h: iOr P Q
Q -> P \/ Q
P, Q: Prop
h: iOr P Q

P -> P \/ Q
P, Q: Prop
h: iOr P Q
H: P

P \/ Q
P, Q: Prop
h: iOr P Q
H: P

P
assumption.
P, Q: Prop
h: iOr P Q

Q -> P \/ Q
P, Q: Prop
h: iOr P Q
H: Q

P \/ Q
P, Q: Prop
h: iOr P Q
H: Q

Q
assumption.
iOr_iff is defined
iEx is defined

forall (X : Type) (P : X -> Prop), (exists x : X, P x) <-> iEx X P

forall (X : Type) (P : X -> Prop), (exists x : X, P x) <-> iEx X P
X: Type
P: X -> Prop

(exists x : X, P x) <-> iEx X P
X: Type
P: X -> Prop

(exists x : X, P x) -> iEx X P
X: Type
P: X -> Prop
iEx X P -> exists x : X, P x
X: Type
P: X -> Prop

(exists x : X, P x) -> iEx X P
X: Type
P: X -> Prop
x: X
hx: P x
Y: Prop
h:= forall x: X, P x -> Y

Y
X: Type
P: X -> Prop
x: X
hx: P x
Y: Prop
h: Y

Y
assumption.
X: Type
P: X -> Prop

iEx X P -> exists x : X, P x
X: Type
P: X -> Prop
h: iEx X P

exists x : X, P x
X: Type
P: X -> Prop
h: iEx X P

forall x : X, P x -> exists x0 : X, P x0
X: Type
P: X -> Prop
h: iEx X P
x: X
hx: P x

exists x0 : X, P x0
X: Type
P: X -> Prop
h: iEx X P
x: X
hx: P x

P x
assumption.
iEx_iff is defined

Advanced exercises

Mutual inductive types

It is also possible to define several inductive types at the same time. You just combine them with the with keyword.

This way we can define the type of trees mutually with that of forests (which are basically lists of trees).

ntree, nforest are defined
ntree_rect is defined
ntree_ind is defined
ntree_rec is defined
ntree_sind is defined
nforest_rect is defined
nforest_ind is defined
nforest_rec is defined
nforest_sind is defined

You can then define mutual definitions over such types by using Fixpoint and the with keyword.

count is defined
count_list is defined
count, count_list are recursively defined (guarded respectively on 2nd, 2nd arguments)

EXERCISE

Define a map function for ntree. Hint: You probably will have to change Definition into something else. Answer: You need Fixpoint.

ntree_map is defined
nforest_map is defined
ntree_map, nforest_map are recursively defined (guarded respectively on 4th, 4th arguments)

Nested inductive types

Finally, you can define more inductive types by using what is called nesting. In the type below, you define a tree as something that contains a list of trees.

tree is defined
tree_rect is defined
tree_ind is defined
tree_rec is defined
tree_sind is defined

EXERCISE

Can you give an element of type tree?

ex4 is defined
All is defined
All_rect is defined
All_ind is defined
All_rec is defined
All_sind is defined
Arguments All_nil {X P}. Arguments All_cons {X P}.
tree_rect_strong is defined
tree_rect_strong is recursively defined (guarded on 3rd argument)

EXERCISE

  • Extend the type tree to have labelled nodes.

  • Prove a bijection between the new tree and ntree, ie. define functions to_tree : forall A, ntree A -> tree A from_tree : forall A, tree A -> ntree A and show that they invert each other.

For the solution, we will make a new tree type, called xtree for e``x``tended.

xtree is defined
xtree_rect is defined
xtree_ind is defined
xtree_rec is defined
xtree_sind is defined
to_tree is defined
to_tree_list is defined
to_tree, to_tree_list are recursively defined (guarded respectively on 2nd, 2nd arguments)
from_tree is defined
from_tree is recursively defined (guarded on 2nd argument)

We reprove the induction principle from above.

xtree_rect_strong is defined
xtree_rect_strong is recursively defined (guarded on 4th argument)

Then we can use it to prove one direction.


forall (A : Type) (t : xtree A), to_tree (from_tree t) = t

forall (A : Type) (t : xtree A), to_tree (from_tree t) = t
A: Type
t: xtree A

to_tree (from_tree t) = t
A: Type
a: A
ts: list (xtree A)
ih:= All (fun t: xtree A => to_tree (from_tree t) = t) ts

to_tree (from_tree (Nx A a ts)) = Nx A a ts
A: Type
a: A
ts: list (xtree A)
ih:= All (fun t: xtree A => to_tree (from_tree t) = t) ts

Nx A a (to_tree_list ((fix F (ts0 : list (xtree A)) : nforest A := match ts0 with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) ts)) = Nx A a ts
A: Type
a: A
ts: list (xtree A)
ih:= All (fun t: xtree A => to_tree (from_tree t) = t) ts

to_tree_list ((fix F (ts0 : list (xtree A)) : nforest A := match ts0 with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) ts) = ts
A: Type
a: A

to_tree_list (nnil A) = []
A: Type
a: A
t: xtree A
l: list (xtree A)
e: to_tree (from_tree t) = t
hl:= All (fun t: xtree A => to_tree (from_tree t) = t) l
ihl:= to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) l) = l
to_tree_list (ncons A (from_tree t) ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) l)) = t :: l
A: Type
a: A

to_tree_list (nnil A) = []
reflexivity.
A: Type
a: A
t: xtree A
l: list (xtree A)
e: to_tree (from_tree t) = t
hl:= All (fun t: xtree A => to_tree (from_tree t) = t) l
ihl:= to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) l) = l

to_tree_list (ncons A (from_tree t) ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) l)) = t :: l
A: Type
a: A
t: xtree A
l: list (xtree A)
e: to_tree (from_tree t) = t
hl:= All (fun t: xtree A => to_tree (from_tree t) = t) l
ihl:= to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) l) = l

to_tree (from_tree t) :: to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) l) = t :: l
A: Type
a: A
t: xtree A
l: list (xtree A)
e: to_tree (from_tree t) = t
hl:= All (fun t: xtree A => to_tree (from_tree t) = t) l
ihl:= to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) l) = l

t :: to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) l) = t :: l
A: Type
a: A
t: xtree A
l: list (xtree A)
e: to_tree (from_tree t) = t
hl:= All (fun t: xtree A => to_tree (from_tree t) = t) l
ihl:= to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l => ncons A (from_tree t) (F l) end) l) = l

to_tree_list ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) l) = l
apply ihl.
to_from_tree is defined

For the other direction, it's maybe more complicated.

We'll show you several ways. One is to use mutual fixed points like for when defining the function. When doing this interactively, we have to be careful that we indeed use the induction hypothesis only on strict subterms. Warning: Rocq will only check at Qed, not before. You can still ask if it's ok up to this point by using the Guarded command inside the proof.

For this, we also give a name to the fix nested in from_tree.

(*
Fixpoint from_tree_list {A} (l : list (xtree A)) :=
  match l with
  | [] => nnil _
  | t :: l => ncons _ (from_tree t) (from_tree_list l)
  end.
*)

from_tree_list is defined
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
t: ntree A

from_tree (to_tree t) = t
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
l: nforest A
from_tree_list (to_tree_list l) = l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
t: ntree A

from_tree (to_tree t) = t
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
l: nforest A
from_tree_list (to_tree_list l) = l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
t: ntree A

from_tree (to_tree t) = t
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: A
l: nforest A

from_tree (to_tree (nnode A a l)) = nnode A a l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: A
l: nforest A

nnode A a ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l0 => ncons A (from_tree t) (F l0) end) (to_tree_list l)) = nnode A a l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: A
l: nforest A

(fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t :: l0 => ncons A (from_tree t) (F l0) end) (to_tree_list l) = l
apply from_to_tree_list.
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
l: nforest A

from_tree_list (to_tree_list l) = l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type

from_tree_list (to_tree_list (nnil A)) = nnil A
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: ntree A
l: nforest A
from_tree_list (to_tree_list (ncons A a l)) = ncons A a l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type

from_tree_list (to_tree_list (nnil A)) = nnil A
reflexivity.
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: ntree A
l: nforest A

from_tree_list (to_tree_list (ncons A a l)) = ncons A a l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: ntree A
l: nforest A

ncons A (from_tree (to_tree a)) (from_tree_list (to_tree_list l)) = ncons A a l
from_to_tree:= forall (A : Type) (t: ntree A), from_tree (to_tree t) = t
from_to_tree_list:= forall (A : Type) (l: nforest A), from_tree_list (to_tree_list l) = l
A: Type
a: ntree A
l: nforest A

ncons A a l = ncons A a l
reflexivity.
from_to_tree is defined
from_to_tree_list is defined

Another option is to use Scheme which will derive better induction principles, working with mutual inductive types.

With them, no more fear of non-terminating fixed points.

ntree_nforest_rec is defined
nforest_ntree_rec is defined
ntree_nforest_rec, nforest_ntree_rec are recursively defined

forall (A : Type) (t : ntree A), from_tree (to_tree t) = t

forall (A : Type) (t : ntree A), from_tree (to_tree t) = t
A: Type
t: ntree A

from_tree (to_tree t) = t

Before we apply the induction principle, we tell Rocq to see the goal as a predicate over t with the pattern t tactic.

  
A: Type
t: ntree A

(fun n : ntree A => from_tree (to_tree n) = n) t

Now we need to give the predicate for forests:

  
A: Type
t: ntree A

forall (a : A) (n : nforest A), from_tree_list (to_tree_list n) = n -> from_tree (to_tree (nnode A a n)) = nnode A a n
A: Type
t: ntree A
from_tree_list (to_tree_list (nnil A)) = nnil A
A: Type
t: ntree A
forall n : ntree A, from_tree (to_tree n) = n -> forall n0 : nforest A, from_tree_list (to_tree_list n0) = n0 -> from_tree_list (to_tree_list (ncons A n n0)) = ncons A n n0
A: Type
t: ntree A

forall (a : A) (n : nforest A), from_tree_list (to_tree_list n) = n -> from_tree (to_tree (nnode A a n)) = nnode A a n
A: Type
t: ntree A
a: A
l: nforest A
ih: from_tree_list (to_tree_list l) = l

from_tree (to_tree (nnode A a l)) = nnode A a l
A: Type
t: ntree A
a: A
l: nforest A
ih: from_tree_list (to_tree_list l) = l

nnode A a ((fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) (to_tree_list l)) = nnode A a l
A: Type
t: ntree A
a: A
l: nforest A
ih: from_tree_list (to_tree_list l) = l

(fix F (ts : list (xtree A)) : nforest A := match ts with | [] => nnil A | t0 :: l0 => ncons A (from_tree t0) (F l0) end) (to_tree_list l) = l
apply ih.
A: Type
t: ntree A

from_tree_list (to_tree_list (nnil A)) = nnil A
reflexivity.
A: Type
t: ntree A

forall n : ntree A, from_tree (to_tree n) = n -> forall n0 : nforest A, from_tree_list (to_tree_list n0) = n0 -> from_tree_list (to_tree_list (ncons A n n0)) = ncons A n n0
A: Type
t, t': ntree A
iht: from_tree (to_tree t') = t'
l: nforest A
ihl: from_tree_list (to_tree_list l) = l

from_tree_list (to_tree_list (ncons A t' l)) = ncons A t' l
A: Type
t, t': ntree A
iht: from_tree (to_tree t') = t'
l: nforest A
ihl: from_tree_list (to_tree_list l) = l

ncons A (from_tree (to_tree t')) (from_tree_list (to_tree_list l)) = ncons A t' l
A: Type
t, t': ntree A
iht: from_tree (to_tree t') = t'
l: nforest A
ihl: from_tree_list (to_tree_list l) = l

ncons A t' l = ncons A t' l
reflexivity.
from_to_tree_alt is defined

Here is the Fibonnaci function.

Notice the as keyword to give a name to subexpression S n. This way Rocq knows that S n is a subterm of the one we started with.

fib is defined
fib is recursively defined (guarded on 1st argument)

EXERCISE

Define the Fibonnaci function fib using nat_rect directly.

The idea is to recursively produce a pair (fib (n-1), fib n) and then take the second projection snd.

fib_natrec is defined

EXERCISE

Define it using course-of-values recursion, a form of strong induction shown below. Of course you need to prove brec first.

below is defined
below is recursively defined (guarded on 2nd argument)
= (?P 4 * (?P 3 * (?P 2 * (?P 1 * (?P 0 * unit)))))%type : Type where ?P : [ |- nat -> Type]
brec' is defined
brec' is recursively defined (guarded on 3rd argument)
brec is defined
fib_brec is defined

Inconsistencies

There are three crucial potential breaking points ofconsistency of type theory:

  • termination of recursive functions, which needs to be ensured

  • strict positivity of inductives, which you have seen in the lecture

  • having type hierarchies rather than a Type : Type rule

Unset Guard Checking.

EXERCISE

Define a function of type nat -> nat and use it to deduce False. Note that this is surprisingly tricky.

n: nat

n <> S n
n: nat

n <> S n

0 <> 1
n: nat
ih: n <> S n
S n <> S (S n)

0 <> 1
discriminate.
n: nat
ih: n <> S n

S n <> S (S n)
n: nat
ih: n <> S n
e: S n = S (S n)

False
n: nat
ih: n <> S n
e: S n = S (S n)
H0: n = S n

False
n: nat
ih: n <> S n
e: S n = S (S n)
H0: n = S n

n = S n
assumption.
S_neq is defined
idnat is defined
f is defined
f is recursively defined (guarded on 1st argument)

False

False

f 0 = S (f 0)
reflexivity.
Unnamed_thm is defined
Set Guard Checking. Unset Positivity Checking.

EXERCISE

Define an inductive type bad such that bad <-> ~ bad, use lemma Russel from above to derive a contradiction.

bad is defined

bad <-> ~ bad

bad <-> ~ bad

bad -> ~ bad

~ bad -> bad

bad -> ~ bad
h: bad
nh: bad -> False

False
contradiction.

~ bad -> bad
nh: ~ bad

bad
nh: ~ bad

bad -> False
assumption.
bad_not_bad is defined

False

False
apply (Russel _ bad_not_bad).
Unnamed_thm0 is defined
Set Positivity Checking.

EXERCISE

We are going to prove a theorem allowing to prove False from Type : Type. Fill in the missing parts below.

Interactive Module Hierarchy started
embeds is defined
X: Type

embeds X X
X: Type

embeds X X
X: Type

forall x : X, x = x
reflexivity.
embeds_refl is defined
Tyi is defined
tree is defined
tree_rect is defined
tree_ind is defined
tree_rec is defined
tree_sind is defined
Arguments T { _ _}.
sub is defined
A: Tyi
D: A -> Tyi

forall s : tree A D, ~ sub s s
A: Tyi
D: A -> Tyi

forall s : tree A D, ~ sub s s
A: Tyi
D: A -> Tyi
a: A
f: D a -> tree A D
ih:= forall d: D a, ~ sub (f d) (f d)

~ sub (T a f) (T a f)
A: Tyi
D: A -> Tyi
a: A
f: D a -> tree A D
ih:= forall d: D a, ~ sub (f d) (f d)
x: D a
e: f x = T a f

False
A: Tyi
D: A -> Tyi
a: A
f: D a -> tree A D
ih:= forall d: D a, ~ sub (f d) (f d)
x: D a
e: f x = T a f

sub (f x) (f x)
A: Tyi
D: A -> Tyi
a: A
f: D a -> tree A D
ih:= forall d: D a, ~ sub (f d) (f d)
x: D a
e: f x = T a f

sub (f x) (T a f)
A: Tyi
D: A -> Tyi
a: A
f: D a -> tree A D
ih:= forall d: D a, ~ sub (f d) (f d)
x: D a
e: f x = T a f

exists x0 : D a, f x0 = f x
A: Tyi
D: A -> Tyi
a: A
f: D a -> tree A D
ih:= forall d: D a, ~ sub (f d) (f d)
x: D a
e: f x = T a f

f x = f x
reflexivity.
sub_irrefl is defined
A: Type
D: A -> Tyi
E: Tyi -> A

~ embeds (tree A D) (D (E (tree A D)))
A: Type
D: A -> Tyi
E: Tyi -> A

~ embeds (tree A D) (D (E (tree A D)))
A: Type
D: A -> Tyi
E: Tyi -> A
F: tree A D -> D (E (tree A D))
G: D (E (tree A D)) -> tree A D
h:= forall x: tree A D, G (F x) = x

False
A: Type
D: A -> Tyi
E: Tyi -> A
F: tree A D -> D (E (tree A D))
G: D (E (tree A D)) -> tree A D
h:= forall x: tree A D, G (F x) = x

sub (T (E (tree A D)) G) (T (E (tree A D)) G)
A: Type
D: A -> Tyi
E: Tyi -> A
F: tree A D -> D (E (tree A D))
G: D (E (tree A D)) -> tree A D
h:= forall x: tree A D, G (F x) = x

exists x : D (E (tree A D)), G x = T (E (tree A D)) G
A: Type
D: A -> Tyi
E: Tyi -> A
F: tree A D -> D (E (tree A D))
G: D (E (tree A D)) -> tree A D
h:= forall x: tree A D, G (F x) = x

G (F (T (E (tree A D)) G)) = T (E (tree A D)) G
apply h.
hier is defined

forall X : Tyi, ~ embeds Tyi X

forall X : Tyi, ~ embeds Tyi X
X: Tyi
E: Tyi -> X
D: X -> Tyi
h:= forall x: Tyi, D (E x) = x

False
X: Tyi
E: Tyi -> X
D: X -> Tyi
h:= forall x: Tyi, D (E x) = x

embeds (tree X D) (D (E (tree X D)))
X: Tyi
E: Tyi -> X
D: X -> Tyi
h:= forall x: Tyi, D (E x) = x

embeds (tree X D) (tree X D)
apply embeds_refl.
hierarchy is defined

We now enable the Type : Type rule.

  Unset Universe Checking.

  

False

False

embeds Tyi Tyi
apply embeds_refl.
inconsistent is defined
Module Hierarchy is defined