---+++ Logic programs Logic programs in LPS are sets of *clauses*, which have either the form: conclusion. or the form: conclusion if conditions. Clauses of the first form, if they do not contain variables, are often called "facts"; but they may or may not be "fluents", which change with time. In many languages, including Prolog, clauses of the second form are often, confusingly, called "rules". In LPS, we use the term "rule" exclusively for reactive rules. If reactive rules represent an agent's goals, then logic programs represent the agent's *beliefs*. Goals are sentences that need to be made true, whereas beliefs are sentences that are assumed to be true already. Beliefs determine and restrict the kinds of models that can be generated when performing actions to make goals true. For example:
:- expects_dialect(lps). happy(bob) at T if lightOn at T. happy(dad) at T if lightOff at T.
Here "happy" is a _predicate symbol_, and "bob" and "dad" are _constants_, which are assumed to name different individuals. Parentheses, "(" and ")", following a predicate symbol, enclose the predicate's _arguments_. So in the first clause above, "bob" is the argument of "happy". "lightOn" and "lightOff" are also predicate symbols, but having zero arguments. They can also be written, somewhat clumsily, as "lightOn()" and "lightOff()". The more important distinction between the different predicates in these two clauses, however, is that "lightOn" and "lightOff are *|extensional predicates|* and "happy" is an *|intentional predicate|*. Extensional predicates are _defined_ only by facts, and intentional predicates are _defined_ by clauses, some of which are not facts. Extentional predicates that are fluents, like "lightOn" and "lightOff", can change directly as the result of actions and other events, and as determined by causal laws. Intentional predicates, like "happy", can change only indirectly as ramifications of changes to extensional predicates. Timelines in LPS display changes only to extensional predicates, and not to intensional predicates. However, the models generated by LPS include the values of not only extensional predicates, but also of intentional predicates. Here is an example that shows this. (Notice that, although it is necessary to declare fluents, events and actions, it is not necessary to declare intensional predicates.)
fluents lightOn, lightOff. events switch. actions switch. initially lightOff. observe switch from 1 to 2. observe switch from 3 to 4. observe switch from 10 to 11. if not happy(bob) at T1 then switch from T1 to T2. happy(bob) at T if lightOn at T. happy(dad) at T if lightOff at T. switch initiates lightOn if lightOff. switch terminates lightOff if lightOff. switch initiates lightOff if lightOn. switch terminates lightOn if lightOn.
go(Timeline).
Here the condition "not happy(bob)" of the reactive rule is true at times 1, 4 and 11. So, to make the reactive rule true (for all times), the action "switch" must be made true from time 4 to 5 and from 11 to 12. However, "switch" does not need to be made true from 1 to 2, because it is already given as true by means of an external event. For these reasons, it could be said that "switch from 4 to 5" and "switch from 11 to 12" are _goals_ (actually sub-goals of the goal of making the reactive rule true), but "switch from 1 to 2" is both a goal and a _belief_. It is often hard to tell the difference between a goal and a belief. This can cause problems in human life, and it can also cause problems for programming in LPS. But, in both cases, it is a lesson that is worth learning.
---++++ Other kinds of clauses There are two other kinds of clauses in LPS, clauses that define time-independent predicates, like for example "1 < 2", and clauses that define complex actions or external events. We will see examples of both of these kinds of clauses later.