Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,25 @@ export class SearchQuotientCluster implements SearchQuotientNode {
split(charIndex: number): [SearchQuotientNode, SearchQuotientNode] {
throw new Error('Method not implemented.');
}

isSameNode(space: SearchQuotientNode): boolean {
// Easiest cases: when the instances or their ' `spaceId` matches, we have
// a perfect match.
if(this == space || this.spaceId == space.spaceId) {
return true;
}

// If it's falsy or a different SearchSpace type, that's an easy filter.
if(!space || !(space instanceof SearchQuotientCluster)) {
return false;
}

// We need to check if the parents match. Done naively in the manner below, this is O(N^2).
// Granted, we shouldn't have _that_ many incoming paths.
if(this.parents.find((path) => !space.parents.find((path2) => path.isSameNode(path2)))) {
return false;
}
Comment on lines +198 to +202
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have to check that this and space have the same number of parents?

Suggested change
// We need to check if the parents match. Done naively in the manner below, this is O(N^2).
// Granted, we shouldn't have _that_ many incoming paths.
if(this.parents.find((path) => !space.parents.find((path2) => path.isSameNode(path2)))) {
return false;
}
if(this.parents.length != space.parents.length) {
return false;
}
// We need to check if the parents match. Done naively in the manner below, this is O(N^2).
// Granted, we shouldn't have _that_ many incoming paths.
if(this.parents.find((path) => !space.parents.find((path2) => path.isSameNode(path2)))) {
return false;
}


return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,12 @@ export interface SearchQuotientNode {
* @param charIndex
*/
split(charIndex: number): [SearchQuotientNode, SearchQuotientNode];

/**
* Determines if the SearchQuotientNode is a duplicate of another instance.
* For such cases, the total search space covered by the quotient-graph
* path(s) taken to reach each must be 100% identical.
* @param node
*/
isSameNode(node: SearchQuotientNode): boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ export class SearchQuotientRoot implements SearchQuotientNode {
return '';
}

isSameNode(space: SearchQuotientNode): boolean {
// Easiest cases: when the instances or their ' `spaceId` matches, we have
// a perfect match.
if(this == space || this.spaceId == space.spaceId) {
return true;
}

// If it's falsy or a different SearchQuotientNode type, that's an easy filter.
if(!space || !(space instanceof SearchQuotientRoot)) {
return false;
}

// The two should be based upon the same LexicalModel.
if(this.model != space.model) {
return false;
}
return true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do these not have parents to check for match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's the 'root' node - there is no parent here.

}

split(charIndex: number): [SearchQuotientNode, SearchQuotientNode] {
return [this, new SearchQuotientRoot(this.model)];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,4 +495,26 @@ export abstract class SearchQuotientSpur implements SearchQuotientNode {
const segment = inputSrc.segment;
return `E${inputSrc.subsetId}:${segment.start}${segment.end !== undefined ? `-${segment.end}` : ''}`;
}

isSameNode(space: SearchQuotientNode): boolean {
// Easiest cases: when the instances or their ' `spaceId` matches, we have
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Easiest cases: when the instances or their ' `spaceId` matches, we have
// Easiest cases: when the instances or their `spaceId` matches, we have

// a perfect match.
if(this == space || this.spaceId == space.spaceId) {
return true;
}

// If it's falsy or a different SearchSpace type, that's an easy filter.
if(!space || !(space instanceof SearchQuotientSpur)) {
return false;
}

// If this spur does not match the exact same edge conditions as the other spur,
// they are not duplicates.
if(this.edgeKey != space.edgeKey) {
return false;
}

// Finally, we recursively verify that the parent matches.
return this.parentNode.isSameNode(space.parentNode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,7 @@ describe('SearchQuotientSpur', () => {
assert.equal(remergedPath.codepointLength, mergeTarget.codepointLength);
assert.sameDeepOrderedMembers(remergedPath.inputSegments, mergeTarget.inputSegments);
assert.isTrue(quotientPathHasInputs(remergedPath, trueDistributions));
assert.isTrue(remergedPath.isSameNode(mergeTarget));
}

it('setup: constructs path properly', () => {
Expand Down Expand Up @@ -1960,6 +1961,7 @@ describe('SearchQuotientSpur', () => {
assert.isTrue(remerged instanceof SearchQuotientSpur);
assert.deepEqual((remerged as SearchQuotientSpur).inputs, inputDistribution);
assert.isTrue(quotientPathHasInputs(remerged, [[startSample], inputDistribution]));
assert.isTrue(remerged.isSameNode(mergeTarget));
});
});
});