Skip to content

Internal epilog.js representation of logic programs

pjames27 edited this page Nov 19, 2024 · 13 revisions

epilog.js Internal Representation Specification

This page contains a specification of the internal Epilog representation of its expressions/language constructs.

The epilog.js functions read and readdata parse strings and return objects in the interpreter's internal representation for Epilog expression.

Epilog expressions can be Constants, Terms, Atoms, Literals, Rules, Function Definitions, or Operations.

readdata Output

An array with 0 or more elements. Each element is the internal representation of an Epilog expression. If the input is not a syntactically valid string of Epilog expressions, returns the empty array.

read Output

The internal epilog.js representation of the first Epilog expression in the input. If the input is not a syntactically valid Epilog expression, returns the string 'error'.

Epilog Expression Types and their representations

Constant

A constant is represented as a string. Symbols, constructors, predicates, and operations are all constants.

Example: The predicate p is represented as the string 'p'.

Term

A Term can be symbol, variable, or Compound Term. Symbols and variables are represented as strings.

Example: The variable X is represented as the string 'X'.

Compound Term

A Compound Terms is represented as an array, where the first element is the constructor and the subsequent elements are the arguments.

Example: The compound term f(a, g(b)) is represented as the array ['f', 'a', ['g', 'b']].

Atom

An atom is represented as an array, where the first element is the predicate and the subsequent elements are the arguments.

Example: The atom p(X, a) is represented as the array ['p', 'X', 'a'].

Literal

Literals can be Atoms or negated atoms.

A negated atom is represented as a two-element array where the first element is the string 'not' and the second element is an atom.

Example: The negated atom ~p(X, a) is represented as the array ['not', ['p', 'X', 'a']].

Rule

A Rule can have a few possible representations.

  1. A rule for a boolean predicate without a body and no parentheses in the head is represented as a string.
  2. A rule without a body and with parentheses in the head is represented as an array where the first argument is the predicate and the subsequent elements are the arguments.
  3. A rule with a body is represented as an array where the first element is the string 'rule', the second element is the head of the rule, and the subsequent elements are the subgoals of the rule.

Example 1: The rule always_true is represented as the string 'always_true'.

Example 2a: The rule p(a) is represented as the array ['p', 'a'].

Example 2b: The rule p() is represented as the array ['p'].

Example 3: The rule q(X) :- p(X) is represented as the array['rule', ['q', 'X'], ['p', 'X']].

Caveat: Some constants are reserved and cannot be used as predicates. rule is one such constant.

Function Definition

A Function Definition is represented as a three-element array where the first element is the string 'definition', the second element is the head of the definition, and the third element is the body of the definition (i.e. a single term).

Example: The function definition tail(X!L) := L is represented as the array ['definition', ['tail', 'X', 'L'], 'L'].

Operation

An Operation has a few different possible representations.

It is always represented as a three-element array where the first element is the string 'handler' and the second element is the head of the operation. The form of the third element depends on the number of conditions and effects, and is structured thusly:

  • If the operation has no conditions, then the third element is the representation of the effects of the operation (described below).
  • If the operation has one or more conditions, then the third element is a three-element array where the first element is the string 'transition', the second element is the representation of the conditions of the operation (described below), and the third element is the representation of the effects of the operation.
  • The representation of the effects of an operation are structured as:
    • If there is only one effect, then it is represented as itself.
    • If there are multiple effects, then they are represented as an array where the first element is the string 'and' and the subsequent elements are the effects.
  • The representation of the conditions of an operation are structured as:
    • If there is only one condition, then it is represented as itself.
    • If there are multiple conditions, then they are represented as an array where the first element is the string 'and' and the subsequent elements are the conditions.

Example 1: The operation a :: c is represented as the array ['handler', 'a', 'c'].

Example 2: The operation a :: c & ~d is represented as the array ['handler', 'a', ['and', 'c', ['not', 'd']].

Example 3: The operation a :: b ==> c is represented as the array ['handler', 'a', ['transition', 'b', 'c'].

Example 4: The operation a :: b & e ==> c is represented as the array ['handler', 'a', ['transition', ['and', 'b', 'e'], 'c'].