Awesome
(**************************************************************)
(* Copyright Dominique Larchey-Wendling [*] *)
(* *)
(* [*] Affiliation LORIA -- CNRS *)
(**************************************************************)
(* This file is distributed under the terms of the *)
(* Mozilla Public License Version 2.0, MPL-2.0 *)
(**************************************************************)
What is this library?
This library formalizes in Coq 8.14+
the notion of rose tree
via purely inductive characterizations and provides implementations of
proper (nested) induction principles and tools to manipulate those
trees.
It is was extracted from a complete rework of the proof of Kruskal's tree theorem based on dependent vectors instead of lists, but can be used independently under the Mozilla Public License MPL-2.0, as initially requested by eg @jjhugues.
This README
file provides a simple introduction to the main definitions.
Overview of the definitions
Some remarks about notations below:
- implicit parameters are denoted between
{...}
as in Coq (eg{X : Type}
) and we do not specify them afterwards except when terms are preceded with an@
which locally disables implicit parameters. Eg we can write@In X x l
orIn x l
orx ∊ l
-- they are the same, -- provided the type ofx
is guessablyX
, or the type ofl
is guessablylist X
; - we write
_
for arguments that Coq can guess by unification from other arguments, eg@In _ x l
is the same asIn x l
, andvec _ n
gives the length of vectors without giving the base type.
Data structures for lists, indices idx n
and vectors vec X n
:
Let us continue with the usual data-structures:
- type of natural numbers
nat
; - type of lists
list X
over base typeX : Type
; - type of indices
idx n
from[0,n[
(identical toFin.t
); - dependent (uniform) vectors
vec X n
withX : Type
andn : nat
(identical toVector.t
); - access to components of vectors via
v⦃i⦄
withv : vec _ n
andi : idx n
.
Inductive nat : Type :=
| O : nat
| S : nat → nat.
(* Decimal notations 0, 1, 2, ... are accepted *)
Inductive list (X : Type) : Type :=
| nil : list X
| cons : X → list X → list X
where "[]" := (@nil _)
and "x :: l" := (@cons _ x l).
Fixpoint In {X} (x : X) (l : list X) : Prop :=
match l with
| [] ⇒ False
| y::l ⇒ y = x ⋁ x ∊ l
end
where "x ∊ l" := (@In _ x l).
Inductive idx n : Type :=
| idx_fst : idx (S n)
| idx_nxt : idx n → idx (S n)
where "𝕆" := idx_fst
and "𝕊" := idx_nxt.
Inductive vec X : nat → Type :=
| vec_nil : vec X 0
| vec_cons : ∀n, X → vec X n → vec X (S n).
where "∅" := vec_nil.
and "x ## v" := (@vec_cons _ x v).
Fixpoint vec_prj X n (v : vec X n) : idx n → X :=
match v with
... (* a bit complicated but critical piece of code *)
end
where "v⦃i⦄" := (@vec_prj _ _ v i).
(* Verifies the below fixpoint equations by *reduction*)
Goal (x##_)⦃𝕆⦄ = x.
Goal (_##v)⦃𝕊 p⦄ = v⦃p⦄.
Data structure for trees
Now we come to variations arround rose trees (finitely branching finite trees),
ie direct sub-trees are collected in list
or vec _ n
:
- uniform trees
ltree X
as lists of trees with nodes of typeX : Type
; - dependent trees
dtree X
where each arityn
as nodes of typeX n : Type
; - dependent uniform trees
vtree X
as vectors of trees with nodes of typeX : Type
; - undecorated trees
btree k
with branching bounded byk : nat
; - undecorated finitely branching trees
rtree
as lists of trees.
Inductive ltree (X : Type) : Type :=
| in_ltree : X → list (ltree X) → ltree X
where "⟨x|l⟩ₗ" := (@in_ltree _ x l).
Inductive dtree (X : nat → Type) : Type :=
| in_dtree k : X k → vec (dtree X) k → dtree X
where "⟨x|v⟩" := (@in_dtree _ _ x v).
Notation "vtree X" := (dtree (λ _, X)).
Inductive btree k := btree_cons n : vec btree n → n < k → btree.
Inductive rtree := rt : list rtree -> rtree.
The critical tools and inductions principles, ie ltree_rect
, dtree_rect
, vtree_rect
, btree_rect
and rtree_rect
.
Notice that the arity/breadth can be bounded at k : nat
in dtree X
by forcing X n
to be an
void
type for n ≥ k
, ie a type without inhabitants; this is a requirement in eg Higman's theorem.