zlf evaluates Prolog through a single WAM runtime. You write facts and rules in Prolog syntax and issue queries with the ? prefix.
alice), single-quoted atoms ('C++'), strings ("text").1, 1.0). Integer and float are distinct term identities.X, _, _Ignored).functor(arg1, arg2, ...).[a, b, c], with canonical [] and '.'/2 identity.{ key: value, ... } — property-map literals.Facts persist through the canonical storage writer; rules compile and persist through StorageRuleStore:
node(alice).
node(alice, [person, employee], { name: "Alice", age: 30 }).
person(alice).
knows(alice, bob).
property(alice, title, "Staff Engineer").
colleague(X, Y) :- works_at(X, C), works_at(Y, C), X \= Y.
reachable(X, Y) :- knows(X, Y).
reachable(X, Y) :- knows(X, Z), reachable(Z, Y).
A line can contain multiple facts: node(a). node(b). follows(a, b).
Queries start with ?:
? node(Id).
? person(Id).
? property(Id, name, Name).
? edge(Source, Type, Target).
? knows(alice, Who).
? prop_name(Id, Name).
zlf provides the ISO programming builtins (=/2, \=/2, ==/2, is/2, arithmetic comparisons, var/1, atom/1, functor/3, arg/3, =../2, call/N), list and string/conversion predicates (member/2, append/3, length/2, atom_chars/2, …), and control (true/0, fail/0, !/0, \+/1, once/1, ;/2, ->/2).
Dynamic database builtins: asserta/1, assertz/1, retract/1, retractall/1, clause/2, current_predicate/1.
Storage routing is purely syntactic (see prolog-storage.md): canonical node/label/property/edge forms and unary/binary shortcuts map to the property graph, while unreserved ground facts of arity >= 3 become durable logical facts in the FactStore.