Zulip Chat Archive

Stream: lean4

Topic: paths using arrays


Dean Young (May 04 2023 at 14:30):

What is the easiest way to require something like

 (L.get (i)).snd= (L.get (i+1)).fst

for each i in the appropriate index, and where L is a list of "pairs".

I'm trying to define paths in a graph. It's specifically important that these paths
be stored as arrays with extra information. I also want a path of length 0 to be stored as an empty array. All this is because I want Lean to be able to run an equality check on two different paths without much effort later on.

-- a graph consists of:
structure graph where
    V : Type    -- a type of vertices
    E : Type    -- a type of edges, such that
    d₀ : E  V  -- each edge has a head
    d₁ : E  V  -- each edge has a tail



structure edge (G : graph) where
    e : G.E
    v₀ : G.V
    v₁ : G.V
    p₀ : G.d₀ e = v₀
    p₁ : G.d₁ e = v₁

open List

def matches (G : graph) (edges : List (edge G)) (i : Fin (edges.length)) (p : i < edges.length - 1) : Prop := sorry

/-
I need n < m ↔ succ n < succ m
-/

structure path (G : graph) where
    edges : List (edge G)
    beginning : (edges.length = 0)  G.V -- marks the starting vertex for paths of length 0
--  sequential : ??? some condition must ensure that the path is sequential

/-
here, some condition must ensure that the path is
in fact a path, but I'd like some help figuring out the
best way to index the list (I'm completely new to them)
-/

def pointpath {G : graph} (v : G.V) : path G := {edges := [], beginning := λ (_: [].length = 0) => v}

def domain {G : graph} (p : path G) (q : p.edges.length  0) : G.V := sorry

def codomain {G : graph} (p : path G) (q : p.edges.length  0) : G.V := sorry

def concatenate {G : graph} (p₀ : path G) (p₁ : path G) : (path G) := sorry

Jeremy Salwen (May 04 2023 at 17:35):

Not an expert, but my understanding would be that there would be many different ways to represent the condition, each of which might be appropriate if you use that style of proposition in your proofs.

For example, you could encode it using indices to say [i] and [i+1] are connected: forall i, edges[i].v1 = edges[i+1].v0
You could also use isInfix with a list of size two: forall e1 e2, [e1, e2] <:+: edges -> e1.v1 = e2.v0
You could also do a recursive definition: sequential := l.head.v1 = l.tail.head.v1 ∧ sequential l.tail

etc, etc

You could also represent a path as a list of vertices, with the attached proof showing that it only passes through valid edges.

I think the key thing is that you can prove the equivalence of these different statements, and transform it to the form you need for a specific proof. So a good starting point is thinking about which form would be easiest to use as a hypothesis to use in your proofs, and start there.

Eric Wieser (May 04 2023 at 22:19):

Are you aware of docs#simple_graph.walk?

Dean Young (May 09 2023 at 23:31):

oh thanks, that's great


Last updated: Dec 20 2023 at 11:08 UTC