Library hydras.Hydra.Hydra_Definitions
Pierre Casteran, LaBRI, University of Bordeaux
An hydra is a finitely branched tree. We use the auxiliary type Hydrae for
representing finite sequences of hydras.
Data types
From Coq Require Export Relations.
From hydras Require Import T1 Epsilon0.
From Coq Require Import List.
Import ListNotations.
Inductive Hydra : Set :=
| node : Hydrae → Hydra
with Hydrae : Set :=
| hnil : Hydrae
| hcons : Hydra → Hydrae → Hydrae.
Alternative representation (discarded)
Mutual induction scheme for types Hydra and Hydrae
Scheme Hydra_rect2 := Induction for Hydra Sort Type
with Hydrae_rect2 := Induction for Hydrae Sort Type.
Arguments Hydra_rect2 P P0 : rename.
Arguments Hydrae_rect2 P P0 : rename.
All elements of s satisfy P
Fixpoint h_forall (P: Hydra → Prop) (s: Hydrae) :=
match s with
| hnil ⇒ True
| hcons h s' ⇒ P h ∧ h_forall P s'
end.
Lemma h_eq_dec : ∀ h h':Hydra, {h = h'}+{h ≠ h'}
with hs_eq_dec : ∀ l l':Hydrae, {l = l'}+{l ≠ l'}.
match s with
| hnil ⇒ True
| hcons h s' ⇒ P h ∧ h_forall P s'
end.
Lemma h_eq_dec : ∀ h h':Hydra, {h = h'}+{h ≠ h'}
with hs_eq_dec : ∀ l l':Hydrae, {l = l'}+{l ≠ l'}.
For list usage
Fixpoint hs2l (s: Hydrae): list Hydra :=
match s with
hnil ⇒ []
| hcons h s' ⇒ h :: hs2l s'
end.
Fixpoint l2hs (l: list Hydra): Hydrae :=
match l with
[] ⇒ hnil
| h :: l' ⇒ hcons h (l2hs l')
end.
Lemma hs2lK (s: Hydrae) : l2hs (hs2l s) = s.
Lemma l2hsK (l: list Hydra) : hs2l (l2hs l) = l.
Number of nodes (a.k.a. size)
Fixpoint hsize (h:Hydra) : nat :=
match h with
| node l ⇒ S (lhsize l)
end
with lhsize l : nat :=
match l with
| hnil ⇒ 0
| hcons h hs ⇒ hsize h + lhsize hs
end.
Fixpoint height (h:Hydra) : nat :=
match h with
| node l ⇒ lheight l
end
with lheight l : nat :=
match l with
| hnil ⇒ 0
| hcons h hs ⇒ Nat.max (S (height h)) (lheight hs)
end.
Notation head := (node hnil).
Notation hyd1 h := (node (hcons h hnil)).
Notation hyd2 h h' := (node (hcons h (hcons h' hnil))).
Notation hyd3 h h' h'' := (node (hcons h (hcons h' (hcons h'' hnil)))).
Fixpoint hcons_mult (h:Hydra)(n:nat)(s:Hydrae):Hydrae :=
match n with
| O ⇒ s
| S p ⇒ hcons h (hcons_mult h p s)
end.
Fixpoint hy_app (s1 s2: Hydrae) : Hydrae :=
match s1 with
hnil ⇒ s2
| hcons h1 s1' ⇒ hcons h1 (hy_app s1' s2)
end.
Fixpoint add_head_r (s: Hydrae) :=
match s with
hnil ⇒ hcons head hnil
| hcons h s' ⇒ hcons h (add_head_r s')
end.
Fixpoint add_head_r_plus (s:Hydrae) (i:nat) :=
match i with
0 ⇒ s
| S j ⇒ add_head_r (add_head_r_plus s j)
end.
Hydra Battles
Relation associated with a single round.
- if h' is obtained from h by chopping off one head of height 1. This situation is described by the proposition R1 h h'.
- Or h' is obtained from h through a beheading at distance from the foot, with creation of n copies of some dub-hydra.
S0
Inductive S0 : relation Hydrae :=
| S0_first : ∀ s, S0 (hcons head s) s
| S0_rest : ∀ h s s', S0 s s' → S0 (hcons h s) (hcons h s').
R1
S1
Inductive S1 (n:nat) : relation Hydrae :=
| S1_first : ∀ s h h' ,
R1 h h' →
S1 n (hcons h s) (hcons_mult h' (S n) s)
| S1_next : ∀ h s s',
S1 n s s' →
S1 n (hcons h s) (hcons h s').
R2
Inductive R2 (n:nat) : relation Hydra :=
| R2_intro : ∀ s s', S1 n s s' → R2 n (node s) (node s')
| R2_intro_2 : ∀ s s', S2 n s s' → R2 n (node s) (node s')
with S2 (n:nat) : relation Hydrae :=
| S2_first : ∀ h h' s ,
R2 n h h'→ S2 n (hcons h s) (hcons h' s)
| S2_next : ∀ h r r',
S2 n r r' → S2 n (hcons h r) (hcons h r').
round_n
- if h' is obtained from h by removing one head of height 1 (and the factor n is irrelevant)
- or h' is obtained from h by removing one head of height greater or equal than 2, and this beheading was made with a relocation factor n.
Definition round_plus := clos_trans_1n Hydra round.
Definition round_star h h' := h = h' ∨ round_plus h h'.
Infix "-+->" := round_plus (at level 60).
Infix "-*->" := round_star (at level 60).
Ltac chop_off i :=
match goal with |- S0 ?h ?h' ⇒
match i with
| O ⇒ eapply S0_first
| S ?j ⇒ eapply S0_rest; chop_off j
end
| |- round ?h ?h' ⇒
∃ 0; left; split; chop_off i
| |- round_n ?n ?h ?h' ⇒
left ; split; chop_off i
end.
Calls the R2 relation
Ltac h_search_n n := match goal with
|- round ?h ?h' ⇒ ∃ n; eright
end.
Ltac h_search := match goal with
| |- round_n ?p ?h ?h' ⇒ eright
end.
Ltac s2_nth n :=
match n with
| 0 ⇒ eleft
| S ?p ⇒ eright ; s2_nth p
end.
Moves to the i-th daugther
Ltac r2_up i := match goal with
|- R2 ?n ?h ?h' ⇒ eright; s2_nth i
end.
Ltac S1_nth i :=
match goal with
|- S1 ?n ?h ?h' ⇒
match i with
| 0 ⇒ eleft
| S ?j ⇒ eright ; S1_nth j
end
end.
chops off a head which is the j-th daughter of the
i-th dauchter
End of the battle
Still fighting
Lemma round_star_intro h h'' : ∀ h',
h -1-> h' → h' -*-> h'' → h -*-> h''.
Ltac forward :=
match goal with
|- round_star ?h ?h' ⇒ eapply round_star_intro
end.
Inductive trace_to dest : list nat → Hydra → Prop :=
trace_to1 : ∀ n h, round_n n h dest → trace_to dest (n:: nil) h
| trace_toS : ∀ n t h h', round_n n h h' → trace_to dest t h' →
trace_to dest (n:: t) h.
Definition trace t h h' := trace_to h' t h.
Classes of battles
Definition round_t := nat → Hydra → Hydra → Prop.
Class Battle :=
{ battle_rel : round_t;
battle_ok : ∀ i h h', battle_rel i h h' → round h h'}.
Arguments battle_rel : clear implicits.
In the current state of this development, we will consider two instances of class Battle:
- In free, we hydra may chose any replication factor at any time.
- In standard the replication factor at round number i is just i
#[ global, refine ] Instance free : Battle
:= Build_Battle (fun _ h h' ⇒ round h h') _.
#[ global, refine] Instance standard : Battle :=
Build_Battle round_n _.
The following relation allows us to consider sequences of rounds in a given class of battles
The proposition rounds b i h j h' holds if there is a battle of class B that
starts with hydra h at round i and ends with hydra h' at round j
Inductive rounds (B:Battle)
: nat → Hydra → nat → Hydra → Prop :=
rounds_1 : ∀ i h h',
battle_rel B i h h' → rounds B i h (S i) h'
| rounds_n : ∀ i h j h' h'',
battle_rel B i h h'' →
rounds B (S i) h'' j h' →
rounds B i h j h'.
number of steps leading to the hydra's death
Definition battle_length B k h l :=
rounds B k h (Nat.pred (k + l)%nat) head.
#[deprecated(note="use rounds")]
Notation battle := rounds (only parsing).
Definition Termination := well_founded (transp _ round).
Definition B_termination (B: Battle) :=
well_founded (fun h' h ⇒ ∃ i:nat, battle_rel B i h h' ).
Class Hvariant {A:Type}{Lt:relation A}
(Wf: well_founded Lt)(B : Battle)
(m: Hydra → A): Prop :=
{variant_decr: ∀ i h h',
h ≠ head → battle_rel B i h h' → Lt (m h') (m h)}.
Class BoundedVariant {A:Type}{Lt:relation A}
{Wf: well_founded Lt}{B : Battle}
{m: Hydra → A} (Var: Hvariant Wf B m)(mu:A):=
{ m_bounded: ∀ h, Lt (m h ) mu }.