Intelligence, Agency & Consciousness · Paper 0092

When one meaning can run many ways

Robert Kowalski separates what an algorithm means from how its knowledge is used, then asks how direction, scheduling, search and storage can change behaviour without changing the answer.

Intelligence, Agency & Consciousness · Paper 0092

When one meaning can run many ways

Rajesh Ranjan Mahapatra

Robert Kowalski separates what an algorithm means from how its knowledge is used, then asks how direction, scheduling, search and storage can change behaviour without changing the answer.

© 2026 Rajesh Ranjan Mahapatra. 33 min read

When one meaning can run many waysAll AI Research Library

TLDR

Five-point orientation
  1. An algorithm can be analysed as logic plus control. Logic states the problem knowledge; control decides how to use it.
  2. Meaning and behaviour are different. Several sound control regimes can preserve answers while changing time, space and order.
  3. Representation still matters. A clearer or stronger logic component can outweigh any improvement in search control.
  4. Horn clauses admit two readings. They are logical implications and, under top-down use, procedures with flexible call order and modes.
  5. The separation is an engineering discipline, not an identity of nature. Kowalski says the boundary is useful but not wholly unambiguous.
01 · The analytical split

The equation is a lens, not a claim that programmes arrive in two boxes

Kowalski’s compact equation, A = L + C, proposes a way to analyse an algorithm. The logic component L specifies the knowledge that may be used in solving a problem. The control component C specifies the problem-solving strategy by which that knowledge is used.

The distinction begins with meaning. L says which relationships hold and what counts as a solution. C decides such matters as whether reasoning proceeds from data towards consequences or from a goal towards subgoals, which pending call is handled next, whether alternatives are explored sequentially or together, and how relational data are stored and retrieved. On Kowalski’s first approximation, admissible changes to C alter behaviour and efficiency but do not alter the problems solved or the answers returned.

That qualification matters. The paper does not say control is irrelevant, nor that logic alone is an executable algorithm. A correct declarative relation can be paired with control that repeats work explosively, consumes unnecessary memory or never reaches an existing answer. Conversely, good control cannot turn a poor representation into an efficient method in every case. Both sides affect performance, but they affect it in different ways.

The motivating promise is replaceability. If A₁ = L + C₁ and A₂ = L + C₂, then, under meaning-preserving control, A₁ and A₂ are equivalent in result while possibly very different in cost. That creates a clean target for optimisation: improve C while holding L fixed. It also creates a clean target for reasoning: establish what L means without first committing to every scheduling choice.

Kowalski is careful not to reify the boundary. The same behaviour can often be analysed as L₁ + C₁ or L₂ + C₂. Work embedded in a more elaborate logical representation can be shifted into a more capable interpreter, and work performed by control can instead be compiled into the clauses. The equation is therefore a disciplined decomposition chosen for explanatory and engineering value.

Algorithm decomposed into logic and controlA logic panel labelled meaning and a control panel labelled use feed a shared algorithm result. Three control paths have different costs but converge on the same answer.L · LOGICknowledge · relation · meaningC · CONTROLdirection · order · search · storageA = L + Csame specified answers
The useful invariant is semantic: control paths may differ in work and storage while preserving the relation defined by the logic.Original schematic after Kowalski 1979, pp. 424–426.

Worked example 1 · one factorial definition, two directions

The clauses “factorial 0 is 1” and “factorial x+1 is (x+1) times factorial x” can generate 0!, 1!, 2! and so on from the base case. That is bottom-up use and behaves like iteration. The same clauses can reduce the request for 6! to a request for 5!, then 4!, down to the base case. That is top-down use and behaves like recursive evaluation. The mathematical relation is unchanged; the direction of activity changes.

Causal probe 1 · freeze L, vary C

If an optimisation changes which inputs have answers, it did not merely improve control under Kowalski’s first approximation. It changed the effective meaning, lost completeness, admitted an unsound result or exposed a termination difference. Testing only speed cannot establish that C preserved L.

02 · What belongs on each side

Logic supplies abstract definitions and data relations; control supplies motion

The paper expands its equation into an inventory. The logic component contains abstract procedure definitions and definitions of data structures. The control component contains direction, scheduling of procedure calls, investigation of alternative procedures, and schemes for storing relational data.

This inventory blocks a common misreading. “Logic” does not mean a pile of facts with no structure. It includes recursively defined relations, abstractions such as sorting, and representations of data. Nor does “control” mean a single program counter. It includes forward versus backward reasoning, sequential versus parallel calls, depth-first versus breadth-first exploration, indexing and retrieval. An interpreter can own some of these choices; an advanced programmer can provide additional control information in a separate language.

The distinction also locates responsibility. Domain-specific knowledge belongs primarily in L. General and problem-specific problem-solving strategies belong in C, provided they preserve meaning. At a high level of programming, the system should assume more responsibility for control. Kowalski uses database query systems as evidence: the user states a relational query, while the system chooses storage and retrieval schemes.

Control may still use domain knowledge. A programmer can state that y is functionally determined by x in F(x,y), allowing a backtracking engine to avoid seeking a second F answer after a later goal fails. A diagnosis system can state that procedure Q is more likely than R to explain symptom P, changing search order. These facts guide effort without becoming new object-level solutions: if they are correct and the interpreter honours them soundly.

The resulting architecture is asymmetric. L must be specified before C in Kowalski’s programme of successive refinement. Control is subordinate to meaning: it may choose how the relation is realised, but it is not entitled to rewrite the relation silently. That asymmetry is the reason the split can support both correctness arguments and performance work.

Tree of logic and control componentsAn algorithm root branches to logic and control. Logic branches to abstract procedures and data definitions. Control branches to direction, call scheduling, alternative search and relational storage.ALGORITHMLOGICCONTROLabstract proceduredefinitionsdata-structuredefinitionsdirectioncallschedulealternativesand storage
Kowalski’s own decomposition is richer than “specification versus implementation”: data representation sits in logic, while retrieval policy sits in control.Original reconstruction of the component diagram in Kowalski 1979, p. 425.

Worked example 2 · a functional dependency as control information

Suppose F(A,y) can return at most one y, followed by G(y). If G fails, a generic backtracker might ask F for another y. The dependency tells it not to waste that search. The allowed F pairs have not changed; only the investigation strategy has.

Causal probe 2 · corrupt the hint

If F actually has two outputs for A, declaring it functional can suppress a valid second answer. The optimisation then changes observable meaning. The example exposes a permanent engineering obligation: control annotations require their own correctness case.

03 · The common language

Horn clauses make the split inspectable

Kowalski chooses clausal predicate logic because one notation can carry a declarative reading and support several operational readings. He narrows attention to Horn clauses: clauses with at most one conclusion: because their form resembles procedures without surrendering their logical interpretation.

An assertion has a conclusion and no conditions. A procedure declaration has one conclusion B and zero or more conditions A₁…Aₙ. A denial has conditions but no conclusion and represents a problem to be refuted. The empty clause is contradiction. Variables are implicitly universal within each clause; variables in different clauses remain distinct even if printed with the same letter.

The logical reading of “Parent(x,y) if Father(x,y)” states a relation. The recursive pair for Ancestor states that a parent is an ancestor and that ancestry composes through an intermediate individual. None of this commits the system to left-to-right calls, depth-first search or a particular index. Those are additions made by control.

Problems are expressed as denials. To ask whether Zeus is a grandparent of Harmonia, deny that relation and seek a refutation. If the denial contains variables, a successful refutation returns substitutions that witness answers. Thus a query for descendants of Zeus can produce Ares, Harmonia and Dionisius rather than merely a Boolean.

Horn form is expressive enough for the paper’s procedural argument, but Kowalski does not pretend it is always the most natural surface form. His subset example shows that converting a compact quantified definition into clauses can obscure its meaning. The restriction is methodological: study the part of logic whose declarative and procedural structures line up most clearly.

assertion: B ←
procedure declaration: B ← A₁, …, Aₙ
denial / goal: ← B₁, …, Bₘ
contradiction: ←
Anatomy of a Horn clauseA parent rule has one conclusion and two joint conditions. The same rule is shown as a logical implication and as a procedure name with two calls.Grandparent(x,y) ← Parent(x,z), Parent(z,y)one conclusionjoint conditionsLOGICAL READINGif both parent relations hold,the grandparent relation holdsPROCEDURAL READINGa grandparent call createstwo parent subcallsone clause · two disciplined interpretations
A Horn clause can remain a proposition while also admitting a procedure-like top-down interpretation.Original figure based on Kowalski 1979, pp. 426–428.

Worked example 3 · recovering a witness

Invoke Grandparent(Zeus,y). The rule introduces z and reduces the request to Parent(Zeus,z) and Parent(z,y). The fact Parent(Zeus,Ares) binds z to Ares; Parent(Ares,Harmonia) then binds y to Harmonia. The answer substitution is not an extra convention pasted onto logic: it is recovered from the refutation.

Causal probe 3 · reverse the conditions

Parent(z,y), Parent(Zeus,z) is logically the same conjunction. Operationally, if y is unbound and the database is large, beginning with Parent(z,y) may enumerate almost every parent pair. The result relation is unchanged, but a textual engine with fixed left-to-right control can make equivalent clause bodies behave very differently.

04 · Direction of reasoning

A definition may propagate from evidence or pull backwards from a goal

The same family clauses solve the grandparent problem in two directions. Bottom-up reasoning begins with assertions and derives consequences until the goal appears. Top-down reasoning begins with the goal and reduces it to subgoals until assertions discharge them.

Bottom-up begins from Father(Zeus,Ares) and Father(Ares,Harmonia). Parent rules derive Parent(Zeus,Ares) and Parent(Ares,Harmonia). The grandparent rule then derives Grandparent(Zeus,Harmonia). Processing moves from available data towards the requested consequence. It may also derive facts irrelevant to the particular request, such as Male(Zeus), because forward closure is not automatically goal-directed.

Top-down begins from Grandparent(Zeus,Harmonia). The grandparent rule replaces that goal with Parent(Zeus,z) and Parent(z,Harmonia). The parent rules reduce those subgoals to father or mother alternatives; compatible facts bind z to Ares and close the proof. Processing moves from the requested consequence towards supporting data. It can still make irrelevant choices: for example, trying Mother(Zeus,z) before Father(Zeus,z).

Direction is control because the clauses do not nominate a starting end. Top-down proof procedures include model-elimination and linear-resolution families; bottom-up procedures include hyper-resolution. Kowalski also points to connection graphs and natural-deduction systems that can mix directions. This is not a choice between logic and something non-logical. Both are deduction, organised differently.

Direction has characteristic failure modes. Forward reasoning can materialise a broad closure that a narrow query never needs. Backward reasoning can revisit the same subproblem or follow an unproductive branch. Neither direction is universally superior. The purpose of separation is to permit the choice to respond to query shape, data distribution and available execution machinery.

Top-down and bottom-up grandparent proofsOn the left, father facts flow upward through parent facts to a grandparent result. On the right, a grandparent goal flows downward through parent subgoals to father facts.BOTTOM-UPTOP-DOWNFather(Zeus,Ares)Father(Ares,Harmonia)Parent(Zeus,Ares)Parent(Ares,Harmonia)Grandparent(Zeus,Harmonia)Grandparent(Zeus,Harmonia)?Parent(Zeus,z)Parent(z,Harmonia)facts bind z = Aresboth subgoals close
The derivation can be read from facts upward or from the goal downward. The clause set is shared; the origin and flow of activity differ.Original reconstruction of Kowalski 1979, pp. 427–428.

Worked example 4 · forward closure for many questions

If thousands of later queries ask about many ancestors, computing and indexing a useful closure can amortise the work. For one isolated grandparent query, that same closure may be wasteful. “Top-down is faster” is therefore not the thesis. The thesis is that direction belongs to C and can be selected without rewriting what Parent or Grandparent means.

Causal probe 4 · add an irrelevant family branch

Add a hundred parent facts unrelated to Zeus. A naïve bottom-up evaluator may derive their consequences; a goal-directed evaluator need not touch them. Add instead a cyclic ancestor rule and repeated subgoals: a naïve top-down evaluator may loop or duplicate work while a tabulating or bottom-up method terminates. Data and rule shape cause the ranking to reverse.

05 · Procedures without fixed modes

A top-down Horn clause is stranger: and more flexible: than a conventional procedure

Under the procedural interpretation, the conclusion names the problems a clause can solve and the body is a set of procedure calls. Invoking a clause means matching a goal with its conclusion, replacing the goal by the body, and applying the matching substitution.

The substitution transmits information in both directions. Matching Grandparent(Zeus,Harmonia) with Grandparent(x,y) binds x and y, sending input to new parent calls. Matching Father(Zeus,z) with the fact Father(Zeus,Ares) binds z, sending output back to the remaining goal. A single invocation can transmit both input and output.

This differs from conventional procedure calls in three ways emphasised by Kowalski. First, a clause body is logically a set or conjunction, not a compulsory sequence; calls may run in any order or in parallel. Secondly, several clauses may have conclusions matching the same call, so choosing a clause is a search problem. Thirdly, argument modes are not fixed once and for all. The same relation can test a pair, find an output from an input, or search for inputs consistent with an output.

Those freedoms are precisely the control surface. A concrete language such as Prolog usually commits to a more particular regime: textual clause order, left-to-right subgoals and depth-first backtracking. Such a regime is one C, not the procedural meaning of Horn clauses in full. Treating it as inevitable collapses the analytical separation.

Flexibility does not remove operational preconditions. A relation can be mathematically symmetric while a chosen implementation expects one argument to be sufficiently instantiated. A reorder can move an expensive generator before a selective test. Parallel calls can require synchronisation on shared variables. The logic tells us which joint assignments satisfy the clause; control must realise them without losing or inventing answers.

Procedure invocation by matchingA grandparent goal matches a clause head, producing bindings for x and y, then becomes two parent calls sharing variable z. A fact later binds z to Ares.Grandparent(Zeus,Harmonia)Grandparent(x,y) ←Parent(x,z), Parent(z,y)matchx = Zeusy = Harmonia← Parent(Zeus,z), Parent(z,Harmonia)a later fact transmits z = Ares as output
Matching converts a call into subcalls while carrying bindings. The shared variable z coordinates the two parent relations.Original figure based on Kowalski 1979, pp. 428–429.

Worked example 5 · one relation, several modes

Parent(Zeus,Ares) tests a ground pair. Parent(Zeus,y) enumerates Zeus’s children. Parent(x,Ares) finds Ares’s parents. Parent(x,y) enumerates the whole relation. A conventional function signature would normally privilege one of these directions; the relation itself does not.

Causal probe 5 · confuse a set with an execution list

If the body is treated as an immutable sequence, swapping two conjuncts looks like a programme change rather than a control change. Restoring the logical conjunction exposes what must be invariant: the joint relation: and what may vary: the schedule used to establish it.

06 · Representation before optimisation

Changing logic can matter more than polishing control

The equation does not make L a frozen ideal. Kowalski contrasts two logical accounts of sorting to show that representation can dominate the effect of a control strategy.

The direct definition says that sorting x gives y when y is a permutation of x and y is ordered. It is transparent as a specification. Yet ordinary ways of controlling those two relations generate permutations and test them, or interleave generation with orderedness checks. Better scheduling prunes some work, but the representation still exposes an enormous search space.

A quicksort-style logical definition introduces partitioning around the first element, recursively sorting the two partitions and appending the results. Even simple top-down sequential control now behaves efficiently compared with permutation generation. The improvement came from L: the relation was decomposed using stronger problem knowledge. The result relation: ordered permutations: remains the intended one, but the logical route is more informative.

This supports a two-stage discipline. Specify and refine a logic component that says clearly what is to be done and captures useful domain structure. Then improve its control. Some programme transformations can derive a new, more efficient L by deduction; other optimisations leave L fixed and change C. Calling both “optimisation” should not hide the distinction.

The boundary remains movable. A sophisticated interpreter might recover useful partitioning or constraints from a more abstract specification, shifting work back into C. A simple interpreter may require the programmer to encode more of that knowledge in L. Kowalski’s long-term preference is for clear logic paired with powerful problem-solving machinery, not for deliberate representational weakness.

Two logical representations of sortingA permutation-and-test definition fans into many candidates, while a partition-and-recurse definition narrows into two sublists. Both converge to the same sorted relation.PERMUTE + TESTPARTITION + RECURSEsort([3,1,2], y)[3,1,2][3,2,1][1,3,2][2,3,1]…pivot = 3[1,2][][1,2] + [3] → [1,2,3]
Control can interleave permutation generation and testing, but a partitioning representation changes the exposed problem structure more radically.Original schematic after Kowalski 1979, pp. 428–429.

Worked example 6 · pruning is not partition knowledge

When constructing a candidate permutation left to right, an orderedness test can reject [3,1,…] early. That is useful control. It still begins inside the permutation representation. Quicksort’s logic states a structural fact: every output element belongs on one side of a pivot. That knowledge prevents most candidates from arising at all.

Causal probe 6 · compare only runtimes

If two versions differ in both L and C, a faster result cannot be credited to “better search” alone. Hold L fixed to test a control claim; hold C fixed to test a representation claim. Kowalski’s decomposition turns an undifferentiated benchmark win into a causal experiment.

07 · Data structures as logic

Abstract relations can outlive their storage representation

Kowalski places definitions of data structures inside L, yet argues that higher-level procedures should be separated from those definitions. The point is not to abolish representation but to make the dependency explicit and replaceable.

A list can be represented by terms: nil names the empty list and cons(x,y) names a list whose first element is x and whose rest is y. Higher-level sorting can interact with this representation through relations such as empty, first and rest. Those interface predicates state what the structure provides without forcing every sorting clause to expose cons cells.

A preliminary deduction can eliminate the interface predicates and specialise the abstract quicksort definition into clauses that pattern-match directly on nil and cons. The specialised form avoids interface calls at runtime but mixes procedure and representation. Kowalski connects this to macro expansion: flatten the abstraction before execution, much as a theorem prover or programme transformer can derive a lower-level logic component.

Separation brings two benefits. The list representation can be replaced without rewriting higher-level sorting, and well-named interface relations make the programme largely self-documenting. Mixing representation into every procedure may gain speed, but it transfers documentation outside the programme and increases the cost of change.

This is why Kowalski’s terminology deliberately conflicts with Wirth’s “program = algorithm + data structure”. In A = L + C, data-structure definitions belong to L. The control side manages the scheme by which relational data are stored and retrieved. A relation such as Parent can be presented independently of whether tuples live in an array, hash table, tree or semantic network.

Data abstraction and specialisationAn abstract sorting relation calls empty, first and rest interfaces above a cons-list representation. A specialisation arrow produces a faster flattened clause while preserving the list relation.abstract sorting relationemptyfirstrestnil · cons(x,y)replaceable representationdeduce / specialiseflattened logicsort(nil,nil)sort(cons(x,xs), y) ←partition(xs,x,…), …same relation · fewer interface calls
Abstraction can be preserved in the authored logic and specialised before execution, separating clarity from runtime overhead.Original figure based on Kowalski 1979, pp. 429–430.

Worked example 7 · swap the list representation

An abstract partition relation consumes “first” and “rest” observations. A linked list, an array slice or a stream can implement those observations differently. If sorting clauses mention cons throughout, the representation leaks into every layer. With an interface, a transformer can later specialise the chosen representation while the higher-level account remains stable.

Causal probe 7 · inline before understanding

Inlining may remove call overhead, yet it also erases the boundary that states what the representation is for. Measure the specialised artefact, but preserve the abstract relation as the correctness reference. Otherwise an optimisation changes the only readable statement of intent.

08 · Scheduling joint conditions

Sequence, coroutining and parallelism are different controls over one conjunction

A clause body does not logically prescribe an execution order. Kowalski uses sorting and tree-leaf comparison to show how alternative schedules can preserve the joint condition while changing when failure is discovered and how much intermediate data are built.

For “y is a permutation of x, and y is ordered”, sequential execution can generate a complete permutation before checking order. Coroutining can suspend generation after each new element and ask whether the partial sequence remains ordered. Invalid prefixes are abandoned early. The two calls still define the same acceptable y values; their communication schedule changes.

Quicksort exposes pipeline parallelism. Partitioning can begin as input elements arrive. Recursive sorts can begin on emerging partitions, and append can begin as sorted output becomes available. The clause lists the joint relations. Control can realise them as a staged sequence, coroutines or communicating processes.

The tree example makes memory visible. To test whether two trees have the same leaf list, a sequential strategy constructs both complete lists and compares them. A communicating strategy lets each traversal emit one leaf, compares the pair immediately and stops at the first mismatch. When the trees disagree early, it avoids most traversal; even when they agree, it need not retain the consumed prefixes.

Kowalski’s claim that parallel top-down subproblems “seems never” to decrease efficiency belongs to the paper’s 1979 framing, not a universal modern cost theorem. Real parallel systems pay scheduling, communication and synchronisation costs. The durable insight is analytical: the conjunction defines compatibility, while the execution regime determines materialisation, latency and resource use.

Sequential and communicating leaf comparisonThe sequential route builds two entire leaf lists before comparing them. The communicating route streams paired leaves through an early comparator and stops on a mismatch.SEQUENTIALCOMMUNICATINGtree Xtree Y[a,b,c,d][a,b,x,d]compare latetree Xtree Ycomparenowmismatch stops both streams
Changing the schedule can replace complete intermediate lists with incremental communication and earlier failure detection.Original reconstruction after Kowalski 1979, pp. 430–431.

Worked example 8 · mismatch on the third leaf

Let X emit [a,b,c,d,…] and Y emit [a,b,x,d,…]. Sequential construction does all work needed to build both lists before the comparison reaches position three. A lockstep schedule retains only the current pair, accepts a and b, then rejects c versus x. The equality relation over leaf sequences is unchanged.

Causal probe 8 · include coordination cost

If every emitted leaf crosses a slow process boundary, a small matching pair of trees may run faster sequentially. That does not refute the split. It shows that C’s cost model must include communication, not merely logical inference steps.

09 · When forward execution wins

Fibonacci breaks the habit of equating recursion with top-down execution

Mathematicians often read recursive definitions bottom-up, generating a sequence from base cases. Conventional implementations encouraged programmers to read them top-down. Kowalski’s Fibonacci example shows why the execution direction should remain a choice.

With two base assertions and the relation Fib(u+2)=Fib(u+1)+Fib(u), a naïve top-down request for Fib(n) expands into requests for Fib(n−1) and Fib(n−2). Those subtrees overlap: Fib(n−2) is solved independently inside both branches, and the duplication compounds. The number of calls grows exponentially with n, while the stack grows with n.

Bottom-up execution begins with the two base values and generates each later value once. It performs linear work. With an appropriate deletion policy it needs to retain only the previous two assertions, using constant working storage. Here the supposedly “declarative” direction looks like the familiar iterative algorithm.

The comparison is not a timeless verdict against top-down reasoning. Kowalski notes that its disadvantage disappears when repeated calls are solved only once: a strategy related in the paper to Warren’s generalisation of Earley parsing. Today one might call the idea memoisation or tabling. That is another C over the same recursive L: demand-driven like top-down evaluation, but sharing answers rather than rebuilding subtrees.

The lesson is causal. The recursive definition does not force exponential work. A particular control regime causes repeated evaluation. Replacing the definition with an imperative loop can fix the symptom, but it also hides that the useful transformation was a change in direction or sharing.

Top-down Fibonacci tree versus bottom-up streamA branching top-down request for Fibonacci six repeats Fibonacci four and three. A bottom-up row computes each value from zero through six once and retains a moving two-value window.TOP-DOWN · REPEATED TREEBOTTOM-UP · ONE PASSF6F5F4F4F3F3F2overlapping subproblems expand again1 → 1 → 2 → 3 → 5 → 8 → 13F0 F1 F2 F3 F4 F5 F6two-value retention window advanceslinear steps · constant workspace
Exponential repetition is a property of naïve top-down control, not of the Fibonacci relation itself.Original figure based on Kowalski 1979, p. 431.

Worked example 9 · three controls over Fib(6)

Naïve backward recursion repeatedly solves Fib(4), Fib(3) and smaller calls. Forward execution derives F2 through F6 once. A tabled backward evaluator asks only for F6 but stores completed subanswers and reuses them. All return the same value, 13 under the paper’s base convention F0=1 and F1=1; their work graphs differ.

Causal probe 9 · add sharing without changing the clauses

If memoisation turns the top-down tree into a directed acyclic graph, the asymptotic gap nearly vanishes while L remains fixed. That intervention identifies duplicated subproblem control: not recursion: as the source of the original explosion.

10 · Alternatives, paths and control arrows

Search strategy completes the algorithm: and exposes the boundary’s mobility

When several clauses match a call, logic does not say which alternative to try first. Kowalski treats sequential investigation as search through nondeterministic alternatives, then uses path finding to show how direction and representation interact.

A grandchild query may try parent facts one at a time, nesting one loop of alternatives inside another and leaving as soon as it finds a witness. In a conventional programme that looks like iteration over an array. In a relational account it is depth-first backtracking over matching assertions. Breadth-first, parallel and indexed searches are other controls over the same facts.

In the first path representation, Go(x) means that x is reachable from a fixed initial node. Arcs are clauses such as Go(B) if Go(A). Bottom-up reasoning from Go(A) is forward search. Top-down reasoning from the goal Go(Z) is backward search. Combining them yields bidirectional search; depth-first versus breadth-first is the strategy for investigating alternatives.

In the second representation, Go*(x,y) means that y is reachable from x, and transitivity is a clause connecting x to z and z to y. A query Go*(A,Z) can still move forward by solving the first subgoal first, backward by solving the second first, or bidirectionally by coroutining them. What counted as inference direction in the one-place representation partly becomes subgoal scheduling in the two-place representation. The same behaviour has different L/C analyses.

The paper closes its technical development with arrows attached to atoms. Arrows state where processing activity can flow: conditions-to-conclusion for top-down use, conclusion-to-conditions for bottom-up use, with numeric annotations for sequencing. The notation can drive a connection-graph prover, but Kowalski marks its limit. Efficient grandparent query order depends on which argument is bound, and a static arrow cannot express that input-sensitive choice. A useful decomposition must admit that its control language is incomplete.

Two analyses of path findingA directed graph is shown beside two logical representations. In Go of one variable, forward and backward search change inference direction. In Go-star of two variables, they change which transitive subgoal is selected first.ABECYZANALYSIS 1 · Go(x)Go(B) ← Go(A)forward = bottom-up from Go(A)backward = top-down from Go(Z)ANALYSIS 2 · Go*(x,y)Go*(x,y) ← Go*(x,z), Go*(z,y)forward = left subgoal firstbackward = right subgoal firstgreen and red traverse one graphbut occupy different analytical slots
The decomposition is useful without being unique: a direction choice under one representation can become a call-order choice under another.Original reconstruction after Kowalski 1979, pp. 431–435.

Worked example 10 · input-sensitive join order

For “names of suppliers of pens”, finding Part rows for pens first can sharply restrict Supply and Supplier. For “names of parts supplied by Jones”, finding Jones’s Supplier row first is selective. The relational conjunction is the same kind of object, but the best first call depends on which constant appears in the query. Static arrows cannot encode the general decision.

Causal probe 10 · move behaviour across the equals sign

Represent reachability with Go(x) and forward versus backward is inference direction. Represent it with Go*(x,y) plus transitivity and the same movement can be selected by subgoal order. If a performance explanation changes when the representation changes, name both L and C; neither label alone identifies the cause.

Executable control laboratory

Hold the graph fixed; change only the frontier discipline

The laboratory fixes a reachability relation and runs three complete controls: depth-first, breadth-first and goal-directed best-first search. Each must agree with exhaustive closure about whether the target is reachable, but its visited order, witness path and amount of work may differ.

The graph is L. Its directed edges determine which paths exist. The start and goal form the problem. The frontier policy is C. Depth-first commits to the earliest open branch, breadth-first expands by distance from the start, and best-first ranks open nodes by their geometric distance to the displayed goal. Duplicate suppression is shared so every strategy terminates on this finite graph.

The three exact checks separate semantics from behaviour. First, the reported reachability must match a control-independent exhaustive closure. Secondly, any returned witness must begin at the start, end at the goal and traverse only declared edges; an unreachable result must return no witness. Thirdly, the reported expansion count must equal a duplicate-free visited trace. These checks do not assert that the controls have equal cost. They assert that cost differences occur inside a preserved relation.

Reachability under three controls

Search trace on the fixed reachability graphDirected graph nodes change colour to show the selected control’s visited order and returned path.
Logical answer
Witness path
Expansion trace
Work

How to read the artefact

Node colour records operational attention, not truth. A node can be reachable even if one strategy stops after finding the goal before visiting it. The green path is a witness, not the complete meaning of the graph. The logical answer is the invariant checked against full closure.

Limits and failure modes

Meaning preservation is a condition to prove, not a benefit that arrives automatically

A slogan can make control sound harmless. The paper’s argument is stronger when read conditionally: improve C without changing L only when the chosen strategy remains correct for the intended relation.

Search order can interact with termination. A depth-first path may descend indefinitely while another branch contains a finite proof. A fair breadth-first procedure may find the proof. Both operate over the same clauses, yet the first may produce no observable answer. For partial computations, “same meaning” requires a semantic account broader than immediate runtime behaviour and an explicit completeness or fairness premise.

Pruning can change the answer set. A functional-dependency annotation, a cut, a beam width or an early stopping rule may discard alternatives. If the discarded branches cannot contribute new valid answers, the pruning is meaning-preserving; otherwise C has reduced completeness. Later logic-programming work makes this obligation explicit by proving correctness and completeness separately and checking that pruning preserves both for the chosen specification.

Modes and floundering complicate the boundary. A relation may support several logical directions, but a concrete implementation can delay calls until arguments are instantiated. Some schedules terminate, others suspend forever. Control still explains the difference, but the engineering claim needs a declared query class and operational preconditions.

Cost itself can leak into meaning when resources are bounded. A system killed after one second does not return the relation’s full answer set. Parallelism can add races or non-deterministic side effects that are absent from pure Horn clauses. Kowalski’s clean separation is most exact for logical, side-effect-free definitions paired with sound problem-solving strategies. Extending it to real systems requires naming resource limits and effects.

The paper also says the L/C division is not wholly unambiguous. A heuristic can be represented as meta-level control or compiled into object-level predicates. An index may look like storage control or a materialised logical relation. The test is not whether every feature has one metaphysical home. It is whether the chosen boundary makes invariants, transformations and obligations easier to see.

InterventionIntended control benefitMeaning-preservation obligation
Reorder subgoalsRun selective or instantiated calls firstRetain all compatible solutions and avoid new nontermination for the stated query class
Prune alternativesAvoid redundant branchesProve removed branches cannot supply required answers
Parallelise callsReduce latency and materialisationPreserve shared-variable consistency and account for side effects
Change storage/indexImprove retrieval costReturn the same relation under updates and duplicates
Bound searchMeet a resource budgetReturn “unknown” or an approximation instead of claiming the full logical answer
Historical placement

The paper joins controlled deduction, logic programming and relational databases

Kowalski credits Pat Hayes’s “computation = controlled deduction”, connects the argument to Bibel and Vaughan Pratt, reads Hewitt’s PLANNER as evidence that logic needs control, and invokes Codd’s separation of a relational view from storage and retrieval.

The 1979 article is not the first appearance of every ingredient. Kowalski’s earlier work on predicate logic as a programming language and connection-graph proof procedures supplied foundations; Colmerauer, Roussel, Warren, Clark, van Emden and others shaped the operational and semantic programme. The article’s contribution is synthetic: it turns those strands into an engineering equation and walks through the dimensions that can move independently.

The database analogy is especially durable. A query states a relation; an optimiser chooses join order, access paths and materialisation. Two physical plans can be extensionally equivalent while having radically different costs. Kowalski’s supplier/part examples anticipate input-sensitive ordering: begin with the relation constrained by the known constant, not with a static leftmost call.

Later work sharpens the premises. Drabent’s construction of a practical Prolog SAT solver treats a logic programme as a declarative object, proves correctness and completeness, then adds delay and pruning controls and separately proves that the required properties survive. Brand and Yap generalise the form to “Propagation = Logic + Control”, distinguishing the truth conditions of complex constraints from information about which propagation is relevant.

Other descendants move the boundary again. Knowledge-base systems such as IDP treat logic as a model of a domain and provide several inference services rather than one procedural reading. Tabled logic programming changes top-down control by retaining answers. Deductive databases compile declarative rules into physical plans. None of these developments makes the 1979 equation a complete architecture; together they show why its separation of concerns remained productive.

Fair historical claim

The companion treats A = L + C as Kowalski’s influential formulation, not as an isolated invention of declarative programming, search control or database optimisation. The primary paper itself names the ideas and collaborators on which it builds.

Two comprehensive reviews

What survived formal, historical and delivery challenge

Review one: scholarly fidelity and teaching. The reconstruction was checked across the complete author-hosted scan: abstract, A=L+C qualification, component diagram, clause notation, top-down and bottom-up grandparent derivations, procedural interpretation, permutation/quicksort contrast, data-structure separation, coroutining, Fibonacci, alternative-clause search, both path analyses, arrow notation, its input-sensitive limitation and the conclusion.

The largest fidelity risk was turning the equation into an absolute partition. The paper explicitly calls the boundary not wholly unambiguous and shows A=L₁+C₁=L₂+C₂. A second risk was claiming that all control preserves behaviour. The page keeps Kowalski’s first-approximation restriction and adds explicit soundness, completeness, termination and resource caveats from later work.

Review two: evidence fairness, language and accessibility. Historical credit remains distributed across Hayes, Codd, Hewitt, Bibel and the logic-programming collaborators cited by Kowalski. Later developments are labelled as context, not read backwards into 1979. The prose avoids treating Prolog’s particular left-to-right depth-first regime as the whole procedural interpretation.

All ten figures carry titles, descriptions, captions and source scopes. Animation is redundant, subtle and disabled under reduced-motion preference. The laboratory writes every state as text, verifies three independent invariants, distinguishes unreachable from unfinished search and exposes work rather than declaring one strategy universally best. Desktop, tablet and phone layouts are part of the release test.

Review verdict

Pass 1: formal and historical reconstruction: passed after restoring representation dependence, the boundary’s ambiguity and meaning-preservation premises. Pass 2: evidence and delivery: passed after distinguishing logical reachability, witness paths, operational traces, termination and bounded-resource outcomes.

Memory studio

Twelve cards for durable recall

1 · A = L + CAn algorithm can be analysed as a meaning-bearing logic plus a strategy-bearing control.
2 · LogicProblem knowledge, abstract procedure relations and data-structure definitions.
3 · ControlDirection, call scheduling, alternative search, storage and retrieval.
4 · InvariantA meaning-preserving control change alters behaviour without altering required answers.
5 · Horn clauseOne conclusion with joint conditions supports declarative and top-down procedural readings.
6 · Top-downBegin with a goal and reduce it to supporting subgoals.
7 · Bottom-upBegin with assertions and derive consequences towards a goal.
8 · RepresentationA stronger L, such as partition-based sorting, can dominate search improvements.
9 · Flexible modesA relation can test, generate or solve backwards according to which arguments are known.
10 · SchedulingSequence, coroutining and parallelism realise the same conjunction differently.
11 · Moving boundaryThe same behaviour may be analysed as L₁+C₁ or L₂+C₂.
12 · Main lessonOptimise the how while proving that the what survives.
Place in the canon

Negation’s proof boundary becomes programming’s control boundary

Paper 0091 asked when a failed proof search justifies a negative conclusion. Paper 0092 broadens the view: proof search itself is the control component of an algorithm whose logic component states what counts as an answer.

Clark’s finite-failure condition already showed that operational details have semantic consequences. A loop cannot license negation, and a selection rule can determine whether failure becomes visible. Kowalski supplies the organising vocabulary: the completed or relational content belongs to L; selection, direction and alternative search belong to C.

The connection is not that meaning and control are independent in every observable sense. It is that separating them makes their interaction testable. One can ask whether a proposed C terminates, remains complete and respects L. Without that split, a missed answer is merely “programme behaviour”; with it, the miss can be diagnosed as representation, search, pruning or scheduling.

Canon 0093 moves to Raymond Reiter’s “A Logic for Default Reasoning”. Clark and Kowalski have established two pressures that default logic answers in a different register: knowledge bases need principled defeasible conclusions, and reasoning systems need to distinguish object-level rules from the conditions that govern their use.

Interpretive synthesis

A programme becomes easier to improve when its promises survive a change of method

The equation’s deepest value is not that every line of code can be coloured logic or control. It is that an engineered system should expose a promise that remains stable while methods of keeping it change.

That promise is L: the relation between legitimate inputs and answers, expressed with enough domain structure to be intelligible and useful. The methods are C: which direction to reason, which subproblem to attend to, which alternative to explore, what to retain and how to retrieve it. Improvement becomes a controlled comparison only when the promise is held fixed.

The paper also resists a naïve celebration of abstraction. Permutation plus orderedness is beautifully direct but computationally weak under ordinary controls. A quicksort relation moves problem knowledge into L. Data abstraction improves clarity, yet specialisation may be required for speed. The useful boundary must serve both proof and execution.

Modern systems repeat this pattern. Database users state relations while optimisers select plans. Constraint modellers state conditions while propagators schedule inference. A graph query has a meaning while engines choose indexes and traversal orders. A machine-learning pipeline has a metric contract while schedulers choose batching and placement. In every case, performance work becomes safer when the invariant is executable.

The hard part is the verb “preserve”. A fast search that misses an answer, a parallel schedule that races, or an index that serves stale data has changed the effective programme. Kowalski’s equation is therefore not permission to ignore control. It is a demand to make control replaceable and then prove, test or monitor the boundary.

Worked example 11 · a query optimiser as C

A three-table join has a declarative result independent of join order. Starting with the most selective relation can reduce intermediate rows by orders of magnitude. The optimiser is allowed to choose that order because equivalence rules justify the same result. A stale statistic may make the plan slow; an incorrect rewrite may make it wrong. Performance and semantics require different checks.

Causal probe 11 · run metamorphic controls

Execute several valid controls over the same small instance and compare complete answer sets. Differences identify a preservation failure; equal answers with different traces reveal genuine control effects. The Paper 0092 laboratory is this experiment in miniature.

Worked example 12 · bounded agency

An agent can represent the rule “approve only if every required check passes” as L. It can order checks cheaply first, run independent checks in parallel and cache stable results as C. If a timeout is reported as approval, control has violated logic. If it is reported as unknown, the system preserves the distinction between truth and unfinished work.

Causal probe 12 · remove the semantic oracle

Without a control-independent specification or exhaustive small-instance oracle, two fast implementations can agree on the same mistake. Preserve L as a testable artefact; do not let the currently fastest C become the only definition of correctness.

Publication brief

Primary source, companion scope and verification contract

This companion reconstructs Robert Kowalski’s “Algorithm = Logic + Control”, published in Communications of the ACM, volume 22, number 7, July 1979, pages 424–436, DOI 10.1145/359131.359136. The primary text was checked from the author-hosted 13-page scan, including diagrams, received/revised dates and references. The article covers the analytical equation, Horn-clause notation, reasoning direction, procedural interpretation, logical representation, data structures, call scheduling, alternative procedures, relational storage, path-finding analyses and graphical control notation.

Verification contract. Five orientation claims, ten accessible animated SVG figures, twelve worked examples, twelve causal probes, twelve memory cards, two comprehensive reviews and three executable exact tests. The release checks British English, reduced-motion support, responsive rendering at 1440, 768 and 390 pixels, source boundaries, complete reference metadata, explicit unreachable outcomes and identical source/generated pages.

Sources

Primary text and scholarly context

  1. Kowalski, R. A. (1979). “Algorithm = Logic + Control.” Communications of the ACM, 22(7), 424–436. DOI: 10.1145/359131.359136. Author-hosted scan: .
  2. Kowalski, R. A. (1974). “Predicate Logic as Programming Language.” Information Processing 74, 569–574.
  3. van Emden, M. H., & Kowalski, R. A. (1976). “The Semantics of Predicate Logic as a Programming Language.” Journal of the ACM, 23(4), 733–742.
  4. Codd, E. F. (1970). “A Relational Model of Data for Large Shared Data Banks.” Communications of the ACM, 13(6), 377–387.
  5. Clark, K. L. (1978). “Negation as Failure.” In H. Gallaire & J. Minker (eds.), Logic and Data Bases, 293–322.
  6. Kowalski, R. A. (1988). “The Early Years of Logic Programming.” Communications of the ACM, 31(1), 38–43.
  7. McCarthy, J. (1982). “Coloring Maps and the Kowalski Doctrine.” Stanford University Computer Science Department.
  8. Drabent, W. (2018). “Logic + Control: On Program Construction and Verification.” Theory and Practice of Logic Programming, 18(1), 1–38. arXiv:1110.4978.
  9. Brand, S., & Yap, R. H. C. (2006). “Towards ‘Propagation = Logic + Control’.” In Principles and Practice of Constraint Programming. arXiv:cs/0608015.
  10. De Cat, B., Bogaerts, B., Bruynooghe, M., Janssens, G., & Denecker, M. (2018). “Predicate Logic as a Modelling Language: The IDP System.” In Declarative Logic Programming. arXiv:1401.6312.