import Sal.MRDTs.RGA_Embed.Sided_ChainLex /-! # The FugueMax chain-lex kernel: right-origin-tagged R entries Weidner-Kleppmann Definition 6 (arXiv:2305.00583v3): FugueMax is Fugue with the tree traversal visiting right-side siblings in the REVERSE order of their right origins, ties by ascending ID; left-side siblings stay in ascending ID order. The Python validation is `whiteboard/litmus/fuguemax_check.py`; the design section is appended to `whiteboard/fugue-maximal-noninterleaving.md`. The realization decision (machine-witnessed in Python by the `mirror` control): the R-sibling order depends on the right origin, which is not a function of `(side, delta)`, so no re-banding of the delta alphabet alone can realize it. The kernel variant therefore enriches the R ENTRY: an R entry carries an immutable right-origin TAG (`[0]` for the `end` origin, otherwise the right origin's sort key, captured at mint time), and the R-sibling rule compares tags first (smaller tag = display-later right origin = earlier sibling), then deltas ascending. The L band is the sided kernel's, unchanged. Flat realization: tags are embedded through the order-REVERSING fixed-width map `fw k = [(8-k)/3, (8-k)%3]` (two symbols in {0,1,2}, all below the marker), and the delta code is complemented into the R band (`compl` = the sided kernel's L-band trick, here realizing ascending deltas). Bands: R block symbols {0,1,2} < marker 3 < L band {4,5}; block heads are never 0, coordinates never contain 3, so keys stay prefix-free and `keyLt` machinery is reused unchanged. -/ namespace Sal.EmbedRGA /-! ## FugueMax entries -/ inductive FMEntry : Type where | R (ro : List ℕ) (d : ℕ) | L (d : ℕ) deriving DecidableEq abbrev FMChain : Type := List FMEntry /-- The delta of an entry. -/ def fmδ : FMEntry → ℕ | .R _ d => d | .L d => d @[simp] def PosFMChain (ch : FMChain) : Prop := ∀ e ∈ ch, 1 ≤ fmδ e /-- Wellformed right-origin tags: the end tag `[0]`, or a real key, nonzero non-marker head, marker-free bounded body, marker terminator. -/ def TagOK (t : List ℕ) : Prop := t = [0] ∨ ∃ h c, t = (h :: c) ++ [3] ∧ h ≠ 0 ∧ h ≠ 3 ∧ h ≤ 5 ∧ ∀ s ∈ c, s ≠ 3 ∧ s ≤ 5 def fmTagOK : FMEntry → Prop | .R t _ => TagOK t | .L _ => True @[simp] def TagsOK (ch : FMChain) : Prop := ∀ e ∈ ch, fmTagOK e theorem tagOK_ne_nil {t : List ℕ} (h : TagOK t) : t ≠ [] := by rcases h with rfl | ⟨h, c, rfl, -⟩ <;> simp theorem tagOK_head {t : List ℕ} (h : TagOK t) : ∃ a t', t = a :: t' ∧ a ≤ 5 := by rcases h with rfl | ⟨h, c, rfl, -, -, hle, -⟩ · exact ⟨0, [], rfl, by omega⟩ · exact ⟨h, c ++ [3], rfl, hle⟩ theorem tagOK_symbols_le {t : List ℕ} (h : TagOK t) : ∀ s ∈ t, s ≤ 5 := by rcases h with rfl | ⟨h, c, rfl, -, -, hle, hc⟩ · intro s hs simp at hs omega · intro s hs simp only [List.cons_append, List.mem_cons] at hs rcases hs with rfl | hs · exact hle · rcases List.mem_append.mp hs with hs' | hs' · exact (hc s hs').2 · rw [List.mem_singleton] at hs' omega /-- Marker-terminated words with marker-free bodies are prefix-free. -/ theorem key_body_prefixFree : ∀ {u v : List ℕ}, (∀ s ∈ v, s ≠ 3) → u ≠ v → ¬ ((u ++ [3]) <+: (v ++ [3])) | [], [], _, hne, _ => hne rfl | [], y :: ys, hv, _, hpre => by rw [List.nil_append, List.cons_append, List.cons_prefix_cons] at hpre exact hv y List.mem_cons_self hpre.1.symm | x :: xs, [], _, _, hpre => by rw [List.cons_append, List.nil_append, List.cons_prefix_cons] at hpre obtain ⟨rfl, htail⟩ := hpre simp at htail | x :: xs, y :: ys, hv, hne, hpre => by rw [List.cons_append, List.cons_append, List.cons_prefix_cons] at hpre obtain ⟨rfl, htail⟩ := hpre have hne' : xs ≠ ys := fun h => hne (by rw [h]) exact key_body_prefixFree (fun s hs => hv s (List.mem_cons_of_mem _ hs)) hne' htail /-- Distinct wellformed tags are never prefixes of one another. -/ theorem tagOK_prefixFree {t₁ t₂ : List ℕ} (h₁ : TagOK t₁) (h₂ : TagOK t₂) (hne : t₁ ≠ t₂) : ¬ (t₁ <+: t₂) := by rcases h₁ with rfl | ⟨a, c, rfl, ha0, -, -, -⟩ · rcases h₂ with rfl | ⟨b, d, rfl, hb0, -, -, -⟩ · exact absurd rfl hne · intro hpre rw [List.cons_append, List.cons_prefix_cons] at hpre exact hb0 hpre.1.symm · rcases h₂ with rfl | ⟨b, d, rfl, -, hb3, -, hd⟩ · intro hpre have := hpre.length_le simp at this · exact key_body_prefixFree (by intro s hs rcases List.mem_cons.mp hs with rfl | hs' · exact hb3 · exact (hd s hs').1) (by simpa using hne) /-! ## The order-reversing fixed-width tag embedding -/ /-- Two R-band symbols per tag symbol, order-reversing on {0..5}. -/ def fw (k : ℕ) : List ℕ := [(8 - k) / 3, (8 - k) % 3] def fwTag : List ℕ → List ℕ | [] => [] | k :: t => fw k ++ fwTag t theorem fwTag_append (s t : List ℕ) : fwTag (s ++ t) = fwTag s ++ fwTag t := by induction s with | nil => rfl | cons k s ih => simp [fwTag, ih] theorem fw_head_band {k : ℕ} (hk : k ≤ 5) : 1 ≤ (8 - k) / 3 ∧ (8 - k) / 3 ≤ 2 := by omega /-- The reversal: a smaller tag symbol yields a lexicographically LARGER fixed-width block, whatever follows. -/ theorem fw_rev {a b : ℕ} (hab : a < b) (hb : b ≤ 5) (u v : List ℕ) : keyLt (fw b ++ u) (fw a ++ v) = true := by have h : (8 - b) / 3 < (8 - a) / 3 ∨ ((8 - b) / 3 = (8 - a) / 3 ∧ (8 - b) % 3 < (8 - a) % 3) := by omega show keyLt ((8 - b) / 3 :: (8 - b) % 3 :: u) ((8 - a) / 3 :: (8 - a) % 3 :: v) = true rcases h with h | ⟨h1, h2⟩ · simp [keyLt, h] · simp [keyLt, h1, h2] theorem fw_inj {a b : ℕ} (ha : a ≤ 5) (hb : b ≤ 5) (h1 : (8 - a) / 3 = (8 - b) / 3) (h2 : (8 - a) % 3 = (8 - b) % 3) : a = b := by omega /-! ## First-difference extraction for `keyLt` on prefix-free words -/ theorem keyLt_first_diff : ∀ {u v : List ℕ}, ¬ (u <+: v) → keyLt u v = true → ∃ p a b u' v', a < b ∧ u = p ++ a :: u' ∧ v = p ++ b :: v' | [], v, hpre, _ => absurd List.nil_prefix hpre | x :: xs, [], _, hlt => by simp [keyLt] at hlt | x :: xs, y :: ys, hpre, hlt => by rcases Nat.lt_trichotomy x y with hxy | rfl | hxy · exact ⟨[], x, y, xs, ys, hxy, rfl, rfl⟩ · have hpre' : ¬ (xs <+: ys) := fun h => hpre (List.cons_prefix_cons.mpr ⟨rfl, h⟩) have hlt' : keyLt xs ys = true := by simp only [keyLt, Nat.lt_irrefl, if_false] at hlt exact hlt obtain ⟨p, a, b, u', v', hab, hu, hv⟩ := keyLt_first_diff hpre' hlt' exact ⟨x :: p, a, b, u', v', hab, by simp [hu], by simp [hv]⟩ · rw [show keyLt (x :: xs) (y :: ys) = false from by simp [keyLt, hxy, Nat.lt_asymm hxy]] at hlt exact Bool.noConfusion hlt /-! ## Blocks and coordinates -/ /-- The block of one entry: R blocks embed the reversed tag then the complemented delta code in the R band; L blocks are the sided kernel's. -/ def fmBlock (Γ : OrderedPrefixCode) : FMEntry → List ℕ | .R t d => fwTag t ++ (compl (Γ.enc d)).map symR | .L d => (compl (Γ.enc d)).map symL def fmCoordOf (Γ : OrderedPrefixCode) : FMChain → List ℕ | [] => [] | e :: ch => fmBlock Γ e ++ fmCoordOf Γ ch theorem fmCoordOf_append (Γ : OrderedPrefixCode) (c1 c2 : FMChain) : fmCoordOf Γ (c1 ++ c2) = fmCoordOf Γ c1 ++ fmCoordOf Γ c2 := by induction c1 with | nil => simp [fmCoordOf] | cons e es ih => simp [fmCoordOf, ih] theorem fmBlock_ne_nil (Γ : OrderedPrefixCode) {e : FMEntry} (he : 1 ≤ fmδ e) : fmBlock Γ e ≠ [] := by cases e with | R t d => have hne := enc_ne_nil Γ (show 1 ≤ d from he) cases henc : Γ.enc d with | nil => exact absurd henc hne | cons b bs => simp [fmBlock, compl, henc] | L d => have hne := enc_ne_nil Γ (show 1 ≤ d from he) cases henc : Γ.enc d with | nil => exact absurd henc hne | cons b bs => simp [fmBlock, compl, henc] /-- Block head shape: R blocks start with an fw head (in {1,2} on wellformed tags), L blocks with an L-band symbol. -/ theorem fmBlock_head_R (Γ : OrderedPrefixCode) {t : List ℕ} {d : ℕ} (ht : TagOK t) : ∃ a rest, fmBlock Γ (.R t d) = (8 - a) / 3 :: rest ∧ a ≤ 5 := by obtain ⟨a, t', rfl, ha⟩ := tagOK_head ht exact ⟨a, (8 - a) % 3 :: (fwTag t' ++ (compl (Γ.enc d)).map symR), by simp [fmBlock, fwTag, fw], ha⟩ theorem fmBlock_head_L (Γ : OrderedPrefixCode) {d : ℕ} (hd : 1 ≤ d) : ∃ b rest, fmBlock Γ (.L d) = symL b :: rest := by cases henc : Γ.enc d with | nil => exact absurd henc (enc_ne_nil Γ hd) | cons b bs => exact ⟨!b, (compl bs).map symL, by simp [fmBlock, compl, henc]⟩ /-! ## Coordinate closure: variant coordinates are valid tag bodies -/ theorem symR_le (b : Bool) : symR b ≤ 5 := by cases b <;> simp [symR] theorem symR_ne3 (b : Bool) : symR b ≠ 3 := by cases b <;> simp [symR] theorem symL_le (b : Bool) : symL b ≤ 5 := by cases b <;> simp [symL] theorem symL_ne3 (b : Bool) : symL b ≠ 3 := by cases b <;> simp [symL] theorem fwTag_symbols {t : List ℕ} (ht : ∀ s ∈ t, s ≤ 5) : ∀ s ∈ fwTag t, s ≠ 3 ∧ s ≤ 5 := by induction t with | nil => intro s hs; simp [fwTag] at hs | cons k t ih => intro s hs rcases List.mem_append.mp (by simpa [fwTag] using hs) with h | h · have hk := ht k List.mem_cons_self simp only [fw, List.mem_cons, List.not_mem_nil, or_false] at h rcases h with rfl | rfl <;> constructor <;> omega · exact ih (fun s hs => ht s (List.mem_cons_of_mem _ hs)) s h theorem fmBlock_symbols (Γ : OrderedPrefixCode) {e : FMEntry} (ht : fmTagOK e) : ∀ s ∈ fmBlock Γ e, s ≠ 3 ∧ s ≤ 5 := by cases e with | R t d => intro s hs rcases List.mem_append.mp hs with h | h · exact fwTag_symbols (tagOK_symbols_le ht) s h · obtain ⟨b, -, rfl⟩ := List.mem_map.mp h exact ⟨symR_ne3 b, symR_le b⟩ | L d => intro s hs obtain ⟨b, -, rfl⟩ := List.mem_map.mp hs exact ⟨symL_ne3 b, symL_le b⟩ theorem fmCoordOf_symbols (Γ : OrderedPrefixCode) {ch : FMChain} (ht : TagsOK ch) : ∀ s ∈ fmCoordOf Γ ch, s ≠ 3 ∧ s ≤ 5 := by induction ch with | nil => intro s hs; simp [fmCoordOf] at hs | cons e es ih => intro s hs rcases List.mem_append.mp hs with h | h · exact fmBlock_symbols Γ (ht e List.mem_cons_self) s h · exact ih (fun x hx => ht x (List.mem_cons_of_mem _ hx)) s h /-- **Tag closure**: the key of a wellformed nonempty coordinate is itself a wellformed tag, what lets minted keys feed back in as right-origin tags. -/ theorem tagOK_key (Γ : OrderedPrefixCode) {ch : FMChain} (hpos : PosFMChain ch) (ht : TagsOK ch) (hne : ch ≠ []) : TagOK (sKey (fmCoordOf Γ ch)) := by cases ch with | nil => exact absurd rfl hne | cons e es => right have hsym := fmCoordOf_symbols Γ (ch := e :: es) ht have hhead : ∃ h rest, fmCoordOf Γ (e :: es) = h :: rest ∧ h ≠ 0 := by cases e with | R t d => obtain ⟨a, rest, heq, ha⟩ := fmBlock_head_R Γ (d := d) (ht (.R t d) List.mem_cons_self) refine ⟨(8 - a) / 3, rest ++ fmCoordOf Γ es, ?_, by omega⟩ show fmBlock Γ (.R t d) ++ fmCoordOf Γ es = _ rw [heq] rfl | L d => obtain ⟨b, rest, heq⟩ := fmBlock_head_L Γ (d := d) (show 1 ≤ d from hpos (.L d) List.mem_cons_self) refine ⟨symL b, rest ++ fmCoordOf Γ es, ?_, ?_⟩ · show fmBlock Γ (.L d) ++ fmCoordOf Γ es = _ rw [heq] rfl · cases b <;> simp [symL] obtain ⟨h, rest, heq, h0⟩ := hhead refine ⟨h, rest, ?_, h0, ?_, ?_, ?_⟩ · show fmCoordOf Γ (e :: es) ++ [3] = (h :: rest) ++ [3] rw [heq] · exact (hsym h (heq ▸ List.mem_cons_self)).1 · exact (hsym h (heq ▸ List.mem_cons_self)).2 · intro s hs exact hsym s (heq ▸ List.mem_cons_of_mem _ hs) /-! ## The entry order -/ /-- FugueMax divergence order: among R-siblings the smaller tag (the display-later right origin) first, ties by ascending delta; among L-siblings ascending delta (unchanged); L before node before R. -/ def fmEntryBefore : FMEntry → FMEntry → Prop | .R t1 d1, .R t2 d2 => keyLt t1 t2 = true ∨ (t1 = t2 ∧ d1 < d2) | .L d1, .L d2 => d1 < d2 | .L _, .R _ _ => True | .R _ _, .L _ => False theorem fmEntryBefore_irrefl (e : FMEntry) : ¬ fmEntryBefore e e := by cases e with | R t d => rintro (h | ⟨-, h⟩) · rw [keyLt_irrefl] at h exact Bool.noConfusion h · omega | L d => exact fun h => absurd h (by simp [fmEntryBefore]) theorem fmEntryBefore_asymm {e1 e2 : FMEntry} (h : fmEntryBefore e1 e2) : ¬ fmEntryBefore e2 e1 := by cases e1 with | R t1 d1 => cases e2 with | R t2 d2 => rcases h with h | ⟨rfl, h⟩ · rintro (h' | ⟨rfl, h'⟩) · rw [keyLt_asymm h] at h' exact Bool.noConfusion h' · rw [keyLt_irrefl] at h exact Bool.noConfusion h · rintro (h' | ⟨-, h'⟩) · rw [keyLt_irrefl] at h' exact Bool.noConfusion h' · omega | L d2 => exact absurd h (by simp [fmEntryBefore]) | L d1 => cases e2 with | R t2 d2 => exact fun h' => absurd h' (by simp [fmEntryBefore]) | L d2 => have h' : d1 < d2 := h simp only [fmEntryBefore] omega theorem fmEntryBefore_total {e1 e2 : FMEntry} (hne : e1 ≠ e2) : fmEntryBefore e1 e2 ∨ fmEntryBefore e2 e1 := by cases e1 with | R t1 d1 => cases e2 with | R t2 d2 => rcases eq_or_ne t1 t2 with rfl | hnt · rcases Nat.lt_trichotomy d1 d2 with h | rfl | h · exact Or.inl (Or.inr ⟨rfl, h⟩) · exact absurd rfl hne · exact Or.inr (Or.inr ⟨rfl, h⟩) · rcases keyLt_total hnt with h | h · exact Or.inl (Or.inl h) · exact Or.inr (Or.inl h) | L d2 => exact Or.inr trivial | L d1 => cases e2 with | R t2 d2 => exact Or.inl trivial | L d2 => rcases Nat.lt_trichotomy d1 d2 with h | rfl | h · exact Or.inl h · exact absurd rfl hne · exact Or.inr h /-! ## The chain order -/ inductive fmChainBefore : FMChain → FMChain → Prop where | extL (ch : FMChain) (d : ℕ) (rest : FMChain) : fmChainBefore (ch ++ .L d :: rest) ch | extR (ch : FMChain) (t : List ℕ) (d : ℕ) (rest : FMChain) : fmChainBefore ch (ch ++ .R t d :: rest) | diverge (q : FMChain) (e1 e2 : FMEntry) (c1 c2 : FMChain) : fmEntryBefore e1 e2 → fmChainBefore (q ++ e1 :: c1) (q ++ e2 :: c2) theorem fmChainBefore_cons (x : FMEntry) {c1 c2 : FMChain} (h : fmChainBefore c1 c2) : fmChainBefore (x :: c1) (x :: c2) := by cases h with | extL ch d rest => exact fmChainBefore.extL (x :: c2) d rest | extR ch t d rest => exact fmChainBefore.extR (x :: c1) t d rest | diverge q e1 e2 t1 t2 hlt => exact fmChainBefore.diverge (x :: q) e1 e2 t1 t2 hlt theorem fmChainBefore_total : ∀ {c1 c2 : FMChain}, c1 ≠ c2 → fmChainBefore c1 c2 ∨ fmChainBefore c2 c1 | [], [], hne => absurd rfl hne | [], e :: es, _ => by cases e with | R t d => exact Or.inl (fmChainBefore.extR [] t d es) | L d => exact Or.inr (fmChainBefore.extL [] d es) | e :: es, [], _ => by cases e with | R t d => exact Or.inr (fmChainBefore.extR [] t d es) | L d => exact Or.inl (fmChainBefore.extL [] d es) | e1 :: t1, e2 :: t2, hne => by by_cases he : e1 = e2 · subst he have hne' : t1 ≠ t2 := fun h => hne (by rw [h]) rcases fmChainBefore_total hne' with h | h · exact Or.inl (fmChainBefore_cons e1 h) · exact Or.inr (fmChainBefore_cons e1 h) · rcases fmEntryBefore_total he with h | h · exact Or.inl (fmChainBefore.diverge [] e1 e2 t1 t2 h) · exact Or.inr (fmChainBefore.diverge [] e2 e1 t2 t1 h) theorem fmChainBefore_inv {c1 c2 : FMChain} (h : fmChainBefore c1 c2) : (∃ d rest, c1 = c2 ++ .L d :: rest) ∨ (∃ t d rest, c2 = c1 ++ .R t d :: rest) ∨ (∃ q e1 e2 t1 t2, fmEntryBefore e1 e2 ∧ c1 = q ++ e1 :: t1 ∧ c2 = q ++ e2 :: t2) := by cases h with | extL ch d rest => exact Or.inl ⟨d, rest, rfl⟩ | extR ch t d rest => exact Or.inr (Or.inl ⟨t, d, rest, rfl⟩) | diverge q e1 e2 t1 t2 hlt => exact Or.inr (Or.inr ⟨q, e1, e2, t1, t2, hlt, rfl, rfl⟩) theorem fmChainBefore_cons_strip {x : FMEntry} {a b : FMChain} (h : fmChainBefore (x :: a) (x :: b)) : fmChainBefore a b := by rcases fmChainBefore_inv h with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, ha, hb⟩ · rw [List.cons_append] at heq injection heq with h1x h2 rw [h2] exact fmChainBefore.extL b d rest · rw [List.cons_append] at heq injection heq with h1x h2 rw [h2] exact fmChainBefore.extR a t d rest · cases q with | nil => simp only [List.nil_append] at ha hb injection ha with h3 h4 injection hb with h5 h6 rw [← h3, ← h5] at hlt exact absurd hlt (fmEntryBefore_irrefl x) | cons y q' => rw [List.cons_append] at ha hb injection ha with hax h4 injection hb with hbx h6 rw [h4, h6] exact fmChainBefore.diverge q' e1 e2 t1 t2 hlt theorem fmChainBefore_nil_right {c : FMChain} (h : fmChainBefore c []) : ∃ d rest, c = .L d :: rest := by rcases fmChainBefore_inv h with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, h1, h2⟩ · exact ⟨d, rest, by simpa using heq⟩ · simp at heq · simp at h2 theorem fmChainBefore_nil_left {c : FMChain} (h : fmChainBefore [] c) : ∃ t d rest, c = .R t d :: rest := by rcases fmChainBefore_inv h with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, h1, h2⟩ · simp at heq · exact ⟨t, d, rest, by simpa using heq⟩ · simp at h1 theorem fmChainBefore_ne {c1 c2 : FMChain} (h : fmChainBefore c1 c2) : c1 ≠ c2 := by cases h with | extL ch d rest => intro h have := congrArg List.length h simp at this | extR ch t d rest => intro h have := congrArg List.length h simp at this | diverge q e1 e2 c1 c2 hlt => intro h have h2 := List.append_cancel_left h injection h2 with h3 h4 subst h3 exact fmEntryBefore_irrefl e1 hlt /-- A member of the subtree strictly after the node extends it on the R side. -/ theorem fm_ext_after_is_R {p ext : FMChain} (h : fmChainBefore p (p ++ ext)) : ∃ t d rest, ext = FMEntry.R t d :: rest := by rcases fmChainBefore_inv h with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, h1, h2⟩ · exfalso have := congrArg List.length heq simp at this · exact ⟨t, d, rest, List.append_cancel_left heq⟩ · exfalso rw [h1, List.append_assoc] at h2 have h3 := List.append_cancel_left h2 injection h3 with h4 h5 subst h4 exact fmEntryBefore_irrefl e1 hlt /-! ## Subtree convexity -/ theorem fm_subtree_convex : ∀ (p : FMChain) {cx cy cz : FMChain}, (∃ ex, cx = p ++ ex) → (∃ ey, cy = p ++ ey) → fmChainBefore cx cz → fmChainBefore cz cy → ∃ ez, cz = p ++ ez | [], _, _, cz, _, _, _, _ => ⟨cz, rfl⟩ | e :: p', cx, cy, cz, hex, hey, h1, h2 => by obtain ⟨ex, hx⟩ := hex obtain ⟨ey, hy⟩ := hey subst hx subst hy cases cz with | nil => obtain ⟨d1, r1, hc1⟩ := fmChainBefore_nil_right h1 obtain ⟨t2, d2, r2, hc2⟩ := fmChainBefore_nil_left h2 rw [List.cons_append] at hc1 hc2 injection hc1 with h3 h3t injection hc2 with h4 h4t rw [h3] at h4 exact FMEntry.noConfusion h4 | cons f cz' => have hfe : f = e := by by_contra hne have hEF : fmEntryBefore e f := by rcases fmChainBefore_inv h1 with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, ha, hb⟩ · rw [List.cons_append] at heq injection heq with h3 h3t exact absurd h3.symm hne · rw [List.cons_append] at heq injection heq with h3 h3t exact absurd h3 hne · cases q with | nil => simp only [List.nil_append] at ha hb injection ha with h3 h3t injection hb with h4 h4t rw [← h3, ← h4] at hlt exact hlt | cons y q' => rw [List.cons_append] at ha hb injection ha with h3 h3t injection hb with h4 h4t exact absurd (h4.trans h3.symm) hne have hFE : fmEntryBefore f e := by rcases fmChainBefore_inv h2 with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, ha, hb⟩ · rw [List.cons_append] at heq injection heq with h3 h3t exact absurd h3 hne · rw [List.cons_append] at heq injection heq with h3 h3t exact absurd h3.symm hne · cases q with | nil => simp only [List.nil_append] at ha hb injection ha with h3 h3t injection hb with h4 h4t rw [← h3, ← h4] at hlt exact hlt | cons y q' => rw [List.cons_append] at ha hb injection ha with h3 h3t injection hb with h4 h4t exact absurd (h3.trans h4.symm) hne exact fmEntryBefore_asymm hEF hFE subst hfe obtain ⟨ez, hez⟩ := fm_subtree_convex p' ⟨ex, rfl⟩ ⟨ey, rfl⟩ (fmChainBefore_cons_strip h1) (fmChainBefore_cons_strip h2) exact ⟨ez, by rw [List.cons_append, hez]⟩ /-! ## The FugueMax marker theorem -/ /-- **Chain order ⟹ key order**: the flat comparison of FugueMax coordinates realizes the FugueMax in-order rule. -/ theorem fmChainBefore_display (Γ : OrderedPrefixCode) {c1 c2 : FMChain} (h1 : PosFMChain c1) (h2 : PosFMChain c2) (ht1 : TagsOK c1) (ht2 : TagsOK c2) (hb : fmChainBefore c1 c2) : keyLt (sKey (fmCoordOf Γ c2)) (sKey (fmCoordOf Γ c1)) = true := by cases hb with | extL ch d rest => -- c1 = c2 ++ .L d :: rest: marker (c2) meets an L-band symbol (c1) have hd : 1 ≤ d := h1 (.L d) (List.mem_append_right _ List.mem_cons_self) obtain ⟨b, tl, hbl⟩ := fmBlock_head_L Γ (d := d) hd show keyLt (fmCoordOf Γ c2 ++ [3]) (fmCoordOf Γ (c2 ++ .L d :: rest) ++ [3]) = true rw [fmCoordOf_append, List.append_assoc, show fmCoordOf Γ (.L d :: rest) ++ [3] = symL b :: (tl ++ (fmCoordOf Γ rest ++ [3])) from by show (fmBlock Γ (.L d) ++ fmCoordOf Γ rest) ++ [3] = _ rw [hbl] simp, show (fmCoordOf Γ c2 ++ [3] : List ℕ) = fmCoordOf Γ c2 ++ 3 :: [] from rfl] exact keyLt_append_cons_lt _ (three_lt_symL b) _ _ | extR ch t d rest => -- c2 = c1 ++ .R t d :: rest: an fw head (c2) meets the marker (c1) have htag : TagOK t := ht2 (.R t d) (List.mem_append_right _ List.mem_cons_self) obtain ⟨a, tl, hbl, ha⟩ := fmBlock_head_R Γ (d := d) htag show keyLt (fmCoordOf Γ (c1 ++ .R t d :: rest) ++ [3]) (fmCoordOf Γ c1 ++ [3]) = true rw [fmCoordOf_append, List.append_assoc, show fmCoordOf Γ (.R t d :: rest) ++ [3] = (8 - a) / 3 :: (tl ++ (fmCoordOf Γ rest ++ [3])) from by show (fmBlock Γ (.R t d) ++ fmCoordOf Γ rest) ++ [3] = _ rw [hbl] simp, show (fmCoordOf Γ c1 ++ [3] : List ℕ) = fmCoordOf Γ c1 ++ 3 :: [] from rfl] exact keyLt_append_cons_lt _ (by omega : (8 - a) / 3 < 3) _ _ | diverge q e1 e2 t1 t2 hlt => show keyLt (fmCoordOf Γ (q ++ e2 :: t2) ++ [3]) (fmCoordOf Γ (q ++ e1 :: t1) ++ [3]) = true rw [fmCoordOf_append, fmCoordOf_append, List.append_assoc, List.append_assoc] rw [keyLt_append_left] have hm1 : e1 ∈ q ++ e1 :: t1 := List.mem_append_right _ List.mem_cons_self have hm2 : e2 ∈ q ++ e2 :: t2 := List.mem_append_right _ List.mem_cons_self cases e1 with | R ta da => cases e2 with | R tb db => rcases hlt with htab | ⟨rfl, hdab⟩ · -- tags differ: the reversed fixed-width embedding decides have hta : TagOK ta := ht1 _ hm1 have htb : TagOK tb := ht2 _ hm2 have hne : ta ≠ tb := by intro h rw [h, keyLt_irrefl] at htab exact Bool.noConfusion htab obtain ⟨p, a, b, u', v', hab, hu, hv⟩ := keyLt_first_diff (tagOK_prefixFree hta htb hne) htab have hble : b ≤ 5 := tagOK_symbols_le htb b (by rw [hv] exact List.mem_append_right _ List.mem_cons_self) rw [show fmCoordOf Γ (.R tb db :: t2) ++ [3] = fwTag p ++ (fw b ++ (fwTag v' ++ ((compl (Γ.enc db)).map symR ++ (fmCoordOf Γ t2 ++ [3])))) from by show (fmBlock Γ (.R tb db) ++ fmCoordOf Γ t2) ++ [3] = _ rw [show fmBlock Γ (.R tb db) = fwTag p ++ (fw b ++ (fwTag v' ++ (compl (Γ.enc db)).map symR)) from by show fwTag tb ++ _ = _ rw [hv, fwTag_append] show fwTag p ++ fwTag (b :: v') ++ _ = _ simp [fwTag]] simp, show fmCoordOf Γ (.R ta da :: t1) ++ [3] = fwTag p ++ (fw a ++ (fwTag u' ++ ((compl (Γ.enc da)).map symR ++ (fmCoordOf Γ t1 ++ [3])))) from by show (fmBlock Γ (.R ta da) ++ fmCoordOf Γ t1) ++ [3] = _ rw [show fmBlock Γ (.R ta da) = fwTag p ++ (fw a ++ (fwTag u' ++ (compl (Γ.enc da)).map symR)) from by show fwTag ta ++ _ = _ rw [hu, fwTag_append] show fwTag p ++ fwTag (a :: u') ++ _ = _ simp [fwTag]] simp] rw [keyLt_append_left] exact fw_rev hab hble _ _ · -- equal tags: complemented delta code, ascending have hda : 1 ≤ da := h1 _ hm1 have hdb : 1 ≤ db := h2 _ hm2 obtain ⟨p, u1, u2, hE1, hE2⟩ := enc_first_diff Γ hda hdb hdab rw [show fmCoordOf Γ (.R ta db :: t2) ++ [3] = fwTag ta ++ ((compl p).map symR ++ 1 :: ((compl u2).map symR ++ (fmCoordOf Γ t2 ++ [3]))) from by show (fmBlock Γ (.R ta db) ++ fmCoordOf Γ t2) ++ [3] = _ show ((fwTag ta ++ (compl (Γ.enc db)).map symR) ++ fmCoordOf Γ t2) ++ [3] = _ rw [hE2] simp [compl, symR], show fmCoordOf Γ (.R ta da :: t1) ++ [3] = fwTag ta ++ ((compl p).map symR ++ 2 :: ((compl u1).map symR ++ (fmCoordOf Γ t1 ++ [3]))) from by show (fmBlock Γ (.R ta da) ++ fmCoordOf Γ t1) ++ [3] = _ show ((fwTag ta ++ (compl (Γ.enc da)).map symR) ++ fmCoordOf Γ t1) ++ [3] = _ rw [hE1] simp [compl, symR]] rw [keyLt_append_left, keyLt_append_left] simp [keyLt] | L db => exact absurd hlt (by simp [fmEntryBefore]) | L da => cases e2 with | R tb db => -- L before R: the bands decide have hda : 1 ≤ da := h1 _ hm1 have htb : TagOK tb := ht2 _ hm2 obtain ⟨b1, tl1, hbl1⟩ := fmBlock_head_L Γ (d := da) hda obtain ⟨a, tl2, hbl2, ha⟩ := fmBlock_head_R Γ (d := db) htb rw [show fmCoordOf Γ (.R tb db :: t2) ++ [3] = (8 - a) / 3 :: (tl2 ++ (fmCoordOf Γ t2 ++ [3])) from by show (fmBlock Γ (.R tb db) ++ fmCoordOf Γ t2) ++ [3] = _ rw [hbl2] simp, show fmCoordOf Γ (.L da :: t1) ++ [3] = symL b1 :: (tl1 ++ (fmCoordOf Γ t1 ++ [3])) from by show (fmBlock Γ (.L da) ++ fmCoordOf Γ t1) ++ [3] = _ rw [hbl1] simp] have hlt3 : (8 - a) / 3 < symL b1 := by have := fw_head_band (k := a) ha cases b1 <;> simp [symL] <;> omega show keyLt ([] ++ (8 - a) / 3 :: (tl2 ++ (fmCoordOf Γ t2 ++ [3]))) ([] ++ symL b1 :: (tl1 ++ (fmCoordOf Γ t1 ++ [3]))) = true exact keyLt_append_cons_lt [] hlt3 _ _ | L db => -- L vs L: mirrored, unchanged from the sided kernel have hda : 1 ≤ da := h1 _ hm1 have hdb : 1 ≤ db := h2 _ hm2 have hdab : da < db := hlt obtain ⟨p, u1, u2, hE1, hE2⟩ := enc_first_diff Γ hda hdb hdab rw [show fmCoordOf Γ (.L db :: t2) ++ [3] = (compl p).map symL ++ 4 :: ((compl u2).map symL ++ (fmCoordOf Γ t2 ++ [3])) from by show (fmBlock Γ (.L db) ++ fmCoordOf Γ t2) ++ [3] = _ show ((compl (Γ.enc db)).map symL ++ fmCoordOf Γ t2) ++ [3] = _ rw [hE2] simp [compl, symL], show fmCoordOf Γ (.L da :: t1) ++ [3] = (compl p).map symL ++ 5 :: ((compl u1).map symL ++ (fmCoordOf Γ t1 ++ [3])) from by show (fmBlock Γ (.L da) ++ fmCoordOf Γ t1) ++ [3] = _ show ((compl (Γ.enc da)).map symL ++ fmCoordOf Γ t1) ++ [3] = _ rw [hE1] simp [compl, symL]] rw [keyLt_append_left] simp [keyLt] /-- **The FugueMax marker theorem**: on distinct wellformed chains the flat key comparison is exactly the FugueMax chain order. -/ theorem fmdisplay_iff_fmChainBefore (Γ : OrderedPrefixCode) {c1 c2 : FMChain} (h1 : PosFMChain c1) (h2 : PosFMChain c2) (ht1 : TagsOK c1) (ht2 : TagsOK c2) (hne : c1 ≠ c2) : keyLt (sKey (fmCoordOf Γ c2)) (sKey (fmCoordOf Γ c1)) = true ↔ fmChainBefore c1 c2 := by constructor · intro h rcases fmChainBefore_total hne with hb | hb · exact hb · have h' := fmChainBefore_display Γ h2 h1 ht2 ht1 hb rw [keyLt_asymm h'] at h exact Bool.noConfusion h · exact fmChainBefore_display Γ h1 h2 ht1 ht2 /-! ## Unique decodability -/ /-- R-band delta symbol map (the complement composed into the map). -/ def symRc (b : Bool) : ℕ := symR (!b) theorem symRc_inj : Function.Injective symRc := by intro a b h cases a <;> cases b <;> simp [symRc, symR] at h ⊢ theorem compl_map_symR (w : List Bool) : (compl w).map symR = w.map symRc := by simp [compl, symRc, List.map_map, Function.comp] def symLc (b : Bool) : ℕ := symL (!b) theorem symLc_inj : Function.Injective symLc := by intro a b h cases a <;> cases b <;> simp [symLc, symL] at h ⊢ theorem compl_map_symL (w : List Bool) : (compl w).map symL = w.map symLc := by simp [compl, symLc, List.map_map, Function.comp] /-- Same-length prefix-or-equal lists sharing a common extension agree, packaged as: two lists that are prefixes of one common list are comparable. -/ theorem fw_group_inj {a b : ℕ} (ha : a ≤ 5) (hb : b ≤ 5) {u v : List ℕ} (h : fw a ++ u = fw b ++ v) : a = b ∧ u = v := by have h1 : (8 - a) / 3 = (8 - b) / 3 := by have := congrArg (fun l => l.headD 0) h simpa [fw] using this have h2 : (8 - a) % 3 = (8 - b) % 3 := by have := congrArg (fun l => (l.drop 1).headD 0) h simpa [fw] using this have hab : a = b := fw_inj ha hb h1 h2 subst hab exact ⟨rfl, by simpa [fw] using h⟩ /-- Equal tag embeddings with arbitrary continuations force equal tags, for prefix-free wellformed tags. -/ theorem fwTag_cancel {t₁ t₂ : List ℕ} (h₁ : TagOK t₁) (h₂ : TagOK t₂) {u v : List ℕ} (h : fwTag t₁ ++ u = fwTag t₂ ++ v) : t₁ = t₂ ∧ u = v := by by_cases hne : t₁ = t₂ · subst hne exact ⟨rfl, List.append_cancel_left h⟩ · exfalso have hp₁ := tagOK_prefixFree h₁ h₂ hne have hp₂ := tagOK_prefixFree h₂ h₁ (Ne.symm hne) -- extract a first difference from either keyLt direction obtain ⟨p, a, b, u', v', hab, hu, hv⟩ : ∃ p a b u' v', a ≠ b ∧ t₁ = p ++ a :: u' ∧ t₂ = p ++ b :: v' := by rcases keyLt_total hne with hk | hk · obtain ⟨p, a, b, u', v', hab, hu, hv⟩ := keyLt_first_diff hp₁ hk exact ⟨p, a, b, u', v', by omega, hu, hv⟩ · obtain ⟨p, a, b, u', v', hab, hu, hv⟩ := keyLt_first_diff hp₂ hk exact ⟨p, b, a, v', u', by omega, hv, hu⟩ have ha5 : a ≤ 5 := tagOK_symbols_le h₁ a (by rw [hu]; exact List.mem_append_right _ List.mem_cons_self) have hb5 : b ≤ 5 := tagOK_symbols_le h₂ b (by rw [hv]; exact List.mem_append_right _ List.mem_cons_self) rw [hu, hv, fwTag_append, fwTag_append, List.append_assoc, List.append_assoc] at h have h' := List.append_cancel_left h rw [show fwTag (a :: u') = fw a ++ fwTag u' from rfl, show fwTag (b :: v') = fw b ++ fwTag v' from rfl, List.append_assoc, List.append_assoc] at h' exact hab (fw_group_inj ha5 hb5 h').1 /-- **Unique decodability**: distinct wellformed FugueMax chains mint distinct coordinates. -/ theorem fmCoordOf_inj (Γ : OrderedPrefixCode) : ∀ {c1 c2 : FMChain}, PosFMChain c1 → PosFMChain c2 → TagsOK c1 → TagsOK c2 → fmCoordOf Γ c1 = fmCoordOf Γ c2 → c1 = c2 | [], [], _, _, _, _, _ => rfl | [], e :: es, _, h2, _, _, h => by exfalso have hd : 1 ≤ fmδ e := h2 e List.mem_cons_self have hne := fmBlock_ne_nil Γ hd cases hb : fmBlock Γ e with | nil => exact hne hb | cons x xs => simp only [fmCoordOf, hb] at h simp at h | e :: es, [], h1, _, _, _, h => by exfalso have hd : 1 ≤ fmδ e := h1 e List.mem_cons_self have hne := fmBlock_ne_nil Γ hd cases hb : fmBlock Γ e with | nil => exact hne hb | cons x xs => simp only [fmCoordOf, hb] at h simp at h | e1 :: c1, e2 :: c2, h1, h2, ht1, ht2, h => by have hd1 : 1 ≤ fmδ e1 := h1 e1 List.mem_cons_self have hd2 : 1 ≤ fmδ e2 := h2 e2 List.mem_cons_self simp only [fmCoordOf] at h have hee : e1 = e2 ∧ fmCoordOf Γ c1 = fmCoordOf Γ c2 := by cases e1 with | R ta da => cases e2 with | R tb db => have hta : TagOK ta := ht1 _ List.mem_cons_self have htb : TagOK tb := ht2 _ List.mem_cons_self simp only [fmBlock, List.append_assoc] at h obtain ⟨rfl, h'⟩ := fwTag_cancel hta htb h rw [compl_map_symR, compl_map_symR] at h' have hde : da = db := by by_contra hnd have p1 : (Γ.enc da).map symRc <+: (Γ.enc da).map symRc ++ fmCoordOf Γ c1 := List.prefix_append _ _ have p2 : (Γ.enc db).map symRc <+: (Γ.enc da).map symRc ++ fmCoordOf Γ c1 := by rw [h'] exact List.prefix_append _ _ rcases Nat.le_total ((Γ.enc da).map symRc).length ((Γ.enc db).map symRc).length with hle | hle · exact Γ.prefixFree hd1 hd2 hnd (map_prefix_reflect symRc_inj (List.prefix_of_prefix_length_le p1 p2 hle)) · exact Γ.prefixFree hd2 hd1 (Ne.symm hnd) (map_prefix_reflect symRc_inj (List.prefix_of_prefix_length_le p2 p1 hle)) subst hde exact ⟨rfl, List.append_cancel_left h'⟩ | L db => exfalso have hta : TagOK ta := ht1 _ List.mem_cons_self obtain ⟨a, tl, hbl, ha⟩ := fmBlock_head_R Γ (d := da) hta obtain ⟨b, tl2, hbl2⟩ := fmBlock_head_L Γ (d := db) hd2 rw [hbl, hbl2] at h have hhead : (8 - a) / 3 = symL b := by have := congrArg (fun l => l.headD 0) h simpa using this have := fw_head_band (k := a) ha cases b <;> simp [symL] at hhead <;> omega | L da => cases e2 with | R tb db => exfalso have htb : TagOK tb := ht2 _ List.mem_cons_self obtain ⟨b, tl, hbl⟩ := fmBlock_head_L Γ (d := da) hd1 obtain ⟨a, tl2, hbl2, ha⟩ := fmBlock_head_R Γ (d := db) htb rw [hbl, hbl2] at h have hhead : symL b = (8 - a) / 3 := by have := congrArg (fun l => l.headD 0) h simpa using this have := fw_head_band (k := a) ha cases b <;> simp [symL] at hhead <;> omega | L db => simp only [fmBlock] at h rw [compl_map_symL, compl_map_symL] at h have hde : da = db := by by_contra hnd have p1 : (Γ.enc da).map symLc <+: (Γ.enc da).map symLc ++ fmCoordOf Γ c1 := List.prefix_append _ _ have p2 : (Γ.enc db).map symLc <+: (Γ.enc da).map symLc ++ fmCoordOf Γ c1 := by rw [h] exact List.prefix_append _ _ rcases Nat.le_total ((Γ.enc da).map symLc).length ((Γ.enc db).map symLc).length with hle | hle · exact Γ.prefixFree hd1 hd2 hnd (map_prefix_reflect symLc_inj (List.prefix_of_prefix_length_le p1 p2 hle)) · exact Γ.prefixFree hd2 hd1 (Ne.symm hnd) (map_prefix_reflect symLc_inj (List.prefix_of_prefix_length_le p2 p1 hle)) subst hde exact ⟨rfl, List.append_cancel_left h⟩ obtain ⟨he, hc⟩ := hee subst he rw [fmCoordOf_inj Γ (fun e he => h1 e (List.mem_cons_of_mem _ he)) (fun e he => h2 e (List.mem_cons_of_mem _ he)) (fun e he => ht1 e (List.mem_cons_of_mem _ he)) (fun e he => ht2 e (List.mem_cons_of_mem _ he)) hc] /-! ## Cross-validation examples (Python twin: fuguemax_check.py) Unary code. The end tag is `[0]`; `fw 0 = [2,2]`; an R entry of delta 1 carries `compl (enc 1) = [false, true]` mapped to `[1,2]`. -/ example : fmCoordOf unaryCode [.R [0] 1] = [2, 2, 1, 2] := by decide /-- Two R-siblings with the end tag order by ascending delta: the smaller delta displays first (the two-front-inserts case, FugueMax order). -/ example : keyLt (sKey (fmCoordOf unaryCode [.R [0] 2])) (sKey (fmCoordOf unaryCode [.R [0] 1])) = true := by decide /-- Two R-siblings with distinct real tags order by REVERSE right origin: the sibling whose right origin displays later (the node `[.R [0] 5]`, which sits after `[.R [0] 4]` and so has the smaller key) displays FIRST, even though it has the larger delta, right origin overrides recency and ID order alike. -/ example : keyLt (sKey (fmCoordOf unaryCode [.R (sKey (fmCoordOf unaryCode [.R [0] 4])) 1])) (sKey (fmCoordOf unaryCode [.R (sKey (fmCoordOf unaryCode [.R [0] 5])) 4])) = true := by decide /-- L-siblings are unchanged: ascending delta, older first. -/ example : keyLt (sKey (fmCoordOf unaryCode [.R [0] 1, .L 20])) (sKey (fmCoordOf unaryCode [.R [0] 1, .L 9])) = true := by decide #print axioms fmdisplay_iff_fmChainBefore #print axioms fm_subtree_convex #print axioms fmCoordOf_inj #print axioms tagOK_key /-! ## Backward-condition bookkeeping The two marker-theorem consumers the backward discharge needs: the before-side twin of `fm_ext_after_is_R`, and the divergence inversion for same-parent R-siblings. Design: `whiteboard/fugue-maximal-noninterleaving.md` §9.7.8 item 2. -/ /-- Order congruence under a common prefix (the append form of `fmChainBefore_cons`). -/ theorem fmChainBefore_append_left (p : FMChain) {a b : FMChain} (h : fmChainBefore a b) : fmChainBefore (p ++ a) (p ++ b) := by induction p with | nil => exact h | cons x p' ih => exact fmChainBefore_cons x ih /-- Strip a common prefix (the append form of `fmChainBefore_cons_strip`). -/ theorem fmChainBefore_append_strip : ∀ (p : FMChain) {a b : FMChain}, fmChainBefore (p ++ a) (p ++ b) → fmChainBefore a b | [], _, _, h => h | _ :: p', _, _, h => fmChainBefore_append_strip p' (fmChainBefore_cons_strip h) /-- A member of the subtree strictly before the node extends it on the L side: the before-side twin of `fm_ext_after_is_R`. -/ theorem fm_ext_before_is_L {p ext : FMChain} (h : fmChainBefore (p ++ ext) p) : ∃ d rest, ext = FMEntry.L d :: rest := by rcases fmChainBefore_inv h with ⟨d, rest, heq⟩ | ⟨t, d, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, h1, h2⟩ · exact ⟨d, rest, List.append_cancel_left heq⟩ · exfalso have := congrArg List.length heq simp at this · exfalso rw [h2, List.append_assoc] at h1 have h3 := List.append_cancel_left h1 injection h3 with h4 h5 subst h4 exact fmEntryBefore_irrefl e2 hlt /-- **Divergence inversion for same-parent R-siblings**: a node one R entry over `p` displays before a member of a same-parent R-child's subtree only through the entry order at the divergence, smaller tag lexicographically, or equal tags and smaller delta, unless the two R entries coincide (the member sits in the node's own subtree). -/ theorem fm_R_sibling_inv {p : FMChain} {t t' : List ℕ} {d d' : ℕ} {u : FMChain} (h : fmChainBefore (p ++ [FMEntry.R t d]) (p ++ FMEntry.R t' d' :: u)) : (keyLt t t' = true ∨ (t = t' ∧ d < d')) ∨ (t = t' ∧ d = d') := by have h' := fmChainBefore_append_strip p h rcases fmChainBefore_inv h' with ⟨dd, rest, heq⟩ | ⟨tt, dd, rest, heq⟩ | ⟨q, e1, e2, t1, t2, hlt, h1, h2⟩ · exfalso have := congrArg List.length heq simp at this · rw [List.singleton_append] at heq injection heq with h1 h2 injection h1 with h3 h4 exact Or.inr ⟨h3.symm, h4.symm⟩ · cases q with | nil => simp only [List.nil_append] at h1 h2 injection h1 with h3 h4 injection h2 with h5 h6 rw [← h3, ← h5] at hlt exact Or.inl hlt | cons y q' => exfalso rw [List.cons_append] at h1 injection h1 with h3 h4 have := congrArg List.length h4 simp at this omega #print axioms fm_ext_before_is_L #print axioms fm_R_sibling_inv end Sal.EmbedRGA