Cortex.Graph.Quotient


On this page
  1. Overview
  2. Context
  3. Theorem Split
  4. GraphEq Setoid
  5. Quotient Carrier
  6. Lifted Operations
  7. Mokhov Laws as Quotient Equality
  8. Operator Restatements
Imports

Overview

Quotient carrier for Mokhov's algebraic graph laws.

Context

Cortex.Graph.Core.Graph is the raw expression syntax. Its constructors remember how a graph was written, so algebraic identities such as overlay empty g = g are false as raw AST equality. Cortex.Graph.Laws therefore exposes the law surface through GraphEq, equality of finite relation denotations.

This module packages that relation as a quotient carrier, AlgGraph. On AlgGraph, Mokhov's laws hold as ordinary Lean equality while raw Graph remains available for syntax-directed recursion, compilation, and expression metrics.

The module is intentionally proof infrastructure. Existing Pulse and Wire modules continue to use raw Graph and GraphEq until a proof needs quotient-level rewriting.

Theorem Split

The page first proves GraphEq is an equivalence and that overlay and connect respect it. It then defines the quotient carrier, lifts the graph operations, and restates Mokhov's law set with =.

namespace Cortex.Graphvariable {α : Type} [DecidableEq α]

GraphEq Setoid

namespace GraphEq

GraphEq is reflexive.

theorem refl (g : Graph α) : GraphEq g g := rfl

GraphEq is symmetric.

theorem symm {g h : Graph α} (hEq : GraphEq g h) : GraphEq h g := Eq.symm hEq

GraphEq is transitive.

theorem trans {g h k : Graph α} (hLeft : GraphEq g h) (hRight : GraphEq h k) : GraphEq g k := Eq.trans hLeft hRight

overlay respects denotational equality in both arguments.

theorem overlay {g g' h h' : Graph α} (hLeft : GraphEq g g') (hRight : GraphEq h h') : GraphEq (Graph.overlay g h) (Graph.overlay g' h') := α:Typeinst✝:DecidableEq αg:Graph αg':Graph αh:Graph αh':Graph αhLeft:GraphEq g g'hRight:GraphEq h h'GraphEq (g.overlay h) (g'.overlay h') α:Typeinst✝:DecidableEq αg:Graph αg':Graph αh:Graph αh':Graph αhLeft:GraphEq g g'hRight:GraphEq h h'denote (g.overlay h) = denote (g'.overlay h') α:Typeinst✝:DecidableEq αg:Graph αg':Graph αh:Graph αh':Graph αhLeft:GraphEq g g'hRight:GraphEq h h'(denote g).overlay (denote h) = (denote g').overlay (denote h') All goals completed! 🐙

connect respects denotational equality in both arguments.

theorem connect {g g' h h' : Graph α} (hLeft : GraphEq g g') (hRight : GraphEq h h') : GraphEq (Graph.connect g h) (Graph.connect g' h') := α:Typeinst✝:DecidableEq αg:Graph αg':Graph αh:Graph αh':Graph αhLeft:GraphEq g g'hRight:GraphEq h h'GraphEq (g.connect h) (g'.connect h') α:Typeinst✝:DecidableEq αg:Graph αg':Graph αh:Graph αh':Graph αhLeft:GraphEq g g'hRight:GraphEq h h'denote (g.connect h) = denote (g'.connect h') α:Typeinst✝:DecidableEq αg:Graph αg':Graph αh:Graph αh':Graph αhLeft:GraphEq g g'hRight:GraphEq h h'(denote g).connect (denote h) = (denote g').connect (denote h') All goals completed! 🐙end GraphEq

graphSetoid α identifies raw graph expressions with the same denotation.

def graphSetoid (α : Type) [DecidableEq α] : Setoid (Graph α) where r := GraphEq iseqv := { refl := GraphEq.refl symm := GraphEq.symm trans := GraphEq.trans }

Quotient Carrier

AlgGraph α is the algebraic graph carrier modulo denotational equality.

def AlgGraph (α : Type) [DecidableEq α] : Type := Quotient (graphSetoid α)namespace AlgGraph

Embed a raw graph expression into the quotient carrier.

def ofGraph (g : Graph α) : AlgGraph α := Quotient.mk (graphSetoid α) g

Raw GraphEq is exactly equality after embedding into AlgGraph.

theorem ofGraph_eq_iff {g h : Graph α} : ofGraph g = ofGraph h GraphEq g h := Quotient.eq

Turn a raw GraphEq proof into quotient equality.

theorem eq_of_graphEq {g h : Graph α} (hEq : GraphEq g h) : ofGraph g = ofGraph h := Quotient.sound hEq

Recover raw GraphEq from quotient equality between embedded expressions.

theorem graphEq_of_eq {g h : Graph α} (hEq : ofGraph g = ofGraph h) : GraphEq g h := Quotient.exact hEq

Denote a quotient graph by lifting Cortex.Graph.denote from raw graph syntax.

def denote : AlgGraph α Relation α := Quotient.lift Cortex.Graph.denote (fun _ _ hEq => hEq)@[simp] theorem denote_ofGraph (g : Graph α) : denote (ofGraph g) = Cortex.Graph.denote g := rfl

Quotient equality is equality of denotations.

theorem eq_iff_denote_eq (g h : AlgGraph α) : g = h denote g = denote h := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αg = h g.denote = h.denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph α (a b : Graph α), a = b denote a = denote b intro rawG α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αrawG:Graph αrawH:Graph αrawG = rawH denote rawG = denote rawH α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αrawG:Graph αrawH:Graph αofGraph rawG = ofGraph rawH Graph.denote rawG = Graph.denote rawH All goals completed! 🐙

Lifted Operations

Empty algebraic graph.

def empty : AlgGraph α := ofGraph Graph.empty

Singleton-vertex algebraic graph.

def vertex (v : α) : AlgGraph α := ofGraph (Graph.vertex v)

Algebraic overlay, lifted from raw graph expressions.

def overlay : AlgGraph α AlgGraph α AlgGraph α := Quotient.lift₂ (fun g h => ofGraph (Graph.overlay g h)) (fun _ _ _ _ hLeft hRight => Quotient.sound (GraphEq.overlay hLeft hRight))

Algebraic connect, lifted from raw graph expressions.

def connect : AlgGraph α AlgGraph α AlgGraph α := Quotient.lift₂ (fun g h => ofGraph (Graph.connect g h)) (fun _ _ _ _ hLeft hRight => Quotient.sound (GraphEq.connect hLeft hRight))instance : Add (AlgGraph α) where add := overlayinstance : Mul (AlgGraph α) where mul := connect@[simp] theorem overlay_ofGraph (g h : Graph α) : overlay (ofGraph g) (ofGraph h) = ofGraph (Graph.overlay g h) := rfl@[simp] theorem connect_ofGraph (g h : Graph α) : connect (ofGraph g) (ofGraph h) = ofGraph (Graph.connect g h) := rfl@[simp] theorem denote_empty : denote (α := α) empty = Relation.empty := rfl@[simp] theorem denote_vertex (v : α) : denote (vertex v) = Relation.vertex v := rfl@[simp] theorem denote_overlay (g h : AlgGraph α) : denote (overlay g h) = Relation.overlay (denote g) (denote h) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph α(g.overlay h).denote = g.denote.overlay h.denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph α (a b : Graph α), (overlay a b).denote = (denote a).overlay (denote b) intro rawG α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αrawG:Graph αrawH:Graph α(overlay rawG rawH).denote = (denote rawG).overlay (denote rawH) All goals completed! 🐙@[simp] theorem denote_connect (g h : AlgGraph α) : denote (connect g h) = Relation.connect (denote g) (denote h) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph α(g.connect h).denote = g.denote.connect h.denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph α (a b : Graph α), (connect a b).denote = (denote a).connect (denote b) intro rawG α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αrawG:Graph αrawH:Graph α(connect rawG rawH).denote = (denote rawG).connect (denote rawH) All goals completed! 🐙

Mokhov Laws as Quotient Equality

empty is a left identity for quotient overlay.

theorem overlay_empty_left (g : AlgGraph α) : overlay empty g = g := α:Typeinst✝:DecidableEq αg:AlgGraph αempty.overlay g = g α:Typeinst✝:DecidableEq αg:AlgGraph α(empty.overlay g).denote = g.denote α:Typeinst✝:DecidableEq αg:AlgGraph αRelation.empty.overlay g.denote = g.denote All goals completed! 🐙

empty is a right identity for quotient overlay.

theorem overlay_empty_right (g : AlgGraph α) : overlay g empty = g := α:Typeinst✝:DecidableEq αg:AlgGraph αg.overlay empty = g α:Typeinst✝:DecidableEq αg:AlgGraph α(g.overlay empty).denote = g.denote α:Typeinst✝:DecidableEq αg:AlgGraph αg.denote.overlay Relation.empty = g.denote All goals completed! 🐙

empty is a two-sided identity for quotient overlay.

theorem overlay_empty (g : AlgGraph α) : overlay empty g = g overlay g empty = g := overlay_empty_left g, overlay_empty_right g

empty is a left identity for quotient connect.

theorem connect_empty_left (g : AlgGraph α) : connect empty g = g := α:Typeinst✝:DecidableEq αg:AlgGraph αempty.connect g = g α:Typeinst✝:DecidableEq αg:AlgGraph α(empty.connect g).denote = g.denote α:Typeinst✝:DecidableEq αg:AlgGraph αRelation.empty.connect g.denote = g.denote All goals completed! 🐙

empty is a right identity for quotient connect.

theorem connect_empty_right (g : AlgGraph α) : connect g empty = g := α:Typeinst✝:DecidableEq αg:AlgGraph αg.connect empty = g α:Typeinst✝:DecidableEq αg:AlgGraph α(g.connect empty).denote = g.denote α:Typeinst✝:DecidableEq αg:AlgGraph αg.denote.connect Relation.empty = g.denote All goals completed! 🐙

empty is a two-sided identity for quotient connect.

theorem connect_empty (g : AlgGraph α) : connect empty g = g connect g empty = g := connect_empty_left g, connect_empty_right g

Quotient overlay is commutative. Mokhov Theorem 1.

theorem overlay_comm (g h : AlgGraph α) : overlay g h = overlay h g := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αg.overlay h = h.overlay g α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph α(g.overlay h).denote = (h.overlay g).denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αg.denote.overlay h.denote = h.denote.overlay g.denote All goals completed! 🐙

Quotient overlay is associative. Mokhov Theorem 2.

theorem overlay_assoc (g h k : AlgGraph α) : overlay (overlay g h) k = overlay g (overlay h k) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.overlay h).overlay k = g.overlay (h.overlay k) α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α((g.overlay h).overlay k).denote = (g.overlay (h.overlay k)).denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.denote.overlay h.denote).overlay k.denote = g.denote.overlay (h.denote.overlay k.denote) All goals completed! 🐙

Quotient connect is associative. Mokhov Theorem 4.

theorem connect_assoc (g h k : AlgGraph α) : connect (connect g h) k = connect g (connect h k) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.connect h).connect k = g.connect (h.connect k) α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α((g.connect h).connect k).denote = (g.connect (h.connect k)).denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.denote.connect h.denote).connect k.denote = g.denote.connect (h.denote.connect k.denote) All goals completed! 🐙

Quotient connect distributes over overlay on the left. Mokhov Theorem 6.

theorem connect_distrib_overlay_left (g h k : AlgGraph α) : connect g (overlay h k) = overlay (connect g h) (connect g k) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph αg.connect (h.overlay k) = (g.connect h).overlay (g.connect k) α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.connect (h.overlay k)).denote = ((g.connect h).overlay (g.connect k)).denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph αg.denote.connect (h.denote.overlay k.denote) = (g.denote.connect h.denote).overlay (g.denote.connect k.denote) All goals completed! 🐙

Quotient connect distributes over overlay on the right.

theorem connect_distrib_overlay_right (g h k : AlgGraph α) : connect (overlay g h) k = overlay (connect g k) (connect h k) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.overlay h).connect k = (g.connect k).overlay (h.connect k) α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α((g.overlay h).connect k).denote = ((g.connect k).overlay (h.connect k)).denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.denote.overlay h.denote).connect k.denote = (g.denote.connect k.denote).overlay (h.denote.connect k.denote) All goals completed! 🐙

Quotient connect decomposition. Mokhov Theorem 8.

theorem connect_decomposition (g h k : AlgGraph α) : connect (connect g h) k = overlay (overlay (connect g h) (connect g k)) (connect h k) := α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.connect h).connect k = ((g.connect h).overlay (g.connect k)).overlay (h.connect k) α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α((g.connect h).connect k).denote = (((g.connect h).overlay (g.connect k)).overlay (h.connect k)).denote α:Typeinst✝:DecidableEq αg:AlgGraph αh:AlgGraph αk:AlgGraph α(g.denote.connect h.denote).connect k.denote = ((g.denote.connect h.denote).overlay (g.denote.connect k.denote)).overlay (h.denote.connect k.denote) All goals completed! 🐙

Operator Restatements

Quotient overlay commutativity through the + notation.

theorem overlay_comm_add (g h : AlgGraph α) : g + h = h + g := overlay_comm g h

Quotient connect associativity through the * notation.

theorem connect_assoc_mul (g h k : AlgGraph α) : g * h * k = g * (h * k) := connect_assoc g h k

Quotient connect decomposition through the + and * notation.

theorem connect_decomposition_mul (g h k : AlgGraph α) : g * h * k = (g * h) + (g * k) + (h * k) := connect_decomposition g h kend AlgGraphend Cortex.Graph