Home

Products

Documentation

Download

Support

 

Documentation

Language Specification - Precondition (PRE) - Semantics


Prev

Description

Syntax

Semantics

Next


Precondition modifiers

A precondition is defined with one of four modifiers: known, knownval, unknown, or not. The modifier for a precondition may be omitted; in this case, the modifier defaults to ‘known’ for a novalcomparison (no right-hand-side value) and to ‘knownval’ for an evalcomparison (a right-hand-side value is present). The modifiers have the following meaning.

known:

The modifier ‘known’ represents the possibility for an agent/object to have a belief/fact, but be unspecific as to whether the agent/objects knows the actual value.

For example, to evaluate the following precondition:

known (car1.color)

The simulation engine would simply check with the belief set of an agent to see whether the agent has a belief of the form:

car1.color = ?

If the engine finds a belief of this form, as it would when the following belief is present:

car1.color = red

then the engine would evaluate the precondition as true. A simple relational precondition like:

known (John is-the-son-of)

will evaluate to true when the engine finds the beliefs (the right hand side and truth-value are completely ignored):

John is-the-son-of Bill is true
John is-the-son-of Bill is false
John is-the-son-of Jack is true
John is-the-son-of Jack is false

A more complex precondition like:

known (Cimap-order1.service-tech is-the-son-of)

will evaluate to true if the following beliefs are present:

Cimap-order1.service-tech = <agent1>
<agent1> is-the-son-of

where <agent1> is either an agent or object.

knownval:

The modifier ‘knownval’ (known value) means that the simulation engine must find a precise match for the precondition. The precondition is only true if matching beliefs/facts can be found for both the left hand side and the right hand side and if the relation between them is found as well. For example for a complex precondition such as:

knownval(Cimap-order1.service-tech is-the-son-of Cimap-order2.service-tech)

the following beliefs must be present:

Cimap-order1.service-tech = <agent1>
Cimap-order2.service-tech = <agent2>
<agent1> is-the-son-of <agent2>

When using variables, the engine will find as many matches as there are valid instantiations for the variables.

unknown (a.k.a. no-knowledge-of):

When the modifier ‘unknown’ is used, the simulation engine looks at the beliefs of the agent or facts in the world for objects for possible matches of the precondition. If there are any matches, the precondition evaluates to false, if no matches are found the precondition evaluates to true. The ‘unknown’ modifier can be interpreted as ‘The agent/object has no beliefs/facts for <precondition>’. However, there are intricacies that need to be explained further.

When matching a precondition of the form: O1A1, the simulation engine looks for a belief of the form O1A1= ?. When a belief of the form O1A1= ? is found, the simulation engine interprets this to mean that the agent ‘knows’ about this object and attribute and thus the precondition is false.

When the precondition is of the form O1 rel however, no matter what the right hand side or the truth of the relation is, the simulation engine will simply look up whether the agent/object possesses the belief/fact O1 rel ?, and if so will evaluate the precondition to be false.

All other preconditions, require at least two steps for the simulation engine to determine the truth or falsehood of the precondition.

The form O1A1 rel requires the simulation engine to evaluate first the O1A1 then the result of the O1A1 (say O2) with the relation. When a belief/fact for either the OA or for O2 rel is not found, the precondition will be evaluated to true, if both are found the precondition will evaluate to false. For example given the following beliefs:

John.car = car1
car1 is-drive-by Jack

and the precondition:

unknown (John.car is-driven-by)

The simulation engine will evaluate the precondition to false, because it finds beliefs for "John.car = ?" with the value car1 and it finds a belief for "car1 is-drive-by ?". If either of the beliefs were not available the precondition would evaluate to true.

not (a.k.a. no-matching-beliefs):

Not works similar to unknown in that when there is no belief for the precondition specified with the not modifier the precondition will evaluate to true. If a belief does exist for the condition in the precondition then the not modifier works similar to the modifier knownval, but negates the resulting truth-value. The simulation engine will first try the knownval for the precondition. If the precondition with the knownval modifier evaluates to true then the precondition with the not modifier evaluates to false and vice versa.

Precondition Evaluation Order

When variables are used in one or more precondition(s) the order in which the preconditions are specified is important. Depending on the order different outcomes are possible. The reason that precondition order is important is that the simulation engine is not a standard pattern matcher, but actually evaluates the preconditions causing potential assignments of values to variables. For example:

knownval(John.car = <car>)

The simulation engine tries to find a belief of the form ‘John.car=’. If it finds one stating ‘John.car=car1’ then it will assign the value car1 to the variable <car>.

If you were to write the following two preconditions in the following order the outcome might be unexpexted:

not(John.car = <car>)
knownval(<car> belongs-to <company>)

Suppose we have the following beliefs:

John.car = car1
car2 belongs-to nynex

The simulation engine will evaluate the first precondition first and first treat the precondition as a knownval therefor assigning the value ‘car1’ to the variable <car> because it matches the precondition with the belief ‘John.car = car1’. Since this precondition is a not this precondition will always evaluate to false. The simulation engine would not continue but if it would then the simulation engine would verify the second precondition. It found a binding for the <car> variable and will substitute its value. It will then try to find a belief of the form ‘car1 belongs-to <company>. It cannot find such a belief and therefor will fail the evaluation causing the frame not to be made available. However if you turn the preconditions around the outcome is different.

knownval(<car> belongs-to <company>)
not(John.car = <car>)

In this case <car> will be bound to car2, the first precondition evaluates to true. The second precondition will be evaluated and the simulation engine tries to find the belief ‘John.car=car2’, it cannot find such a belief but due to the ‘not’ modifier the precondition will evaluate to true causing the frame to be made available.

The precondition ordering will also be important when taking into account the use of variables. The next section discusses the distinction made by the simulation engine in the types variables and how that can affect the importance of the precondition order.

Pre-, Post- and Unassigned Variables

The simulation engine makes a distinction in how variables are bound in a frame. The three types of value assignments are pre-assigned, post-assigned and unassigned.

Unassigned variables are variables not used in any preconditions but that get their binding in an activity.

Pre-assigned variables are variables that get their values assigned in preconditions and get a pre-binding before the preconditions are evaluated. Pre-assigned variables are variables used in an object/attribute tuple (OA) or that are used in an object/relation tuple (OR) or object/relation/object triplet (ORO) where the object is a variable. In case of the ORO it could be one of the objects that is a variable or both. The simulation engine makes sure that for each OA, OR (with an (un)known modifier) and ORO there is at least one matching belief/fact before fully evaluating the preconditions. The variables used in these condition elements will get a pre-binding by matching the variables with the object values in the beliefs/facts. A final binding will be determined when the preconditions are evaluated.

Post-assigned variables are variables that get their values assigned in preconditions as well, but they will get a binding during the evaluation of the preconditions. These variables have no pre-binding like pre-assigned variables do. Post-assigned variables are the variables not used in any OA, OR, ORO condition elements but are usually ‘assignment’ variables specified on the left hand side or right hand side of a value condition, for example:

<myagent>.car = <mycar>

<myagent> is part of an OA pair and is therefor a post-assigned variable. <mycar> is not specified in any OA, OR, ORO condition element and is therefor a post-assigned variable. The simulation engine will have found potential matched for the OA and will have pre-bound the <myagent> variable. During the evaluation of the precondition the simulation engine will then for each value of <myagent> get the belief/fact that caused that value binding for <myagent> and retrieve its right hand side. Assume that the belief was:

John.car = car1

<myagent> is John and the right hand side is ‘car1’. The simulation engine will now assigne the value ‘car1’ to the variable <mycar> during the evaluation of the precondition.

Due to the distinction between pre- and post-assigned variables ordering of preconditions is also important if no conflicts are to occur with the constraints listed below. Assume a frame with the following preconditions:

knownval(<totalOrders> = <numVMOrders>+Builder.numOrders) knownval(VM.numOrders = <numVMOrders>)

In this case the first precondition has two post-assigned variables <totalOrders> and <numVMOrders>. The simulation engine can resolve Builder.numOrders to a value but cannot resolve the values for the post-assigned variables. This would be an endless list of possible values. The simulation engine would report an error and fail the evaluation of the precondition. If the preconditions would now be reversed

knownval(VM.numOrders = <numVMOrders>) 
knownval(<totalOrders> = <numVMOrders>+Builder.numOrders)

then the simulation engine resolves the <numVMOrders> post-assigned variable first, it will bind a value to it by finding a belief of the form VM.numOrders = ? and assigning the right hand side value to the variable. Then during the evaluation of the second precondition the <numVMOrders> variable will have a value bound to it that can be used together with the right hand side value of the belief Builder.numOrders = ? to assign a value to <totalOrders>. The evaluation of all preconditions will succeed and the frame can be made available.

Constraints

  1. The left hand side attribute type and the right hand side value-type or right hand side attribute type of a value-expression must be the same, except in the case of an attribute being of a collection type and an index having been specific for the attribute, in that case any value can be assigned, if no index is specified however only unknown is valid or an expression resulting in the same collection type. If an object-attribute-index is used on the left or right hand side to resolve to a value then the type compatibility constraint is relaxed, the compiler will assume that a value of the correct type is returned to compare to the left or right hand side. The virtual machine will at run-time ensure that type compatibility holds, if not it will evaluate the precondition to false and generate a warning message in the log.

  2. The left hand side and right hand side types in a relational expression must match the types as defined for the relation used in the relational expression. Only the right hand side can be defined to use an object-attribute-index. The compiler will allow this without type checking, the compiler will assume that a value of the correct type is returned for the relation. The virtual machine will at run-time ensure that type compatibility holds, if not it will evaluate the precondition to false and generate a warning message in the log. The use of object-attribute-index on the left hand side would resolve to an unknown type not allowing the compiler to verify whether the relation is declared for that type and is therefore not permitted.

  3. Expressions must evaluate to a value of type int, long or double.

  4. No nested expressions are allowed. The first release of the virtual machine will not support them yet. As soon as the virtual machine is able to support nested expressions, this constraint will be lifted.

  5. Only one unbound post-assigned variable can be used in a precondition.

  6. No unbound post-assigned variables can be used in a precondition using one of the relational operators ‘<’, ‘>’ or ‘!=’.

  7. No unbound post-assigned variables can be used in an expression.

Note that constraints 5 to 7 cannot be detected by the compiler but only by the simulation engine. The simulation engine will report errors in the error log and will fail the evaluation of the precondition in which these constraints are violated.

 


Questions or problems regarding this web site should be directed to the Webmaster.
Copyright © 2000-2009 NASA Ames Research Center. All rights reserved.
Last modified: Tuesday May 19, 2009.