1. LPS-masters
  2. LPS
  3. lps_corner


Clone wiki

lps_corner / Syntax

Syntax of LPS

The current syntax of LPS uses a flexible mixture of explicit and implicit time. However, most of the top-level of an LPS “program” does not depend upon time and has the following, mostly optional components.


%   written either in this form
/* or in this form, which is convenient if they occupy several lines.


fluents         …  .    
events      …  .
actions     …  .    


initially   …  .    
observe     …   .

Reactive rules

if …  then …  .

Clauses for time-dependent predicates

… if …  .

Clauses for timeless predicates (e.g. Prolog)

 :-   .

Causal laws

… initiates … if …  .
… terminates … if …  .


false …  .

In more detail:



This is an optional declaration of the maximum number of states. If the declaration is not present, the maximum is currently set at 20 by default.

fluents    fluent1, fluent2, …, fluentn.    % n >= 1

Fluents are time-dependent atomic sentences. Here they are specified by giving the name of the fluent followed by its arguments. For example, a two-argument fluent named location could be specified by any one of location/2, location(,), or location(object, _place), where , _object, and _place are “anonymous variables”.

Fluents can be “extensional” if they are represented by “facts” and updated by events or “intensional” if they are represented by clauses that mirror changes of the extensional fluents.

events    event1, event2, … , eventn.   % n >= 1.

Events can be external, given by observations, or generated by the system. They can be “atomic”, taking place instantaneously from one state to the next, or “composite”, taking place over a series of zero or more states. For example, say/2, say(,) or say(_agent, _expression).

actions    action1, action2, …, actionn.    % n >= 1.

Actions are “atomic”, taking place instantaneously, and are generated by the system. They have the same syntax as events, and can also be declared as events, which may be external.


initially   fluent1, fluent2, … , fluentn.  % n >= 1.

This specifies the extensional fluents that are true in the initial state at time 0.

observe  event1, event2, … , eventn from time1 to time2.    % n >= 1.

time1 and time2 should be successive positive integers, e.g. from 2 to 3. The program can have multiple observe statements with different times.

Reactive rules.

if literal1, … , literaln then literaln+1, … , literaln+m.  % n >= 1 and m >= 1.

Each literal is a timed or untimed atomic formula or the negation of an atomic formula. (See below.) Implicitly all times after "then" are later than or equal to the latest time before "then". Also, no time after a comma is earlier than any time before the same comma.

Clauses for time-dependent predicates.

atomic formula if literal1, … , literaln.   % n > 1.
atomic formula.                 % n = 0.

These clauses are used to define:

  • 1) intensional predicates, which change as a consequence of changes to extensional predicates. For example (with explicit time)
location(Object, Place) at T if holding(Agent, Object) at T,  location(Agent, Place) at T. 

These can also be written without explicit time:

location(Object, Place) if holding(Agent, Object), location(Agent, Place).
  • 2) composite actions and events, which can take place over zero or more state transitions. For example (with explicit time):
makeAt(Agent, Place) from T to T if location(Agent, Place) at T.
makeAt(Agent, Place) from T1 to T2 if not location(Agent, Place) at T1,move(Agent, Place) from T1 to T2.

Traditional clauses in Prolog are also allowed:

atomic formula :- literal1,  , literaln.       % n > 0.

These clauses can be used to define time-independent predicates directly in Prolog. For example,

parent(X,Y) :- mother(X,Y).
parent(X,Y) :- father(X,Y).

The implementation does not support the logical connective for disjunction. So the following definition of parent does not work.

parent(X,Y) :- mother(X,Y);father(X,Y).

Prolog predicates includes all time-independent predicates, including temporal inequalities, e.g. philosopher(hume) and T1 < T2.

Causal laws

event initiates fluent if literal1, … , literaln.   % n > 0.

Here event is an external event or an atomic (non-composite) action. event, fluent and literals can all be written without explicit time. Implicitly, if the event takes place from T to T+1 then fluent is true at time T+1 if all the literals are true at time T.

Do we allow the literals be events? (to be answered).

event terminates fluent if literal1, … , literal.   % n > 0.

Like initiates, implicitly, if the event takes place from T to T+1 then the fluent at time T is terminated. It is possible for a fluent to be initiated and terminated at the same time, but by different events, as for example, when a subscription runs out, but is renewed at the same time.


false   literal1, literal2, … , literaln.   % n > 1

These are used to constrain candidate actions, say from T to T+1. So one of the literals must be an action. Other literals can be actions or external events that also occur from T to T+1. They can also be fluents that are true at time T. Because of these restrictions on time, these constraints can be written without explicit time.

Fluent literals in constraints can be negative literals, but action and other event literals can not be negated.


predicate(term1, term2,  , termn)   % n > 0

Such literals are also called (untimed) atomic formulas, or simply atoms, and can be fluents, events, or time-independent. The predicate must start with a lower case letter. The terms can be variables, constants (numbers or strings starting with a lower case letter), numbers, or any expression allowed by Prolog.

Variables follow the Prolog convention of starting with an upper case letter, or with _ if their name does not matter because it does not occur elsewhere in the same sentence.

not atom    

atom can be an atomic fluent. Other uses of negation are under investigation.

fluent at T 

Here T is a time variable. However, the possibility that T may be a constant time has not been excluded.

event from T1 to T2
event from T1
event to T2 

These all have their obvious intended meanings.


  • 1) Most of the components listed above are optional. To be meaningful an LPS program needs only reactive rules and actions, for example, the program:
actions rain.
if true then rain.
if rain then rain.

generates a sequence of 19 actions:

rain, rain, …, rain.
  • 2) Literals in reactive rules and clauses are processed Prolog-like, in the order in which they are written. Processing is suspended if the time of a fluent or the start time of an event is later than the current time, or if the time is a variable and the literal cannot be made true at the current time, but might become true later.

  • 3) Times can be omitted from fluents and events. However, for this to work, composite events and actions need to be declared as events, and intensional fluents need to be declared as fluents. This feature is currently under development, and is subject to change. Implicit and explicit times can be mixed in the same sentence. Currently, the interpreter interprets implicit times according to the following rules:

The expression:

fluent1, fluent2    


fluent1 at T1, fluent2 at T2, T1 =< T2.

The expression:

fluent, event   


fluent at T1, event from T2 to T3, T1 =< T2. 

The expression:

event1, event2  


event1 from T1 to T2, event2 from T3 to T4, T2 =< T3.

The expression:

event, fluent   


event from T1 to T2, fluent at T3, T2 =< T3.

The expression:

event if conditions        


event from T1 to Tn if conditions

where T1 is the earliest time in conditions and Tn is the latest time in conditions.

The expression:

fluent if conditions           


fluent at T if conditions

where all the time variables in conditions are identical to T.

LPS syntax (tentative) summary

Files have the .lps extension and (more or less) the following structure. Please, beware, this is just a rough approximation:

  spec ::= statement 
  statement ::= settings rules 
  settings ::= max_time actions fluents initial_state observations 
  rules ::= if_then_rules if_rules  initiate_rules terminate_rules constraints 
  if_rules ::= if_rule | if_rule if_rules
  if_rule ::= literal "." | literal "if" conjunction "." | literal ":-" conjunction  "." 
  if_then_rules ::= if_then_rule | if_then_rule if_then_rules
  if_then_rule ::= "if" conjunction "then" conjunction "." 
  constraints ::= constraint | constraint constraints
  constraint ::= "false" conjunction "." 
  conjunction ::= "true" | literal | literal "," conjunction

Wei's syntax (Deprecated)

Files have the .lpsw extension and (more or less) the following structure:

  spec ::= statement 
  statement ::= settings rules 
  settings ::= max_time  actions  fluents  initial_state  observations  events
  rules ::= if_rules reactive_rules initiate_rules terminate_rules constraints 
  if_rules ::= if_rule | if_rule if_rules
  if_rule ::= timeless_rule | event_rule | prolog_clause
  timeless_rule ::= "l_timeless(" literal "," conjunction ")."
  event_rule ::= "l_events(" happens_literal "," hold_conjunction_list ")."
  reactive_rules ::= if_then_rule | if_then_rule if_then_rules
  if_then_rule ::=  "reactive_rule(" conjunction "," conjunction ")."
  constraints ::= constraint | constraint constraints
  constraint ::= "d_pre(" conjunction ")."
  conjunction ::= "true" | literal | literal "," conjunction