Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for comparing graphs #85

Merged
merged 1 commit into from
Dec 16, 2019
Merged

Add support for comparing graphs #85

merged 1 commit into from
Dec 16, 2019

Conversation

dsnet
Copy link
Collaborator

@dsnet dsnet commented Mar 27, 2018

Previously, trying to call Equal on a graph would result in a stack-overflow
due to infinite recursion traversing cycles on a graph.
While a vast majority of Go values are trees or acyclic graphs, there exist
a small number of cases where graph equality is required.

As such, we add cycle detection to Equal and define what it means for two graphs
to be equal. Contrary to reflect.DeepEqual, which declares two graphs to be
equal so long any cycle were encountered, we require two graphs to have
equivalent graph structures.

Mathematically speaking, a graph G is a tuple (V, E) consisting of the set of
vertices and edges in that graph. Graphs G1 and G2 are equal if V1 == V2,
E1 == E2, and both have the same root vertex (entry point into the graph).
When traversing G1 and G2, we remember a stack of previously visited edges
ES1 and ES2. If the current edge e1 is in ES1 or e2 is in ES2, then we know that
a cycle exists. The graphs have the same structure when the previously
encountered edge ep1 and ep2 were encountered together.
Note that edges and vertices unreachable from the root vertex are ignored.

Appreciation goes to Eyal Posener (@posener), who proposed a different
(but semantically equivalent) approach in #79, which served as inspiration.

Fixes #74

@dsnet dsnet force-pushed the cycles branch 6 times, most recently from b93aced to 63fa30a Compare March 27, 2018 23:47
@dsnet dsnet changed the title Add support for handling cycles Add support for comparing graphs Mar 27, 2018
@dsnet dsnet force-pushed the cycles branch 3 times, most recently from d897f62 to 99d06a8 Compare March 27, 2018 23:59
@dsnet dsnet requested a review from neild March 28, 2018 00:00
@dsnet
Copy link
Collaborator Author

dsnet commented Mar 28, 2018

@neild for review. I still need to add a lot more unit tests.

cmp/compare.go Outdated
return
}
defer s.curPtrs.Pop(vx, vy)
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop commented-out code here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

cmp/compare.go Outdated
// Report the entire slice as is if the arrays are of primitive kind,
// and the arrays are different enough.
// Checking element pointers is necessary for slices of non-primitives,
// as they may contain slices that sub-slices some parent slice.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: s/sub-slices/sub-slice/

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

cmp/path.go Outdated
// by checking whether the pointer has already been visited. The cycle detection
// uses a seperate stack for the x and y values.
//
// Suppose a cycle were detected, we need to determine whether the two pointers
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If a cycle is detected we need to..."

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

cmp/path.go Outdated
}

// Push indicates intent to descend into pointers vx and vy where
// visited reports whether thay have been seen before. If visited before,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reports whether either has been seen before

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@posener
Copy link

posener commented Jun 9, 2018

@dsnet , it have been a while 😄 , any intentions to merge this?

@dsnet dsnet mentioned this pull request Feb 27, 2019
@dsnet
Copy link
Collaborator Author

dsnet commented Mar 12, 2019

Apologies for the massive delay. This is next on my TODO list in regards to cmp now that the reporter logic has been completely re-written.

@LasTshaMAN
Copy link

Any updates on this ?

@dsnet dsnet force-pushed the cycles branch 2 times, most recently from 6b9e0db to 87e1c3f Compare December 16, 2019 21:10
Previously, trying to call Equal on a graph would result in a stack-overflow
due to infinite recursion traversing cycles on a graph.
While a vast majority of Go values are trees or acyclic graphs, there exist
a small number of cases where graph equality is required.

As such, we add cycle detection to Equal and define what it means for two graphs
to be equal. Contrary to reflect.DeepEqual, which declares two graphs to be
equal so long any cycle were encountered, we require two graphs to have
equivalent graph structures.

Mathematically speaking, a graph G is a tuple (V, E) consisting of the set of
vertices and edges in that graph. Graphs G1 and G2 are equal if V1 == V2,
E1 == E2, and both have the same root vertex (entry point into the graph).
When traversing G1 and G2, we remember a stack of previously visited edges
ES1 and ES2. If the current edge e1 is in ES1 or e2 is in ES2, then we know that
a cycle exists. The graphs have the same structure when the previously
encountered edge ep1 and ep2 were encountered together.
Note that edges and vertices unreachable from the root vertex are ignored.

Appreciation goes to Eyal Posener (@posener), who proposed a different
(but semantically equivalent) approach in #79, which served as inspiration.

Fixes #74
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

proposal: support cyclic data structures
4 participants