Exercise 18: Completed rule implementation

Implement SolveRule and Derive:

SolveRule

SolveRule Input:

A rule.
The derivation target: An ITransOutput that represents what is trying to be derived.

SolveRule Output:

A list of entities. For relationship rules, this will be either null to represent failure or the true entity to represent success. For assignment rules, this will be a list of entities that satisfy the value of the assignment.

SolveRule Algorithm:

Run SolveConditions.
If the resultant list is empty, return an empty list.
If the resultant list isn't empty and the conclusion type is a relation, then return the true entity.
If the resultant list isn't empty and the conclusion type is a property value, then process each result iteratively. Use the conclusion's value specifier to create the result. This can be accomplished by implementing an Eval function for IValueToken which takes a dictionary of variable values, substitutes them, and returns the resultant entity.

For each result:

Add the resultant token to the output list.

Derive

Derive is called with a PropertyToken or RelationshipToken.

Algorithm:

Look up rules that might be able to derive the value/relationship.
For each potential rule, determine whether it is really a match. In the process, determine the value of any variables in the conclusion by doing a token-by-token comparison of the conclusion with the derivation target. Implement this functionality as RuleSolver.Match.
Attempt to solve any rules that match.
If any rules can be solved, return the resulting value, which will be an IEntity for derived property values or a bool for derived relationships.

Test Cases

...

Web UI

Add a new text area to the web UI that allows rules to be specified.
If the answer to a user's question is a property whose value is not known, try to derive it. If it can be derived, return the result. Always indicate whether a value was derived.