PROforma Expressions: PROforma Functions
Reference document of the functions that can be used in PROforma expressions.
Table of Contents
Function usage
Functions can be used in any expression in tallis. For example, preconditions, postconditions, arugment conditions etc. In addition thy can be used in embedded expressions and in expression tags (e.g. from web enactment)
A not well documented part of tallis, is that it supports two different types of expressions:
Conditions
Conditions are expressions that evaluate either true or false. They cannot be used to assign any value to anything. All the expressions in tallis proforma are of this form, except the postconditions.
Assignments
An assignment (not very successfully called assertion in tallis terminology) can only be found in the postcondition. The postcondition is a set of binary assignments using the equals operator ("=") that in this case it means "assign". The assignemnts are separated by the keyword "AND" that in this context is just a separator.
Embedded expressions
Most of the textual attributes of proforma components (e.g. caption or description, context etc) can embed expressions that are calculated during runtime and replaced with their value.
The embedded expression syntax is ${expression}
For example, consider the following task argument description:
Administer diouretic because the patients blood pressure is ${bloodPressure}mmHgThe ${} syntax causes everything inside the curly brackets to be calculated as an expression
Expression JSP tag
The expression JSP tag can be used to assign any value returned by a proforma function to a JSP bean. This is not restricted only into primitive values, but also to the new object type of values that are going to be present in 1.7
Logical Functions
AND  Expression AND Expression  Returns TRUE if all its arguments are TRUE, returns FALSE if any argument is FALSE. If either operand evaluates to UNKNOWN then the resulting expression evaluates to FALSE. 
OR  Expression OR Expression  Returns TRUE if any argument is TRUE, returns FALSE if all arguments are FALSE. If either operand evaluates to UNKNOWN then the resulting expression evaluates to FALSE. 
NOT  not(Expression)  Returns TRUE for a FALSE argument and FASLE for a TRUE or UNKNOWN argument. 
IF  if(Expression, value_if_true, value_if_false)  Returns one value if the specified Expression evaluates to TRUE and another value if it evaluates to FALSE. 
isknown  isknown(Expression)  Returns FALSE if Expression is UNKNOWN, returns TRUE otherwise. 
Decision Result Functions
result_of  result_of(Decision: Single candidate selection)  Returns the decision’s committed candidate if a single candidate was committed; returns UNKNOWN otherwise. 
result_set  result_set(Decision: Multi candidate selection)  Returns the decision’s set of committed candidates; returns UNKNOWN if no candidate were committed. 
Task State Functions
is_completed  is_completed(Task)  Returns TRUE if a Task is in the State, returns FALSE if a Task is not in the State. 
is_discarded  is_discarded(Task)  
is_dormant  is_dormant(Task)  
is_in_progress  is_in_progress(Task) 
Candidate Support Functions
netsupport  netsupport(Decision, Candidate)  Returns Net Support value for Candidate of Decision. 
candsupport_count_for  candsupport_count_for(Decision, Candidate)  Returns the count of the supporting arguments whose condition evaluates to true for Candidate of Decision. 
candsupport_count_against  candsupport_count_against(Decision, Candidate)  Returns the count of the opposing arguments whose condition evaluates to true for Candidate of Decision. 
candsupport_count_summary  candsupport_count_summary(Decision, Candidate)  Returns the algebaic summary of the count of the supporting and opposing arguments whose condition evaluates to true for Candidate of Decision. A positive argument counts as +1 and an opposing as 1 
Comparison Operators
>  Number/TextString > Number/TextString  A real number may be compared with an integer but a text string may only be compared with another text string. If either of the operands of a comparison evaluates to UNKNOWN then the resulting expression evaluates to FALSE. 
<  Number/TextString < Number/TextString  
>=  Number/TextString >= Number/TextString  
=<  Number/TextString =< Number/TextString  
=  Number/TextString = Number/TextString  
!=  Number/TextString != Number/TextString 
Math & Trig Functions
+  Number + Number  If either of the operands of an arithmetic operator evaluates to UNKNOWN then the resulting expression also evaluates to UNKNOWN. 
  Number  Number  
*  Number * Number  
/  Number / Number  
ln  ln(Number)  Returns the natural logarithm of a number 
exp  exp(Number)  Returns e raised to the power of a given number 
power_of  power_of(Number: base, Number: exponent) 
Returns base raised to the power of exponent

sin  sin(angle: radians)  Returns the sine of an angle. 
cos  cos(angle: radians)  Returns the cosine of an angle. 
tan  tan(angle: radians)  Returns the tangent of an angle. 
asin  asin(number)  Returns the arcsine of a number in radians. 
acos  acos(number)  Returns the arccosine of a number in radians. 
atan  atan(number)  Returns the arctangent of a number in radians. 
abs  abs(Number)  Returns the absolute value of a number. 
random  random()  Returns a random number greater than or equal to 0 and less than 1. Note: two occurrences of random() that are evaluated without an intervening change in engine state will return the same value. For instance, if a task has the precondition random() = random() then this precondition will always evaluate to true. 
Set Functions
include(s)  Set includes Member  Returns TRUE if Set includes Member, returns FALSE if Set does not include Member. If either operand evaluates to UNKNOWN then the resulting expression evaluates to FALSE. Note: Exp1 oneof Exp2 is equivalent to Exp2 includes Exp1 
oneof  Member oneof Set  
nth  nth(n, Set)  Returns the nth Member in a Set, returns UNKNOWN if the Set does not have an nth Member. The function is 1 based, first element is nth(1, set) Examples: nth(2,["fee","fi","fo","fum"]) evaluates to "fi" nth(4,[2,3,5]) evaluates to unknown. 
count  count(Set)  Returns the number of Members in a Set. 
max  max(Set)  Returns the largest value in a set of values. Note: Text strings are compared lexicographically ignoring case, e.g., max(["bb","bbb","AAA"]) evaluates to "bbb". 
min  min(Set)  Returns the smallest value in a set of values. 
sum  sum(Set)  Returns the sum of members of a Set. Examples: sum[] evaluates to 0. sum([1,1,2,3,5]) evaluates to 12. 
union  union(Set1,Set2)  Returns all Members of both Sets. Note: Unlike a set theoretic union the PROforma union operator does not eliminate duplicates. Example: union([1,2+2,5],[5,2,1]) evaluates to [1,4,5,5,2,1]. 
diff  diff(Set1, Set2)  Returns Members of Set1 that are not Members of Set2. Example: diff([1,2+2,5,6],[5,2,1]) evaluates to [4,6]. 
intersect  intersect(Set1, Set2)  Returns Members of Set1 that are also Members of Set2. Example: intersect([1,2+2,5],[5,2,1]) evaluates to [1,5]. 
Task time Functions
now  now()  Returns the current engine time. 
startup_time  startup_time()  Returns the time the process description started. Basically this is the in_progress_time of the root plan. 
completed_time  completed_time(Task)  Returns the “engine time” at which a Task last entered a State (or UNKNOWN if the Task has not entered the State). Example: If Task1 has a state trigger Now() – completed_time(Task2) > 1000 it wouldn’t start until 1 second (i.e. 1000 milliseconds) after Task2 has completed. 
discarded_time  discarded_time(Task)  
in_progress_time  in_progress_time(Task) 
Datetime manipulation Functions
date_diff_QUANTITY
date_diff_years 
date_diff_QUANTITY(datetime:from, datetime:to)  Returns the difference between the "from" datetime and the "to" datetime in QUANTITY units, e.g. date_diff_years 
DATE_PART_FUNCTION
date_part_year 
DATE_PART_FUNCTION(datetime)  Returns the requested part of the datetime, e.g. the year part, or the month part, etc 
date_parse  date_parse(text) 
Parses a datetime string to a date. Acceptable formats are: Dates: 19981023 1998/10/23 23101998 23/10/1998 Times: 14:20:30.334 14:20:30 14:20 Date & Time: any_date_formTany_time_form any_date_form any_time_form e.g.: 19981023T14:20:30.334 19981023 14:20:30 
Formatting and information access Functions
These functions are generally used to format values (e.g. decimal numbers) or accesss information regarding the engine (e.g. get component attributes). The distinctive difference from the rest of the functions is that on error they return an error string rather than crashing or thowing an exception. The reason for this choice is that these functions are mostly meant for presentation layer where they will be used inside embedded expressions and at this context a hard error that terminates the engine because of a type is not desireable.
format_num formatnum 
format_num(numtoformat:real, numofdigits:integer) 
Returns a string with the supplied number formated to the specified number of digits On error it returns an informative string Since 1.7 
sprintf 
sprintf(text:format_str, any_type:arg) sprintf(text:format_str, any_type:arg1, any_type:arg2) sprintf(text:format_str, any_type:arg1, any_type:arg2, any_type:arg3) 
Uses a printf style formating string to format the argumnets. Please look at Java Formatter syntax for details On error it returns an informative string Since 1.7 Known issues: Incomplete implementation 
attr  Usage: attr(componentName, text:attrname) 
Reflection function that return an attribute (e.g. caption) of a component (e.g. task, data item). For example: attr(systolicBP, 'caption') > "Systolic blood pressure" attr(systolicBP, 'units') = "mmHg" On error it returns an informative string Since 1.7 
get_caption  Usage: get_caption(dataitem) 
Reflection function that returns the caption of a range value. Since 1.7, ranges can have spearate value from caption. This function
returns the caption instead of the value. For example, if we have a data item tumourStage that has a value of "t3"
and a caption of "T3 (10mm to 20mm)", then: get_caption(tumourStage) > "T3 (10mm to 20mm)" On error it returns an informative string Since 1.7 Known issues: It only works well with text data items 
Miscellaneous Functions
:= (assign)  DataItem := value  Assigns a the right hand side value to the left hand side data item. Returns: true: When the value on the right side is known (not null) false: When the value on the right side unknown (null) Throws an engine exception if something goes wrong, eg. type incompatibility Examples: age := 20 dob := date_diff_years(dob, now() Important: The expression on the right hand side is firstly evaluated and then assigned to the data item. This has two implications. (1) if the same data item is used somewhere in the right hand side, it will have the previous value. (2) You should never assign a value twice in the same expression Since 1.7 
# (concatenate)  TextString # TextString  Joins several text strings into one text string. Example: the expression "more " # "beans" evaluates to the text string more beans. 
forever  forever()  Always evaluates to FALSE. Alias to false() that is intended to be used as a cycle until condition for tasks that cycle forever. 
true  true()  Always evaluates to TRUE. Since 1.7 
false  false()  Always evaluates to FALSE. Since 1.7 
unknown  unknown()  Always evaluates to unknown (null). Usefult for reseting values to unknown. Checking any value againsta unknown() or null() will return false. Two unknowns are not considered equal! Works: bloodPressure := unknown() Always false: bloodPressure = unknown() Use isknown() to test Since 1.7 
null  null()  (Alias for unknown)Always evaluates to unknown (null). Usefult for reseting values to unknown. Since 1.7 
activate_trigger  Usage: activate_trigger(triggername) 
This function activates an event trigger. It does not return any result. It should only be used in the context of a postcondition (to send a trigger activation).
As of the time of writing this documentation, a limitation in tallis postcondition requires to use a trick to activate the function
like: dummyDataItem = activate_trigger(triggername) Since 1.7 Known issues: This is considered a hack at this point and will probably change in future versions 