DmxLarchey / Kruskal-Trees

Coq library for rose trees
Mozilla Public License 2.0
1 stars 1 forks source link
(**************************************************************)
(*   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:

Data structures for lists, indices idx n and vectors vec X n:

Let us continue with the usual data-structures:

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:

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.