A fact is identified by its key fields. A key field may either be a simple data type or a reference to another fact. If it is another fact, that fact is called a predecessor.

Starting from the results of lesson 1b, add the following fact to the model:
fact LogOn {
key:
    User user;
    Machine machine;
}

LogOn records the fact that a user has logged on to a machine. It has references to both the user and the machine. Just like other kinds of key fields, you set these in the constructor and access them via read-only properties.
[TestMethod]
public void UserLogsOnToAMachine()
{
    User user = _community.AddFact(new User("alan1"));
    Machine machine = _community.AddFact(new Machine());
    LogOn logOn = _community.AddFact(new LogOn(user, machine));

    Assert.AreSame(user, logOn.User);
    Assert.AreSame(machine, logOn.Machine);
}
The key fields are immutable. The following code does not compile.
[TestMethod]
public void PredecessorsAreImmutable()
{
    User user = _community.AddFact(new User("alan1"));
    Machine machine = _community.AddFact(new Machine());
    LogOn logOn = _community.AddFact(new LogOn(user, machine));

    User flynn = _community.AddFact(new User("flynn1"));
    logOn.User = flynn;
}
Key fields identify a fact. So if you try to create a new LogOn with the same User and Machine, you will get back the same one. The following test fails:
[TestMethod]
public void UserLogsOnTwice()
{
    User user = _community.AddFact(new User("alan1"));
    Machine machine = _community.AddFact(new Machine());
    LogOn logOn1 = _community.AddFact(new LogOn(user, machine));
    LogOn logOn2 = _community.AddFact(new LogOn(user, machine));

    Assert.AreNotSame(logOn1, logOn2);
}
That isn't the behavior we want for LogOn. We want to record each individual log on event as a separate fact. So we have to add the "unique" keyword.
fact LogOn {
key:
    unique;
    User user;
    Machine machine;
}

After transforming the template and building the solution, the test passes.

References to other facts are called predecessors. A predecessor behaves just like any other key field: it identifies the fact and it is immutable. You set it during construction, and you can access it using a read-only property.

Next: Lesson 1d: Successors

Last edited May 15, 2011 at 4:23 AM by MichaelLPerry1971, version 4

Comments

No comments yet.