Prolog invented logic programming and powered a generation of expert systems. Its ideas — facts,
rules, backward-chaining inference — are timeless, and it has been a stable ISO standard
(ISO/IEC 13211-1) since 1995. Its ergonomics are another matter: you hand-roll the
query-and-format plumbing, conflict resolution is manual, side effects mean assert/retract,
and there’s no built-in way to test a ruleset, learn a threshold, or call an external tool.
Tln keeps the logic and modernizes everything around it. These pages put the two side by side —
ISO Prolog on the left, Tln on the right — using real programs from the Tln examples. The
Prolog is idiomatic ISO Prolog (ISO/IEC 13211-1:1995 or later), syntax-checked with
SWI-Prolog; the Tln is the actual .tln source, validated with the tln compiler.
Both reason over the same external facts, loaded as generic triples:
record(Entity, Id, Type, Category, Status, Date)
attr(Entity, Id, Name, Value)
Take the classic family tree. In Prolog you write the facts, the rules, and the query-and-print
plumbing to use them. In Tln the parent links arrive as facts from your systems — never written
in .tln — so a relationship is just a rule that declares its own output:
% facts, rules, AND the query-and-print plumbing:
parent(tom, bob).
parent(bob, ann).
parent(bob, pat).
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
ancestor(X, Z) :- parent(X, Z).
ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).
list_children(P) :-
forall(parent(P, C),
format("~w~n", [C])).// Facts arrive from your systems as record/attr triples
// (loaded, never written in .tln):
// record(family, "bob", person) attr(family, "bob", "parent", "tom")
// record(family, "ann", person) attr(family, "ann", "parent", "bob")
// record(family, "pat", person) attr(family, "pat", "parent", "bob")
detect "Children of Tom" {
for records where type == "person"
and attr "parent" == "tom"
flag matching items
label "{item.name} is a child of Tom"
}Fewer moving parts, and the outcome is declared rather than scripted. Explore the full worked comparisons below.
And it isn’t only rewrite-by-hand: existing Prolog can be ported. The relational subset lowers
to native Tln rules — even recursive ones with comparison/threshold guards — while the
genuinely Prolog-only parts (compound terms, cut, assert, value-inventing arithmetic) keep
running on the pure-Go tln-prolog engine — no external
Prolog required.