sparql-view-unfold
    Preparing search index...

    Class TermClusterSet<T, Term>

    A ClusterSet whose groups may be pinned: every value in the group equals what the pin says - a term, or the shape of a triple term whose positions are groups in their own right.

    Its two users differ in what a pin conflict means, which is why setPin reports one rather than raising it: for the unfolding (ClusterSolver) a group asked to be two terms at once is a broken mapping, for an assertion conjunction it is an ordinary contradiction. They also differ in the terms a pin may hold, hence the second type parameter, and in what meeting two pins comes to, hence meetPins.

    Ranges live here rather than only in the solver, since the same question is asked on both sides: a group in a subject position holds no Literal and no triple term, which is what confines the nesting of shapes to the object chain.

    A pin makes the child DAG a real graph, and two invariants keep it well founded:

    • occurs check: a group may not reach itself through the pins, ?o ≡ <<( ?o ... )>> having no solution. Checked once a whole work list settles rather than as each pin lands, since a merge closes a cycle just as a pin does - and only from the groups that work list touched, the rest of the graph having been acyclic before it ran (hasCycle).
    • liveness: a group that is the child of a live pin survives remove however few members it has left, or the pin pointing at it would dangle.

    Type Parameters

    • T
    • Term extends { termType: RDF.Term["termType"] }

    Hierarchy (View Summary)

    Index

    Constructors

    • Type Parameters

      • T
      • Term extends {
            termType:
                | "NamedNode"
                | "BlankNode"
                | "Literal"
                | "Variable"
                | "DefaultGraph"
                | "Quad";
        }

      Parameters

      • toId: (value: T) => string

        How to transform a value into its string key

      • meetPins: (a: Pin<Term>, b: Pin<Term>) => false | PinMeet<Term>

        Meets the two pins a group is asked to carry at once, reporting false when no value satisfies both

      Returns TermClusterSet<T, Term>

    Properties

    acyclic: boolean

    Whether the last work list to settle left the pins acyclic, which is what lets hasCycle start from the groups a run touched rather than from every group there is. Cleared by a run that gives up halfway, since the constraints it did establish may have closed a cycle nothing went on to check.

    false is not known to be acyclic, never cyclic. Nothing reads it as an answer: all it decides is where hasCycle starts from, so being wrong about it the safe way costs a walk of every group and nothing else.

    cleanNumber: number

    Counter for generating unique group IDs

    groupMergeHistory: Record<number, number>

    A history of oldGroups (keys) that got merged into newGroups (values). Needed to dereference removed groups still used in a pin.

    groupToPin: Record<number, Pin<Term> | undefined>

    Maps group ID to what the group is pinned to (if anything) - read through pinOf.

    groupToRange: Record<number, RangeSet>

    Maps group ID to the term types its value may have - read through rangeOf.

    groupToValues: Record<number, T[]>

    Maps group ID to the values in it - read through valuesOf and groupEntries.

    meetPins: (a: Pin<Term>, b: Pin<Term>) => false | PinMeet<Term>

    Meets the two pins a group is asked to carry at once, reporting false when no value satisfies both

    pinChildToOwners: Record<number, Set<number>>

    The reverse of childrenOf, keyed by resolved group: the groups whose shape holds this one in one of its positions. It is what isPinChild reads instead of walking every pin there is, that question being asked on every ClusterSet.remove.

    Kept as an over-approximation the lookup verifies against the pins themselves, so that the only thing maintenance owes it is never to lose an owner: entries move with the group they are keyed by (migrateGroupData) and are dropped with it (dropGroup), while an owner whose pin has moved on is pruned the next time it is read.

    toId: (value: T) => string
    valueToGroup: Record<string, number | undefined>

    Maps a value to the group it is in - read through groupOf.

    Accessors

    • get revision(): number

      The state the set is in, as a stamp that no two states of any two sets share.

      Every method that writes anything moves it on (touch), so a memo taken off the set is valid for exactly as long as this is what it was taken at - which is a check the memo cannot forget to make, there being nothing to invalidate.

      Returns number

    Methods

    • Gives a group the shape of a triple term, creating an anonymous group per position where it has none.

      Parameters

      • group: number

        The group to shape

      Returns false | Readonly<Record<TriplePosition, number>>

      the group per position, or false when the group cannot hold a triple term

    • The positions of the shape a group is pinned to.

      Parameters

      • group: number

        The group to look up

      Returns Readonly<Record<TriplePosition, number>> | undefined

      the group per position, or undefined when it is not pinned to a shape

    • The group a value is in, without creating one for it - the read-only counterpart of getGroup.

      Parameters

      • value: T

        The value to look up

      Returns number | undefined

      the group ID, or undefined when the value is in no group

    • Whether any group is its own descendant, which no value satisfies: a triple term is strictly larger than each of its components, so ?o ≡ <<( ?o ... )>> is unsatisfiable - and resolving such a group to a term would not terminate.

      Descending from touched alone is the whole graph's answer whenever the graph was acyclic before the run (acyclic): a cycle that holds none of the groups the run pinned or merged holds none of its new edges either - the pins of those groups are the only ones it changed, and a merge is the identification of two groups into one of them - so it was there to be found on the way in. Where that does not hold, every group is a root again.

      Parameters

      • touched: readonly number[]

        The groups the run that is settling pinned or merged

      Returns boolean

      whether the pins close a cycle

    • A group a live pin points at survives however few members it has: it is a position of a shape, and dropping it would leave that shape naming a group that is no longer there.

      Parameters

      • group: number

        The group to check

      Returns boolean

      whether it is worth keeping

    • Whether some group's shape holds this one in one of its positions, read off pinChildToOwners and checked against the pins of the owners it names - which is also where an owner that no longer points here is pruned.

      Parameters

      • group: number

        The group to look for

      Returns boolean

      whether anything points at it

    • Merges two groups by id, which is what a group nothing names can be merged by - the values-only half of a merge, whatever else a subclass hangs off a group being migrated by migrateGroupData.

      Parameters

      • fromGroup: number

        One group

      • toGroup: number

        The other

      Returns { newGroup: number; oldGroup: number } | undefined

      the ids involved, or undefined when the two ids are the same group

    • Merges two groups, carrying over everything the disappearing one held.

      Parameters

      • from: T

        One of the values whose group to merge

      • to: T

        The other

      Returns { conflict: boolean; newGroup: number; oldGroup: number } | undefined

      the ids involved and whether the two could not hold the same value, which leaves the set in a state no caller may read - what to do about that is up to the two subclasses; undefined when both values were already in one group

    • Narrows what terms a group's value may have.

      Parameters

      • group: number

        The group to narrow

      • range: RangeSet

        The term types to narrow it to

      Returns boolean

      false when nothing is left for it to be, or when its pin is not one of those terms

    • Whether the pin - if there is one - is a term the group's range still admits.

      Parameters

      • group: number

        The group whose range to read

      • pin: Pin<Term> | undefined

        The pin to check

      Returns boolean

      whether the two agree

    • Records a group as an owner of every position of the pin it just took on.

      Parameters

      • owner: number

        The group carrying the pin

      • pin: Pin<Term> | undefined

        The pin it carries, positions of which are groups when it is a shape

      Returns void

    • Dereferences a group id through the merge history.

      Parameters

      • group: number

        The id to resolve

      Returns number

      the group it has become, or itself when it is still its own group

    • Pins a group, meeting the pin with whatever the group already carries and draining everything that meet decides (PinMeet).

      Parameters

      • group: number

        The group to pin

      • pin: Pin<Term>

        What every value of it equals

      Returns boolean

      false on a contradiction, after which the set holds no meaningful state

    • Pins a term onto a group.

      Parameters

      • group: number

        The group to pin

      • term: Term

        The term every value of it equals

      Returns boolean

      false when the group already carries something incompatible, which leaves the set in a state no caller may read

    • The term a group is pinned to.

      Parameters

      • group: number

        The group to look up

      Returns Term | undefined

      the term, or undefined when nothing pins it, or a shape does instead

    • Unifies two groups by id - the merge mergeGroups is, for the groups no value names.

      Parameters

      • left: number

        One group

      • right: number

        The other

      Returns boolean

      false when the two cannot hold the same value

    • Takes a group back out as an owner of the positions of a pin it no longer carries.

      Parameters

      • owner: number

        The group that carried the pin

      • pin: Pin<Term> | undefined

        The pin it is losing

      Returns void