A successor is a fact which references another. It is the opposite of a predecessor. A predecessor can query for its successors.

Add the logOns query to the Machine fact:
fact Machine {
key:
    unique;
    
query:
    LogOn* logOns {
        LogOn l : l.machine = this
    }
}

The type of the query is "LogOn*". The asterisk indicates that there are many LogOn facts returned.

The query is defined using set notation. The colon is pronounced "such that". The query reads: "logsOns is the set of all LogOns l such that l.machine is this Machine". It is essentially the same as a relational join.

You can access a query via its read-only collection property.
[TestMethod]
public void InitiallyNoUserIsLoggedOn()
{
    Machine machine = _community.AddFact(new Machine());

    Assert.IsFalse(machine.LogOns.Any());
}
When you create a fact that satisfies a query, it is automatically added to the results.
[TestMethod]
public void UserIsLoggedOn()
{
    User user = _community.AddFact(new User("alan1"));
    Machine machine = _community.AddFact(new Machine());
    LogOn logOn = _community.AddFact(new LogOn(user, machine));

    Assert.AreSame(logOn, machine.LogOns.Single());
}
The cardinality of a query is always many (*). You cannot guarantee that a query returns only one result. I used "Single" in the unit test to verify that the query had exactly one result, but you should never use "Single" in production code. You cannot assume that only one fact will match the query.

A fact can define queries. Each query is expressed in set notation. It selects the facts whose predecessor is the starting point. Those facts are called successors. You access the results of a query using a read-only collection property. Successors are automatically added to the collection.

Next: Practice 1: Define a query

Last edited May 15, 2011 at 3:24 AM by MichaelLPerry1971, version 9

Comments

No comments yet.