ALM is a logic language in the tradition of Prolog, Datalog, and ASP.
ALM is all about objects and actions (which are themselves
types of objects). Every object has a "sort". Sorts are
organized into a directed acyclic graph such that sorts can have
one or more subsorts.
ALM has the following built in sorts:built in sorts for booleans and integers.
- booleans
- integers
- universe, which is the root sort for everything
- action, which is the root sort for all action objects, and is itself a subsort of universe
Additionally, users can define their own sorts with the "specialization" operator ("::").
"a :: b" reads "a is a subsort of b"
Objects can have attributes, which are properties intrinsic to the object and which never change.
Semantically, attributes are just functions from an object to another value.
Some sorts are small and known ahead of time. These can be represented as set literals like
"some_sort :: {a, b, c}". I think this is just typedef some_sort = A | B | C
in DDLog.
ALM has a number of built in functions. These mostly describe the sort hierarchy. The two most important
built in functions are:
instance : objects x sorts -> booleans
, which tells you if an object is of a particular sort.
is_a : object x sorts -> booleans
, which tells if an object is a subsort of a particular sort.
In addition to objects and the built in functions, ALM has what are called "fluents", functions whose value changes over time
as the system changes. There are two types: basic, which have inertia and don't change until changed
by some action; and defined, which are derived purely from the values of other fluents, and don't have
inertia. These almost exactly correspond to the distinction between input and output relations in DDLog,
with one exception: rules can add to the values of basic fluents, while, by my experimentation, rules can't
add to the values of input relations. I think this is easily overcome by representing each basic fluent as
the combination of an input and output relation.
The last construct in ALM is axioms. Axioms have two forms:
-
The first are called state constraints. They read "P if Q". These correspond exactly to
normal rules in DDLog if you just replace "if" with :-
.
-
The second are called causal laws. They say "if action A occurs and P is true, then Q is true in the next state". While DDLog
doesn't directly represent change over time, these relationships are still easily representable via normal Datalog rules. I
think I'll have to write an interpretter that takes the output of causal laws and modifies the input relations accordingly.