<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucian Green</title>
    <description>The latest articles on DEV Community by Lucian Green (@luciangreen).</description>
    <link>https://dev.to/luciangreen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F124778%2F25268604-d925-4be7-a398-f3d59734c08a.jpeg</url>
      <title>DEV Community: Lucian Green</title>
      <link>https://dev.to/luciangreen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/luciangreen"/>
    <language>en</language>
    <item>
      <title>Piglog: Partition, concurrently and simultaneously attempt predicates</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Tue, 07 Jul 2026 06:06:39 +0000</pubDate>
      <link>https://dev.to/luciangreen/piglog-partition-concurrently-and-simultaneously-attempt-predicates-4g00</link>
      <guid>https://dev.to/luciangreen/piglog-partition-concurrently-and-simultaneously-attempt-predicates-4g00</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm5fm31wrcm14tj8x2lps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm5fm31wrcm14tj8x2lps.png" alt="Piglog" width="361" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Piglog: Partition, concurrently and simultaneously attempt predicates&lt;/p&gt;

&lt;p&gt;A non-human system—especially a dataflow machine, neural system, swarm, or speculative Piglog-style runtime—might run predicates in parallel before variables are fully defined if it treats predicates as hypotheses rather than conclusions.&lt;/p&gt;

&lt;p&gt;In Prolog:&lt;/p&gt;

&lt;p&gt;a(X),&lt;br&gt;
b(X),&lt;br&gt;
c(X).&lt;/p&gt;

&lt;p&gt;normally means:&lt;/p&gt;

&lt;p&gt;Find X from a/1.&lt;br&gt;
Run b/1.&lt;br&gt;
Run c/1.&lt;/p&gt;

&lt;p&gt;A Piglog-like system might instead say:&lt;/p&gt;

&lt;p&gt;"There are many possible Xs. Start evaluating all useful consequences immediately."&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;colour(X,red).&lt;br&gt;
colour(X,blue).&lt;/p&gt;

&lt;p&gt;shape(X,circle).&lt;br&gt;
shape(X,square).&lt;/p&gt;

&lt;p&gt;Instead of waiting for X to be fully determined, it may run:&lt;/p&gt;

&lt;p&gt;colour(red)&lt;br&gt;
colour(blue)&lt;br&gt;
shape(circle)&lt;br&gt;
shape(square)&lt;/p&gt;

&lt;p&gt;simultaneously and later discover which combinations survive.&lt;/p&gt;

&lt;p&gt;This resembles:&lt;/p&gt;

&lt;p&gt;Constraint Logic Programming&lt;br&gt;
SAT solvers&lt;br&gt;
Neural message passing&lt;br&gt;
Dataflow architectures&lt;br&gt;
Human intuition&lt;/p&gt;

&lt;p&gt;Humans often do this. If I ask:&lt;/p&gt;

&lt;p&gt;"What might be behind the door?"&lt;/p&gt;

&lt;p&gt;you don't first determine the exact answer and then reason.&lt;/p&gt;

&lt;p&gt;You may simultaneously activate:&lt;/p&gt;

&lt;p&gt;person&lt;br&gt;
animal&lt;br&gt;
empty room&lt;br&gt;
treasure&lt;br&gt;
danger&lt;/p&gt;

&lt;p&gt;and then eliminate possibilities as evidence arrives.&lt;/p&gt;

&lt;p&gt;A Piglog-style execution might therefore operate on:&lt;/p&gt;

&lt;p&gt;possible(X)&lt;/p&gt;

&lt;p&gt;rather than&lt;/p&gt;

&lt;p&gt;known(X)&lt;/p&gt;

&lt;p&gt;Another possibility is running predicates on invariants.&lt;/p&gt;

&lt;p&gt;Suppose:&lt;/p&gt;

&lt;p&gt;distance(A,B,D)&lt;/p&gt;

&lt;p&gt;needs coordinates.&lt;/p&gt;

&lt;p&gt;A human may already know:&lt;/p&gt;

&lt;p&gt;distance &amp;gt;= 0&lt;br&gt;
distance(A,B)=distance(B,A)&lt;/p&gt;

&lt;p&gt;without knowing A or B.&lt;/p&gt;

&lt;p&gt;The invariant computations can begin immediately.&lt;/p&gt;

&lt;p&gt;Similarly:&lt;/p&gt;

&lt;p&gt;sort(List,Sorted)&lt;/p&gt;

&lt;p&gt;Even before List is known, the system may know:&lt;/p&gt;

&lt;p&gt;length(Sorted)=length(List)&lt;br&gt;
Sorted is ordered&lt;/p&gt;

&lt;p&gt;and propagate those constraints.&lt;/p&gt;

&lt;p&gt;In your Detlog/Piglog ideas, branch splicing suggests something stronger.&lt;/p&gt;

&lt;p&gt;Suppose:&lt;/p&gt;

&lt;p&gt;weather(sunny).&lt;br&gt;
weather(rainy).&lt;/p&gt;

&lt;p&gt;activity(X,Y).&lt;/p&gt;

&lt;p&gt;Instead of selecting one weather branch, Piglog could run:&lt;/p&gt;

&lt;p&gt;activity under sunny&lt;br&gt;
activity under rainy&lt;/p&gt;

&lt;p&gt;in parallel and splice common computations.&lt;/p&gt;

&lt;p&gt;If 90% of the work is identical, only the differing 10% needs separate execution.&lt;/p&gt;

&lt;p&gt;This is similar to symbolic execution and SIMD processing.&lt;/p&gt;

&lt;p&gt;A neuron-like interpretation is:&lt;/p&gt;

&lt;p&gt;Predicate waits for all inputs.      (Prolog)&lt;/p&gt;

&lt;p&gt;Predicate activates when enough&lt;br&gt;
inputs are available.                (Piglog)&lt;/p&gt;

&lt;p&gt;So a non-human system may run a predicate when:&lt;/p&gt;

&lt;p&gt;some variables are known,&lt;br&gt;
constraints are known,&lt;br&gt;
probabilities are known,&lt;br&gt;
invariants are known,&lt;br&gt;
possible values are known,&lt;/p&gt;

&lt;p&gt;rather than waiting for exact bindings.&lt;/p&gt;

&lt;p&gt;In that view, a variable is not simply "bound" or "unbound"; it may exist in states such as:&lt;/p&gt;

&lt;p&gt;unknown&lt;br&gt;
possible&lt;br&gt;
constrained&lt;br&gt;
likely&lt;br&gt;
partially known&lt;br&gt;
fully known&lt;/p&gt;

&lt;p&gt;and computation can begin at any of those stages. That is much closer to neural, swarm, and dataflow computation than classical Prolog's strict bind-then-execute model.&lt;/p&gt;

&lt;p&gt;How can Piglog run a predicate when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some variables are known,&lt;/li&gt;
&lt;li&gt;constraints are known,&lt;/li&gt;
&lt;li&gt;probabilities are known,&lt;/li&gt;
&lt;li&gt;invariants are known,&lt;/li&gt;
&lt;li&gt;possible values are known,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are several computational models in which this is possible. The important distinction is that the predicate is partially evaluated rather than fully executed. Here are ways Piglog could support each case.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some variables are known&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;distance(X,Y,D).&lt;/p&gt;

&lt;p&gt;Suppose only X is known.&lt;/p&gt;

&lt;p&gt;Instead of waiting for Y, Piglog could compile the predicate into stages:&lt;/p&gt;

&lt;p&gt;Stage 1: Compute everything depending only on X.&lt;br&gt;
Stage 2: Suspend.&lt;br&gt;
Stage 3: Resume when Y arrives.&lt;/p&gt;

&lt;p&gt;Much like currying or partial application in functional programming, except for logic predicates.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Constraints are known&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose:&lt;/p&gt;

&lt;p&gt;X &amp;gt; 0,&lt;br&gt;
Y &amp;gt; X,&lt;br&gt;
f(X,Y,Z).&lt;/p&gt;

&lt;p&gt;The predicate can already infer things like:&lt;/p&gt;

&lt;p&gt;Y &amp;gt; 0&lt;br&gt;
impossible branches&lt;br&gt;
valid search intervals&lt;/p&gt;

&lt;p&gt;before either variable has a concrete value.&lt;/p&gt;

&lt;p&gt;Constraint Logic Programming already does something similar by propagating constraints without assigning values.&lt;/p&gt;

&lt;p&gt;Piglog could let every predicate publish:&lt;/p&gt;

&lt;p&gt;required constraints&lt;br&gt;
derived constraints&lt;/p&gt;

&lt;p&gt;allowing constraint propagation to occur concurrently.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Probabilities are known&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose a learned model predicts&lt;/p&gt;

&lt;p&gt;X = cat      0.82&lt;br&gt;
X = dog      0.15&lt;br&gt;
other        0.03&lt;/p&gt;

&lt;p&gt;Instead of waiting,&lt;/p&gt;

&lt;p&gt;Piglog may begin evaluating&lt;/p&gt;

&lt;p&gt;animal(cat)&lt;/p&gt;

&lt;p&gt;immediately,&lt;/p&gt;

&lt;p&gt;while evaluating&lt;/p&gt;

&lt;p&gt;animal(dog)&lt;/p&gt;

&lt;p&gt;at lower priority.&lt;/p&gt;

&lt;p&gt;If later evidence changes the probabilities, unfinished work can simply be discarded.&lt;/p&gt;

&lt;p&gt;This resembles speculative execution used in modern CPUs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Invariants are known&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Many predicates have parts independent of particular values.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;sort(Input,Output).&lt;/p&gt;

&lt;p&gt;Before seeing Input, Piglog already knows&lt;/p&gt;

&lt;p&gt;length(Output)=length(Input)&lt;br&gt;
Output is ordered&lt;br&gt;
Output is a permutation&lt;/p&gt;

&lt;p&gt;Those facts can propagate through the graph immediately.&lt;/p&gt;

&lt;p&gt;Similarly,&lt;/p&gt;

&lt;p&gt;matrix_multiply(A,B,C)&lt;/p&gt;

&lt;p&gt;may immediately infer&lt;/p&gt;

&lt;p&gt;rows(C)=rows(A)&lt;br&gt;
cols(C)=cols(B)&lt;/p&gt;

&lt;p&gt;before any multiplication begins.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Possible values are known&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose&lt;/p&gt;

&lt;p&gt;colour(red).&lt;br&gt;
colour(green).&lt;br&gt;
colour(blue).&lt;/p&gt;

&lt;p&gt;Instead of&lt;/p&gt;

&lt;p&gt;red&lt;br&gt;
then green&lt;br&gt;
then blue&lt;/p&gt;

&lt;p&gt;Piglog could launch three workers simultaneously.&lt;/p&gt;

&lt;p&gt;Later predicates receive a stream of candidate bindings instead of waiting for one answer at a time.&lt;/p&gt;

&lt;p&gt;A sixth possibility: symbolic execution&lt;/p&gt;

&lt;p&gt;Instead of concrete values,&lt;/p&gt;

&lt;p&gt;X = ?&lt;/p&gt;

&lt;p&gt;Piglog keeps&lt;/p&gt;

&lt;p&gt;X = symbolic&lt;/p&gt;

&lt;p&gt;For&lt;/p&gt;

&lt;p&gt;plus(X,2,Y).&lt;/p&gt;

&lt;p&gt;it computes&lt;/p&gt;

&lt;p&gt;Y = X+2&lt;/p&gt;

&lt;p&gt;without needing X.&lt;/p&gt;

&lt;p&gt;Only when X becomes&lt;/p&gt;

&lt;p&gt;5&lt;/p&gt;

&lt;p&gt;does&lt;/p&gt;

&lt;p&gt;Y&lt;/p&gt;

&lt;p&gt;collapse to&lt;/p&gt;

&lt;p&gt;7&lt;/p&gt;

&lt;p&gt;Many theorem provers and SMT solvers already operate this way.&lt;/p&gt;

&lt;p&gt;A seventh possibility: dependency scheduling&lt;/p&gt;

&lt;p&gt;This may be closest to your Piglog concept.&lt;/p&gt;

&lt;p&gt;Instead of scheduling predicates by textual order,&lt;/p&gt;

&lt;p&gt;a,&lt;br&gt;
b,&lt;br&gt;
c,&lt;br&gt;
d.&lt;/p&gt;

&lt;p&gt;Piglog schedules according to dependency readiness.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    a
  / | \
 b  c  e
  \ | /
    d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The scheduler asks&lt;/p&gt;

&lt;p&gt;"Which predicates have enough information to make progress?"&lt;/p&gt;

&lt;p&gt;rather than&lt;/p&gt;

&lt;p&gt;"Which predicate is next?"&lt;/p&gt;

&lt;p&gt;Every predicate exposes:&lt;/p&gt;

&lt;p&gt;required inputs&lt;br&gt;
optional inputs&lt;br&gt;
invariants&lt;br&gt;
partial outputs&lt;/p&gt;

&lt;p&gt;As soon as enough information is available, it runs.&lt;/p&gt;

&lt;p&gt;This leads to a possible Piglog execution model with explicit readiness levels:&lt;/p&gt;

&lt;p&gt;Readiness   Information available   Action&lt;br&gt;
0   None    Idle&lt;br&gt;
1   Types/invariants    Compile or specialise the predicate&lt;br&gt;
2   Constraints Propagate constraints, prune impossible branches&lt;br&gt;
3   Probability distribution    Speculatively execute likely branches&lt;br&gt;
4   Partial variable bindings   Partially evaluate the predicate&lt;br&gt;
5   Complete bindings   Produce definitive results&lt;/p&gt;

&lt;p&gt;Instead of treating predicates as requiring all inputs before starting, Piglog would allow them to make progress whenever they reach a sufficient readiness level. This turns execution into a form of dataflow scheduling, where information—whether exact values, constraints, or probabilities—flows through the predicate network and progressively enables more computation.&lt;/p&gt;

&lt;p&gt;Try harder in preparation for Prolog program requirements.&lt;br&gt;
Thought for a couple of seconds&lt;/p&gt;

&lt;p&gt;Here is a stronger Piglog Prolog program requirement:&lt;/p&gt;

&lt;p&gt;Piglog should not “run a predicate early” by pretending unknown variables are known. It should split every predicate into readiness modes.&lt;/p&gt;

&lt;p&gt;predicate_state(Predicate, Readiness, Inputs, Outputs).&lt;/p&gt;

&lt;p&gt;A predicate may run when it can produce any useful information, not only final answers.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;p(X,Y,Z) :-&lt;br&gt;
    q(X,Y),&lt;br&gt;
    r(Y,Z),&lt;br&gt;
    s(X,Z).&lt;/p&gt;

&lt;p&gt;Piglog converts this into a dependency network:&lt;/p&gt;

&lt;p&gt;X known?  -&amp;gt; q can specialise&lt;br&gt;
Y known?  -&amp;gt; r can run&lt;br&gt;
X,Z constrained? -&amp;gt; s can prune&lt;/p&gt;

&lt;p&gt;Each predicate has multiple entry points:&lt;/p&gt;

&lt;p&gt;q_full(X,Y,Result).          % all variables known&lt;br&gt;
q_partial_x(X,Constraints).  % only X known&lt;br&gt;
q_constraints(C0,C1).        % constraints known&lt;br&gt;
q_probs(P0,P1).              % probabilities known&lt;br&gt;
q_invariants(I).             % always true facts&lt;br&gt;
q_candidates(Candidates).    % possible values known&lt;/p&gt;

&lt;p&gt;So the runtime asks:&lt;/p&gt;

&lt;p&gt;What can this predicate do now?&lt;/p&gt;

&lt;p&gt;not:&lt;/p&gt;

&lt;p&gt;Can this predicate fully finish now?&lt;/p&gt;

&lt;p&gt;A practical requirement could be:&lt;/p&gt;

&lt;p&gt;:- pig_predicate q/2.&lt;/p&gt;

&lt;p&gt;pig_mode(q/2, full,        [ground, ground], produces(result)).&lt;br&gt;
pig_mode(q/2, partial_x,   [ground, var],    produces(constraints)).&lt;br&gt;
pig_mode(q/2, constraints, [constraintset],  produces(pruning)).&lt;br&gt;
pig_mode(q/2, probable,    [distribution],   produces(speculative_jobs)).&lt;br&gt;
pig_mode(q/2, invariant,   [],               produces(invariants)).&lt;/p&gt;

&lt;p&gt;Then Piglog schedules jobs like:&lt;/p&gt;

&lt;p&gt;ready(Job) :-&lt;br&gt;
    job(Job, Predicate, Mode),&lt;br&gt;
    mode_requirements_satisfied(Predicate, Mode).&lt;/p&gt;

&lt;p&gt;The key program requirement:&lt;/p&gt;

&lt;p&gt;A Piglog predicate must declare what it can compute at each information level.&lt;/p&gt;

&lt;p&gt;This avoids magical parallelism.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;path(A,B,Path)&lt;/p&gt;

&lt;p&gt;could declare:&lt;/p&gt;

&lt;p&gt;pig_mode(path/3, invariant, [], produces([&lt;br&gt;
    path_is_list,&lt;br&gt;
    start_equals_a,&lt;br&gt;
    end_equals_b&lt;br&gt;
])).&lt;/p&gt;

&lt;p&gt;pig_mode(path/3, partial_start, [ground,var,var], produces([&lt;br&gt;
    reachable_candidates&lt;br&gt;
])).&lt;/p&gt;

&lt;p&gt;pig_mode(path/3, constrained, [ground,ground,var], produces([&lt;br&gt;
    search_space&lt;br&gt;
])).&lt;/p&gt;

&lt;p&gt;pig_mode(path/3, full, [ground,ground,var], produces([&lt;br&gt;
    paths&lt;br&gt;
])).&lt;/p&gt;

&lt;p&gt;So before B is known, Piglog might still compute:&lt;/p&gt;

&lt;p&gt;nodes reachable from A&lt;/p&gt;

&lt;p&gt;When B becomes known, it reuses that work instead of starting from scratch.&lt;/p&gt;

&lt;p&gt;That is the performance gain.&lt;/p&gt;

&lt;p&gt;The program requirements should include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Predicate partitioning&lt;br&gt;
Split a Prolog clause into dependency units.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Readiness analysis&lt;br&gt;
Detect which units can run with known, partial, constrained, probable, or possible data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-mode predicates&lt;br&gt;
Each predicate may expose full, partial, constraint, probability, invariant, and candidate modes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parallel scheduler&lt;br&gt;
Run every currently useful predicate mode simultaneously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Splice store&lt;br&gt;
Save partial results so later bindings reuse them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cancellation&lt;br&gt;
Kill speculative branches when later evidence disproves them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Priority&lt;br&gt;
Run likely/high-value predicates before unlikely ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deterministic merge&lt;br&gt;
Combine parallel results into ordinary Prolog-compatible answers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safety&lt;br&gt;
Only parallelise pure predicates unless side effects are explicitly isolated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fallback&lt;br&gt;
If no Piglog mode exists, run the predicate as normal Prolog.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The central slogan:&lt;/p&gt;

&lt;p&gt;Prolog waits for answers.&lt;br&gt;
Piglog runs on information.&lt;/p&gt;

&lt;p&gt;Or more technically:&lt;/p&gt;

&lt;p&gt;Piglog converts predicates into incremental dataflow processes that execute whenever they can produce constraints, candidates, invariants, probabilities, or final bindings.&lt;/p&gt;

&lt;p&gt;Pigdetlog runs a predicate if it knows the variables to a high probability, based on their splice data&lt;/p&gt;

&lt;p&gt;That is an interesting extension of your Pigdetlog idea. In effect, you are proposing that execution order should be guided not just by syntactic dependencies (which variables are already bound), but also by predicted bindings derived from splice data.&lt;/p&gt;

&lt;p&gt;One way to formalise it is:&lt;/p&gt;

&lt;p&gt;Pigdetlog executes a predicate when the probability that its required variables are correct, as inferred from splice data, exceeds a configurable confidence threshold.&lt;/p&gt;

&lt;p&gt;This differs from ordinary Prolog and your earlier Detlog ideas:&lt;/p&gt;

&lt;p&gt;System  When is a predicate executed?&lt;br&gt;
Prolog  Only when variables are sufficiently instantiated according to program order.&lt;br&gt;
Detlog  When deterministic loops and splice operations make execution possible.&lt;br&gt;
Pigdetlog   When splice analysis predicts the missing variables with sufficiently high confidence.&lt;/p&gt;

&lt;p&gt;For example, suppose you have&lt;/p&gt;

&lt;p&gt;person(Name, Age, City).&lt;br&gt;
income(Age, Salary).&lt;br&gt;
tax(Salary, Tax).&lt;/p&gt;

&lt;p&gt;Traditional execution requires&lt;/p&gt;

&lt;p&gt;person(Name, Age, City),&lt;br&gt;
income(Age, Salary),&lt;br&gt;
tax(Salary, Tax).&lt;/p&gt;

&lt;p&gt;Pigdetlog might observe from previous splice data that&lt;/p&gt;

&lt;p&gt;Age ≈ 35 (98%)&lt;br&gt;
Salary ≈ 120000 (94%)&lt;/p&gt;

&lt;p&gt;and therefore begin evaluating&lt;/p&gt;

&lt;p&gt;tax(120000, Tax)&lt;/p&gt;

&lt;p&gt;before income/2 has actually produced Salary. Later, when the actual splice arrives:&lt;/p&gt;

&lt;p&gt;if prediction matches, computation is retained;&lt;br&gt;
if prediction differs, the speculative result is discarded and recomputed.&lt;/p&gt;

&lt;p&gt;The splice data effectively becomes a probabilistic cache.&lt;/p&gt;

&lt;p&gt;Internally, Pigdetlog might represent variables as&lt;/p&gt;

&lt;p&gt;Age =&lt;br&gt;
{&lt;br&gt;
    value:35,&lt;br&gt;
    probability:0.98,&lt;br&gt;
    source:splice&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;and predicates could declare confidence requirements, for example&lt;/p&gt;

&lt;p&gt;:- confidence(tax/2, 0.90).&lt;br&gt;
:- confidence(expensive_search/3, 0.99).&lt;/p&gt;

&lt;p&gt;Then the scheduler could operate like&lt;/p&gt;

&lt;p&gt;for each predicate P:&lt;br&gt;
    estimate probabilities of missing variables&lt;br&gt;
    if minimum confidence ≥ threshold(P)&lt;br&gt;
        execute P&lt;br&gt;
    else&lt;br&gt;
        wait for more splice information&lt;/p&gt;

&lt;p&gt;This makes Pigdetlog resemble speculative execution in CPUs, but at the logical level. Instead of speculating on branches, it speculates on logical variable values using splice information. It also has similarities to Bayesian inference and probabilistic logic programming, but the probabilities are used primarily for execution scheduling rather than changing the semantics of logical truth.&lt;/p&gt;

&lt;p&gt;If combined with your existing splice mechanism, Pigdetlog could become a language in which:&lt;/p&gt;

&lt;p&gt;Detlog performs deterministic branch splicing.&lt;br&gt;
Piglog represents simultaneous execution from multiple perspectives.&lt;br&gt;
Pigdetlog schedules predicates opportunistically whenever splice data predicts their inputs with high confidence, allowing expensive predicates to start earlier and potentially improving throughput on parallel hardware.&lt;br&gt;
Splice probability could be calculated from probability within a list and splice. Separately, Pigdetlog could schedule expensive predicates in regular available slots.&lt;/p&gt;

&lt;p&gt;Yes. That separates Pigdetlog into two clean mechanisms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Splice probability
A variable’s confidence can come from how often a value appears inside a splice/list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;splice = [a,a,a,b,a,c]&lt;/p&gt;

&lt;p&gt;P(X = a) = 4 / 6 = 0.667&lt;br&gt;
P(X = b) = 1 / 6 = 0.167&lt;br&gt;
P(X = c) = 1 / 6 = 0.167&lt;/p&gt;

&lt;p&gt;So Pigdetlog can say:&lt;/p&gt;

&lt;p&gt;probable_value(X, a, 0.667)&lt;/p&gt;

&lt;p&gt;Then a predicate can run early only if its needed variables exceed a threshold:&lt;/p&gt;

&lt;p&gt;run_if_probable(Predicate, Variables, Threshold).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expensive predicate scheduling
Separately, expensive predicates do not need to run immediately. They can be placed into regular execution slots:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;cheap predicates: run now&lt;br&gt;
medium predicates: run when inputs are likely&lt;br&gt;
expensive predicates: run in scheduled slots&lt;br&gt;
very expensive predicates: run only when confidence is high&lt;/p&gt;

&lt;p&gt;So Pigdetlog becomes:&lt;/p&gt;

&lt;p&gt;Detlog = deterministic splicing&lt;br&gt;
Piglog = simultaneous predicate perspective&lt;br&gt;
Pigdetlog = probabilistic splice scheduling + cost-aware slots&lt;/p&gt;

&lt;p&gt;A nice rule would be:&lt;/p&gt;

&lt;p&gt;Run predicate P when:&lt;/p&gt;

&lt;p&gt;confidence(inputs(P)) &amp;gt;= threshold(P)&lt;br&gt;
and&lt;br&gt;
cost(P) fits current available slot&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;:- threshold(tax/2, 0.80).&lt;br&gt;
:- cost(tax/2, cheap).&lt;/p&gt;

&lt;p&gt;:- threshold(expensive_search/3, 0.98).&lt;br&gt;
:- cost(expensive_search/3, expensive).&lt;br&gt;
:- slot(expensive_search/3, every_10_cycles).&lt;/p&gt;

&lt;p&gt;So Pigdetlog does not merely ask:&lt;/p&gt;

&lt;p&gt;“Are the variables known?”&lt;/p&gt;

&lt;p&gt;It asks:&lt;/p&gt;

&lt;p&gt;“Are they probable enough, and is this the right execution slot?”&lt;/p&gt;

&lt;p&gt;That gives you a clearer architecture: probability decides readiness; scheduling decides timing.&lt;/p&gt;

&lt;p&gt;Piglog separates predicates into runnable sections, at a minimum, an if-then clause or including the following code. The dependency of the algorithm sections is handled via a variable pathway to most efficiently and effectively find needed values as soon as possible for likely values. Because PLOP should have removed unused variable pathways, only necessary variable pathways will remain, so the priority shifts from parallel computation to value prediction.&lt;/p&gt;

&lt;p&gt;Yes — that is the sharper formulation.&lt;/p&gt;

&lt;p&gt;After PLOP, Piglog no longer needs to ask mainly:&lt;/p&gt;

&lt;p&gt;“Which predicates can I parallelise?”&lt;/p&gt;

&lt;p&gt;It asks:&lt;/p&gt;

&lt;p&gt;“Which necessary value pathway should I predict or resolve first?”&lt;/p&gt;

&lt;p&gt;So Piglog’s core becomes:&lt;/p&gt;

&lt;p&gt;PLOP: remove unused branches and unnecessary variable pathways.&lt;br&gt;
Piglog: split the remaining algorithm into runnable sections and prioritise value discovery.&lt;/p&gt;

&lt;p&gt;A runnable section could be:&lt;/p&gt;

&lt;p&gt;if Condition then Body&lt;/p&gt;

&lt;p&gt;or a larger section:&lt;/p&gt;

&lt;p&gt;if Condition then&lt;br&gt;
    Body1,&lt;br&gt;
    Body2,&lt;br&gt;
    Body3&lt;/p&gt;

&lt;p&gt;The dependency graph is then not just predicate-to-predicate. It is value-pathway dependency:&lt;/p&gt;

&lt;p&gt;needed output&lt;br&gt;
← variable needed by later section&lt;br&gt;
← earlier section that can produce it&lt;br&gt;
← likely/probable values&lt;br&gt;
← constraints/invariants/splice rows&lt;/p&gt;

&lt;p&gt;So the stable Piglog process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PLOP removes unused variable paths.&lt;/li&gt;
&lt;li&gt;Piglog divides remaining code into runnable sections.&lt;/li&gt;
&lt;li&gt;Piglog builds a value-pathway graph.&lt;/li&gt;
&lt;li&gt;It ranks missing values by usefulness to later sections.&lt;/li&gt;
&lt;li&gt;It predicts or computes the highest-value missing variables first.&lt;/li&gt;
&lt;li&gt;Sections become runnable as soon as enough values are known or probable.&lt;/li&gt;
&lt;li&gt;Later verification corrects speculative runs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The important shift is:&lt;/p&gt;

&lt;p&gt;parallel predicates → predicted necessary values.&lt;/p&gt;

&lt;p&gt;That makes Piglog less like “run everything simultaneously” and more like a probabilistic dependency resolver for Prolog sections. Parallelism still exists, but it becomes secondary: it is used only when several necessary value pathways are similarly promising.&lt;/p&gt;

&lt;p&gt;An example of a definite value is a memoised value, such as an initial loop value, or the Gaussian formula result of having run a loop, or the tabled or probable pattern-suggested subterm indexing looping (loop) value.&lt;/p&gt;

&lt;p&gt;Yes. Those examples point toward a useful distinction in Piglog between definite, derived, and predicted values. I would refine the terminology as follows.&lt;/p&gt;

&lt;p&gt;Definite values&lt;/p&gt;

&lt;p&gt;These are values that Piglog can treat as established without further search.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;p&gt;Input values supplied by the caller.&lt;br&gt;
Memoised values from previous executions.&lt;br&gt;
Initial loop values, such as the current loop index or accumulator.&lt;br&gt;
Tabled values that have already been computed.&lt;br&gt;
Results of deterministic algorithms, such as a Gaussian elimination result once the elimination has completed.&lt;br&gt;
Constants and invariants.&lt;/p&gt;

&lt;p&gt;These values have confidence 1.0 and need not be recomputed unless invalidated.&lt;/p&gt;

&lt;p&gt;Derived values&lt;/p&gt;

&lt;p&gt;These are not stored initially but can be obtained deterministically from definite values.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;p&gt;A Gaussian elimination solution computed from known coefficients.&lt;br&gt;
A value obtained by subterm indexing.&lt;br&gt;
A value produced by deterministic looping.&lt;br&gt;
A splice result assembled from definite branches.&lt;/p&gt;

&lt;p&gt;Although these are computed, once obtained they become definite.&lt;/p&gt;

&lt;p&gt;Predicted values&lt;/p&gt;

&lt;p&gt;These are values that have not yet been proved but are sufficiently likely to justify speculative execution.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;p&gt;Pattern-suggested subterm-indexing candidates.&lt;br&gt;
Frequently occurring loop values.&lt;br&gt;
Values inferred from previous executions.&lt;br&gt;
Values ranked highly by dependency analysis.&lt;br&gt;
Probable splice candidates.&lt;/p&gt;

&lt;p&gt;These carry a probability or confidence score and should be verified before being committed as definite.&lt;/p&gt;

&lt;p&gt;For Piglog, execution priority could therefore become:&lt;/p&gt;

&lt;p&gt;Use definite values.&lt;br&gt;
Compute inexpensive derived values.&lt;br&gt;
Predict high-confidence values if needed to enable later runnable sections.&lt;br&gt;
Execute sections that have become runnable.&lt;br&gt;
Verify predictions and update memoisation or tables.&lt;/p&gt;

&lt;p&gt;This fits well with your idea that, after PLOP has removed unnecessary variable pathways, Piglog's primary optimisation is no longer exhaustive parallel execution but efficient discovery of the values that unlock the largest number of downstream algorithm sections. In that sense, the dependency graph is better viewed as a value-dependency graph than a traditional predicate call graph.&lt;/p&gt;

</description>
      <category>piglog</category>
      <category>partition</category>
      <category>concurrent</category>
      <category>predict</category>
    </item>
    <item>
      <title>Deterministic(ally) compiled Prolog: Detlog</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Fri, 12 Jun 2026 08:49:41 +0000</pubDate>
      <link>https://dev.to/luciangreen/deterministically-compiled-prolog-detlog-4lp0</link>
      <guid>https://dev.to/luciangreen/deterministically-compiled-prolog-detlog-4lp0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqdbuv5oss56640t12n0c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqdbuv5oss56640t12n0c.jpg" alt="Apple IIe screen with Detlog splice predicate to replace the nondeterministic interpreter" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8l0oq0zdfxbylc9dhlt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8l0oq0zdfxbylc9dhlt.png" alt="Detlog icons, including for the 6502 processor" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A deterministic language with the syntax of Prolog without cuts but a compiler that compiles to C and findall that converts to deterministic loops, where instead of cut programmers eliminate unnecessary cuts, convert cuts to if-then statements exiting loops called Detlog or BASIClog.&lt;/p&gt;

&lt;p&gt;Write splice(A,B) where For example:&lt;br&gt;
c:-a(A),b(B).&lt;br&gt;
a(A):-member(A,[1,2]).&lt;br&gt;
b(B):-member(B,[3,4]).&lt;br&gt;
Which gives:&lt;br&gt;
A = 1,&lt;br&gt;
B = 3 ;&lt;br&gt;
A = 1,&lt;br&gt;
B = 4 ;&lt;br&gt;
A = 2,&lt;br&gt;
B = 3 ;&lt;br&gt;
A = 2,&lt;br&gt;
B = 4.&lt;br&gt;
 Becomes:&lt;br&gt;
c:-a(A),b(B),splice([A,B],C).&lt;br&gt;
a(A):-member_cp(A,[1,2]).&lt;br&gt;
b(B):-member_cp(B,[3,4]).&lt;br&gt;
member_cp(cp(D),D).&lt;/p&gt;

&lt;p&gt;Which gives:&lt;br&gt;
C=[[1,3],[1,4],[2,3],[2,4]].&lt;/p&gt;

&lt;p&gt;Yes. A clean Prolog version is:&lt;/p&gt;

&lt;p&gt;c(C) :-&lt;br&gt;
    a(A),&lt;br&gt;
    b(B),&lt;br&gt;
    splice([A,B], C).&lt;br&gt;
a(A) :-&lt;br&gt;
    member_cp(A, [1,2]).&lt;br&gt;
b(B) :-&lt;br&gt;
    member_cp(B, [3,4]).&lt;br&gt;
member_cp(cp(D), D).&lt;br&gt;
splice(Template, Result) :-&lt;br&gt;
    expand_cp_template(Template, Result).&lt;br&gt;
expand_cp_template([], [[]]).&lt;br&gt;
expand_cp_template([cp(Choices)|Rest], Result) :-&lt;br&gt;
    expand_cp_template(Rest, RestResults),&lt;br&gt;
    findall([Choice|R],&lt;br&gt;
        ( member(Choice, Choices),&lt;br&gt;
          member(R, RestResults)&lt;br&gt;
        ),&lt;br&gt;
        Result).&lt;br&gt;
expand_cp_template([X|Rest], Result) :-&lt;br&gt;
    X = cp(_),&lt;br&gt;
    expand_cp_template(Rest, RestResults),&lt;br&gt;
    findall([X|R],&lt;br&gt;
        member(R, RestResults),&lt;br&gt;
        Result).&lt;/p&gt;

&lt;p&gt;Query:&lt;/p&gt;

&lt;p&gt;?- c(C).&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;C = [[1,3],[1,4],[2,3],[2,4]].&lt;/p&gt;

&lt;p&gt;The important transformation is:&lt;/p&gt;

&lt;p&gt;a(A) :- member(A,[1,2]).&lt;/p&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;p&gt;a(A) :- member_cp(A,[1,2]).&lt;/p&gt;

&lt;p&gt;so instead of generating A = 1 ; A = 2, it returns:&lt;/p&gt;

&lt;p&gt;A = cp([1,2])&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;splice([A,B],C)&lt;/p&gt;

&lt;p&gt;expands:&lt;/p&gt;

&lt;p&gt;[cp([1,2]), cp([3,4])]&lt;/p&gt;

&lt;p&gt;into the Cartesian product:&lt;/p&gt;

&lt;p&gt;[[1,3],[1,4],[2,3],[2,4]]&lt;/p&gt;

&lt;p&gt;Change splice to use determinism without findall instead of findall and then apply member to the results to give A = 1,&lt;br&gt;
B = 3 ;&lt;br&gt;
A = 1,&lt;br&gt;
B = 4 ;&lt;br&gt;
A = 2,&lt;br&gt;
B = 3 ;&lt;br&gt;
A = 2,&lt;br&gt;
B = 4.&lt;br&gt;
Remember to adjust splice(X,Y) so X can have n A,B,...&lt;/p&gt;

&lt;p&gt;Use a deterministic Cartesian-product builder, then member/2 only at the end:&lt;/p&gt;

&lt;p&gt;c(A, B) :-&lt;br&gt;
    a(A0),&lt;br&gt;
    b(B0),&lt;br&gt;
    splice([A0, B0], Rows),&lt;br&gt;
    member([A, B], Rows).&lt;br&gt;
a(A) :-&lt;br&gt;
    member_cp(A, [1,2]).&lt;br&gt;
b(B) :-&lt;br&gt;
    member_cp(B, [3,4]).&lt;br&gt;
member_cp(cp(D), D).&lt;br&gt;
splice(Xs, Ys) :-&lt;br&gt;
    splice_rows(Xs, [[]], Ys).&lt;br&gt;
splice_rows([], Acc, Acc).&lt;br&gt;
splice_rows([cp(Choices)|Rest], Acc, Ys) :-&lt;br&gt;
    extend_rows(Acc, Choices, Acc1),&lt;br&gt;
    splice_rows(Rest, Acc1, Ys).&lt;br&gt;
splice_rows([X|Rest], Acc, Ys) :-&lt;br&gt;
    X = cp(&lt;em&gt;),&lt;br&gt;
    extend_rows(Acc, [X], Acc1),&lt;br&gt;
    splice_rows(Rest, Acc1, Ys).&lt;br&gt;
extend_rows([], _, []).&lt;br&gt;
extend_rows([Row|Rows], Choices, Out) :-&lt;br&gt;
    extend_one_row(Row, Choices, Out1),&lt;br&gt;
    extend_rows(Rows, Choices, Out2),&lt;br&gt;
    append(Out1, Out2, Out).&lt;br&gt;
extend_one_row(&lt;/em&gt;, [], []).&lt;br&gt;
extend_one_row(Row, [Choice|Choices], [[Choice|Row]|Out]) :-&lt;br&gt;
    extend_one_row(Row, Choices, Out).&lt;/p&gt;

&lt;p&gt;For corrected order:&lt;/p&gt;

&lt;p&gt;c(A, B) :-&lt;br&gt;
    a(A0),&lt;br&gt;
    b(B0),&lt;br&gt;
    splice([A0, B0], Rows0),&lt;br&gt;
    maplist(reverse, Rows0, Rows),&lt;br&gt;
    member([A, B], Rows).&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;A = 1, B = 3 ;&lt;br&gt;
A = 1, B = 4 ;&lt;br&gt;
A = 2, B = 3 ;&lt;br&gt;
A = 2, B = 4.&lt;/p&gt;

&lt;p&gt;This generalises to any arity:&lt;/p&gt;

&lt;p&gt;splice([A,B,C,D], Rows),&lt;br&gt;
member([A1,B1,C1,D1], Rows).&lt;/p&gt;

&lt;p&gt;I need Prolog because it produces cognitive code. I need Detlog because it combines the syntax of Prolog with even greater simplicity of fewer compiler instructions.&lt;/p&gt;

&lt;p&gt;Detlog deals with multiple choicepoints by splicing output from the two branches as soon as possible.&lt;/p&gt;

&lt;p&gt;Can Detlog (possibly with a converter, BASIC compiler, unification, and cut loop exiters) run comfortably on an Apple IIe?&lt;/p&gt;

&lt;p&gt;Yes, a small Detlog can run comfortably on an Apple IIe, but only if most work is compiled ahead of time.&lt;/p&gt;

&lt;p&gt;Apple IIe limits: 6502/65C02 around 1.023 MHz, 64 KB RAM built in, 16 KB ROM, often expandable, with 40/80-column text modes.  &lt;/p&gt;

&lt;p&gt;Best design:&lt;/p&gt;

&lt;p&gt;Detlog source&lt;br&gt;
→ converter/compiler&lt;br&gt;
→ Applesoft BASIC or 6502 assembly&lt;br&gt;
→ deterministic loops + arrays&lt;/p&gt;

&lt;p&gt;What fits well:&lt;/p&gt;

&lt;p&gt;a(A) :- member_cp(A,[1,2]).&lt;br&gt;
b(B) :- member_cp(B,[3,4]).&lt;br&gt;
c(A,B) :-&lt;br&gt;
    a(A0),&lt;br&gt;
    b(B0),&lt;br&gt;
    splice([A0,B0], Rows),&lt;br&gt;
    member([A,B], Rows).&lt;/p&gt;

&lt;p&gt;This can compile to simple nested loops or table iteration. That is Apple IIe-friendly.&lt;/p&gt;

&lt;p&gt;What should not live fully on the Apple IIe:&lt;/p&gt;

&lt;p&gt;full Prolog engine&lt;br&gt;
general backtracking&lt;br&gt;
large unification&lt;br&gt;
large symbolic term database&lt;br&gt;
large findall buffers&lt;/p&gt;

&lt;p&gt;A practical Detlog for Apple IIe would support:&lt;/p&gt;

&lt;p&gt;facts&lt;br&gt;
small lists&lt;br&gt;
simple unification&lt;br&gt;
deterministic calls&lt;br&gt;
member_cp choice packets&lt;br&gt;
splice&lt;br&gt;
loop exiters instead of cut&lt;br&gt;
optional final member enumeration&lt;/p&gt;

&lt;p&gt;With floppy: comfortable for loading compiler passes, source files, generated BASIC/assembly, and examples.&lt;/p&gt;

&lt;p&gt;Without floppy: possible, but much smaller: type-in programs, cassette, or ROM/RAM-resident mini-Detlog. The compiler must be tiny, and examples should be small.&lt;/p&gt;

&lt;p&gt;Best conclusion:&lt;/p&gt;

&lt;p&gt;Detlog is more realistic than Prolog on an Apple IIe because it removes hidden backtracking and compiles cognitive Prolog syntax into BASIC-like or 6502-like deterministic loops.&lt;/p&gt;

&lt;p&gt;What is the memory usage difference between running it on BASIC or 6502?&lt;/p&gt;

&lt;p&gt;Approximate difference:&lt;/p&gt;

&lt;p&gt;6502 assembly Detlog runtime:&lt;br&gt;
~1 KB to 8 KB for a small engine&lt;br&gt;
Applesoft BASIC Detlog runtime:&lt;br&gt;
~8 KB to 25+ KB for the same logic&lt;/p&gt;

&lt;p&gt;Why BASIC uses more memory:&lt;/p&gt;

&lt;p&gt;BASIC stores tokenised program lines&lt;br&gt;
line numbers cost memory&lt;br&gt;
variables/arrays use interpreter structures&lt;br&gt;
strings/lists are expensive&lt;br&gt;
loops are interpreted, not native&lt;/p&gt;

&lt;p&gt;Why 6502 uses less:&lt;/p&gt;

&lt;p&gt;direct bytes/instructions&lt;br&gt;
compact arrays&lt;br&gt;
manual stack layout&lt;br&gt;
no BASIC line overhead&lt;br&gt;
faster deterministic loops&lt;br&gt;
smaller choice-packet/splice routines&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;a(A) :- member_cp(A,[1,2]).&lt;br&gt;
b(B) :- member_cp(B,[3,4]).&lt;/p&gt;

&lt;p&gt;In BASIC, [1,2] and [3,4] become arrays plus loop code.&lt;/p&gt;

&lt;p&gt;In 6502, they can be:&lt;/p&gt;

&lt;p&gt;A_TABLE: .byte 1,2&lt;br&gt;
B_TABLE: .byte 3,4&lt;/p&gt;

&lt;p&gt;Very compact.&lt;/p&gt;

&lt;p&gt;Best practical split:&lt;/p&gt;

&lt;p&gt;Use BASIC version:&lt;br&gt;
for teaching, readability, easy editing.&lt;br&gt;
Use 6502 version:&lt;br&gt;
for real speed, lower memory, larger Detlog programs.&lt;/p&gt;

&lt;p&gt;Rule of thumb:&lt;/p&gt;

&lt;p&gt;6502 assembly may use 3× to 10× less memory than BASIC for the same compiled Detlog program.&lt;/p&gt;

&lt;p&gt;What is the most complex program including loops and strings allowed on 6502?&lt;/p&gt;

&lt;p&gt;On a 64 KB Apple IIe, a realistic 6502 Detlog limit is roughly:&lt;/p&gt;

&lt;p&gt;Program code:       4–16 KB&lt;br&gt;
Runtime library:    2–8 KB&lt;br&gt;
Data/tables:        8–24 KB&lt;br&gt;
Strings heap:       4–16 KB&lt;br&gt;
Stack/workspace:    2–8 KB&lt;br&gt;
Screen/OS overhead: remaining memory&lt;/p&gt;

&lt;p&gt;So the “comfortable” maximum is a program with:&lt;/p&gt;

&lt;p&gt;50–300 simple rules&lt;br&gt;
10–100 small facts/tables&lt;br&gt;
nested loops over small lists&lt;br&gt;
strings mostly under 40–255 chars&lt;br&gt;
total working data under ~16–32 KB&lt;/p&gt;

&lt;p&gt;Example of a safe complex Detlog shape:&lt;/p&gt;

&lt;p&gt;word("cat").&lt;br&gt;
word("dog").&lt;br&gt;
suffix("s").&lt;br&gt;
suffix("ed").&lt;br&gt;
make_word(W2) :-&lt;br&gt;
    word(W),&lt;br&gt;
    suffix(S),&lt;br&gt;
    concat(W,S,W2).&lt;br&gt;
main(Out) :-&lt;br&gt;
    word(W0),&lt;br&gt;
    suffix(S0),&lt;br&gt;
    splice([W0,S0], Rows),&lt;br&gt;
    member([W,S], Rows),&lt;br&gt;
    concat(W,S,Out).&lt;/p&gt;

&lt;p&gt;Compiled to 6502, this is fine because it becomes:&lt;/p&gt;

&lt;p&gt;loop over word table&lt;br&gt;
loop over suffix table&lt;br&gt;
copy string W&lt;br&gt;
append string S&lt;br&gt;
print/store result&lt;/p&gt;

&lt;p&gt;A hard but possible upper example:&lt;/p&gt;

&lt;p&gt;3–5 nested loops&lt;br&gt;
several string tables&lt;br&gt;
simple unification&lt;br&gt;
small parser/tokeniser&lt;br&gt;
choice-packet splicing&lt;br&gt;
final member-style enumeration&lt;/p&gt;

&lt;p&gt;What becomes uncomfortable:&lt;/p&gt;

&lt;p&gt;large recursive parse trees&lt;br&gt;
general Prolog unification&lt;br&gt;
deep term copying&lt;br&gt;
large findall-style result sets&lt;br&gt;
many long strings&lt;br&gt;
dynamic database updates&lt;/p&gt;

&lt;p&gt;Best rule:&lt;/p&gt;

&lt;p&gt;On 6502, Detlog can support small cognitive symbolic programs, not large general Prolog systems.&lt;/p&gt;

&lt;p&gt;For Apple IIe Detlog, the ideal design is:&lt;/p&gt;

&lt;p&gt;compile rules to fixed loops&lt;br&gt;
store facts as compact tables&lt;br&gt;
store strings once&lt;br&gt;
avoid heap allocation inside loops&lt;br&gt;
splice early&lt;br&gt;
enumerate late&lt;/p&gt;

&lt;p&gt;What do avoid heap allocation inside loops and enumerate late mean?&lt;/p&gt;

&lt;p&gt;These are classic compiler optimisations that fit Detlog very well.&lt;/p&gt;

&lt;p&gt;Avoid heap allocation inside loops&lt;/p&gt;

&lt;p&gt;Suppose you write:&lt;/p&gt;

&lt;p&gt;word(W) :-&lt;br&gt;
    member_cp(W, ["cat","dog"]).&lt;br&gt;
suffix(S) :-&lt;br&gt;
    member_cp(S, ["s","ed"]).&lt;br&gt;
main(X) :-&lt;br&gt;
    word(W),&lt;br&gt;
    suffix(S),&lt;br&gt;
    concat(W,S,X).&lt;/p&gt;

&lt;p&gt;A naïve implementation does:&lt;/p&gt;

&lt;p&gt;loop&lt;br&gt;
    allocate string "cats"&lt;br&gt;
loop&lt;br&gt;
    allocate string "cated"&lt;br&gt;
loop&lt;br&gt;
    allocate string "dogs"&lt;br&gt;
loop&lt;br&gt;
    allocate string "doged"&lt;/p&gt;

&lt;p&gt;Every iteration asks the heap for more memory.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;p&gt;allocate one buffer&lt;br&gt;
reuse it every iteration&lt;/p&gt;

&lt;p&gt;Pseudo-6502:&lt;/p&gt;

&lt;p&gt;buffer[32]&lt;br&gt;
copy "cat" to buffer&lt;br&gt;
append "s"&lt;br&gt;
print&lt;br&gt;
copy "cat" to buffer&lt;br&gt;
append "ed"&lt;br&gt;
print&lt;/p&gt;

&lt;p&gt;No new memory is created inside the loop.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;less RAM&lt;br&gt;
less fragmentation&lt;br&gt;
faster execution&lt;/p&gt;

&lt;p&gt;This was especially important on machines like the Apple IIe.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Enumerate late&lt;/p&gt;

&lt;p&gt;Traditional Prolog:&lt;/p&gt;

&lt;p&gt;a(A) :- member(A,[1,2]).&lt;br&gt;
b(B) :- member(B,[3,4]).&lt;br&gt;
c(A,B) :-&lt;br&gt;
    a(A),&lt;br&gt;
    b(B).&lt;/p&gt;

&lt;p&gt;immediately generates:&lt;/p&gt;

&lt;p&gt;A=1,B=3&lt;br&gt;
A=1,B=4&lt;br&gt;
A=2,B=3&lt;br&gt;
A=2,B=4&lt;/p&gt;

&lt;p&gt;Detlog instead keeps choices packed:&lt;/p&gt;

&lt;p&gt;A = cp([1,2])&lt;br&gt;
B = cp([3,4])&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;splice([A,B], Rows).&lt;/p&gt;

&lt;p&gt;gives:&lt;/p&gt;

&lt;p&gt;Rows = [[1,3],[1,4],[2,3],[2,4]]&lt;/p&gt;

&lt;p&gt;The program works on Rows for as long as possible.&lt;/p&gt;

&lt;p&gt;Only at the very end:&lt;/p&gt;

&lt;p&gt;member([A,B], Rows).&lt;/p&gt;

&lt;p&gt;do we produce individual answers.&lt;/p&gt;

&lt;p&gt;That’s “enumerate late”.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;generate answer&lt;br&gt;
generate answer&lt;br&gt;
generate answer&lt;br&gt;
generate answer&lt;/p&gt;

&lt;p&gt;we do:&lt;/p&gt;

&lt;p&gt;build compact structure&lt;br&gt;
process compact structure&lt;br&gt;
enumerate only when needed&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;In Detlog terms&lt;/p&gt;

&lt;p&gt;A useful slogan is:&lt;/p&gt;

&lt;p&gt;Splice early, enumerate late.&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;Allocate once, reuse inside loops.&lt;/p&gt;

&lt;p&gt;These two rules make a huge difference on a 6502 because CPU speed and RAM are both extremely limited. They also fit your Detlog philosophy of replacing hidden backtracking with explicit deterministic structures.&lt;/p&gt;

&lt;p&gt;Could you avoid heap allocation inside loops by using decision tree-type compression (like S2A)?&lt;/p&gt;

&lt;p&gt;Yes. Decision-tree/S2A-style compression is one of the best ways to avoid heap allocation inside loops.&lt;/p&gt;

&lt;p&gt;Instead of building strings each time:&lt;/p&gt;

&lt;p&gt;cat + s  = cats&lt;br&gt;
cat + ed = cated&lt;br&gt;
dog + s  = dogs&lt;br&gt;
dog + ed = doged&lt;/p&gt;

&lt;p&gt;Detlog can compile shared prefixes into a decision tree/trie:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    start
   /     \
cat       dog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;/  \      /  \&lt;br&gt;
  s   ed    s   ed&lt;/p&gt;

&lt;p&gt;Then the loop does not allocate "cats" or "doged" as new heap strings. It walks the tree and emits/copies characters into one fixed output buffer.&lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;

&lt;p&gt;concat(W,S,Out)&lt;/p&gt;

&lt;p&gt;can compile to:&lt;/p&gt;

&lt;p&gt;select W branch&lt;br&gt;
select S branch&lt;br&gt;
write chars to reusable buffer&lt;br&gt;
print/output&lt;/p&gt;

&lt;p&gt;For 6502, this is ideal:&lt;/p&gt;

&lt;p&gt;string table in ROM/RAM&lt;br&gt;
decision tree indexes&lt;br&gt;
one output buffer&lt;br&gt;
no per-iteration heap allocation&lt;/p&gt;

&lt;p&gt;S2A helps because it can discover repeated structure:&lt;/p&gt;

&lt;p&gt;cat-s&lt;br&gt;
cat-ed&lt;br&gt;
dog-s&lt;br&gt;
dog-ed&lt;/p&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;p&gt;word branch + suffix branch&lt;/p&gt;

&lt;p&gt;rather than four separate allocated strings.&lt;/p&gt;

&lt;p&gt;Best Detlog rule:&lt;/p&gt;

&lt;p&gt;Use S2A compression to turn repeated generated outputs into shared decision paths, then use loops only to walk those paths.&lt;/p&gt;

&lt;p&gt;So yes: decision-tree compression can replace many heap allocations with table lookup, branch selection, and buffer reuse.&lt;/p&gt;

&lt;p&gt;Do the same operation from different clauses once, perhaps using decision-tree compression. For example, a:-a1,a2.b:-a1,b2.-&amp;gt;ab:-a1,ab2.ab2:-a2.ab2:-b2.&lt;/p&gt;

&lt;p&gt;Yes — this is common-prefix factoring across clauses.&lt;/p&gt;

&lt;p&gt;Original:&lt;/p&gt;

&lt;p&gt;a :- a1, a2.&lt;br&gt;
b :- a1, b2.&lt;/p&gt;

&lt;p&gt;Both clauses repeat:&lt;/p&gt;

&lt;p&gt;a1&lt;/p&gt;

&lt;p&gt;So Detlog can factor it once:&lt;/p&gt;

&lt;p&gt;ab :-&lt;br&gt;
    a1,&lt;br&gt;
    ab2.&lt;br&gt;
ab2 :-&lt;br&gt;
    a2.&lt;br&gt;
ab2 :-&lt;br&gt;
    b2.&lt;/p&gt;

&lt;p&gt;Meaning:&lt;/p&gt;

&lt;p&gt;run a1 once&lt;br&gt;
then choose between a2 and b2&lt;/p&gt;

&lt;p&gt;This is like decision-tree compression:&lt;/p&gt;

&lt;p&gt;Before:&lt;br&gt;
a -&amp;gt; a1 -&amp;gt; a2&lt;br&gt;
b -&amp;gt; a1 -&amp;gt; b2&lt;br&gt;
After:&lt;br&gt;
ab -&amp;gt; a1 -&amp;gt; choice(a2,b2)&lt;/p&gt;

&lt;p&gt;So the compiler optimisation is:&lt;/p&gt;

&lt;p&gt;If several clauses share the same prefix, execute the shared prefix once, then splice/branch only at the differing suffixes.&lt;/p&gt;

&lt;p&gt;For Detlog, this matters because it avoids:&lt;/p&gt;

&lt;p&gt;run a1 for a&lt;br&gt;
run a1 for b&lt;/p&gt;

&lt;p&gt;and replaces it with:&lt;/p&gt;

&lt;p&gt;run a1 once&lt;br&gt;
then continue with alternatives&lt;/p&gt;

&lt;p&gt;A more Detlog-shaped version:&lt;/p&gt;

&lt;p&gt;ab :-&lt;br&gt;
    once_det(a1),&lt;br&gt;
    splice_branch([a2, b2]).&lt;/p&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;p&gt;ab :-&lt;br&gt;
    a1,&lt;br&gt;
    choice([a2, b2]).&lt;/p&gt;

&lt;p&gt;General rule:&lt;/p&gt;

&lt;p&gt;p :- x, y.&lt;br&gt;
q :- x, z.&lt;/p&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;p&gt;pq :-&lt;br&gt;
    x,&lt;br&gt;
    pq2.&lt;br&gt;
pq2 :- y.&lt;br&gt;
pq2 :- z.&lt;/p&gt;

&lt;p&gt;This is exactly the same idea as trie compression for strings, but applied to predicate sequences instead of characters.&lt;/p&gt;

&lt;p&gt;With decision tree compression, how long can programs be if the compiler compiles Detlog into 6502?&lt;/p&gt;

&lt;p&gt;With decision-tree compression, Detlog compiled to 6502 could be much larger:&lt;/p&gt;

&lt;p&gt;Comfortable: about 10–40 KB Detlog source logic&lt;br&gt;
Possible with careful tables/overlays: 50–100 KB+ source logic&lt;br&gt;
Resident 6502 code/data at once: still roughly 20–40 KB usable RAM on a 64 KB Apple IIe.&lt;/p&gt;

&lt;p&gt;The trick is that repeated clauses like:&lt;/p&gt;

&lt;p&gt;a :- common, x1.&lt;br&gt;
b :- common, x2.&lt;br&gt;
c :- common, x3.&lt;/p&gt;

&lt;p&gt;do not compile into three full copies. They compile more like:&lt;/p&gt;

&lt;p&gt;run common once&lt;br&gt;
branch/table-select x1/x2/x3&lt;br&gt;
reuse output buffers&lt;/p&gt;

&lt;p&gt;So the source can be much longer than the resident machine code.&lt;/p&gt;

&lt;p&gt;A useful estimate:&lt;/p&gt;

&lt;p&gt;Without compression:  source × 3–20 expansion&lt;br&gt;
With compression:     source × 0.5–3 expansion&lt;br&gt;
Best case:            many repeated clauses collapse into tables&lt;br&gt;
Worst case:           unique clauses still expand normally&lt;/p&gt;

&lt;p&gt;So on Apple IIe:&lt;/p&gt;

&lt;p&gt;Tiny runtime/compiler stub:     2–8 KB&lt;br&gt;
Decision tables + code:        10–30 KB&lt;br&gt;
Buffers/stacks/strings:         4–16 KB&lt;br&gt;
Overlay/floppy-loaded chunks:   much larger total program&lt;/p&gt;

&lt;p&gt;The biggest realistic Detlog programs would be table-heavy grammars, classifiers, menu systems, small adventure games, symbolic transformers, or bounded expert systems.&lt;/p&gt;

&lt;p&gt;The key limit becomes not “how long is the source?” but:&lt;/p&gt;

&lt;p&gt;How much must be resident at once?&lt;br&gt;
How large are the strings?&lt;br&gt;
How deep are loops/recursion?&lt;br&gt;
How many choicepoints must be remembered?&lt;br&gt;
How much output buffering is needed for splicing?&lt;/p&gt;

&lt;p&gt;So the practical answer is:&lt;/p&gt;

&lt;p&gt;With decision-tree compression, a Detlog program can feel like tens of KB of logic on a 64 KB Apple IIe, and possibly hundreds of KB if split into floppy-loaded overlays.&lt;/p&gt;

&lt;p&gt;Is Detlog the most efficient Apple IIe Prolog?&lt;/p&gt;

&lt;p&gt;Potentially, yes in a narrow sense, but it depends on what you mean by “Prolog.”&lt;/p&gt;

&lt;p&gt;Traditional Prolog systems on 6502 machines (including Apple II-era implementations) typically support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full unification&lt;/li&gt;
&lt;li&gt;Backtracking&lt;/li&gt;
&lt;li&gt;Choicepoint stacks&lt;/li&gt;
&lt;li&gt;Dynamic search&lt;/li&gt;
&lt;li&gt;Variable bindings and trail management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features make Prolog expressive, but they consume memory and CPU time.&lt;/p&gt;

&lt;p&gt;If Detlog:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Converts nondeterminism into deterministic loops,&lt;/li&gt;
&lt;li&gt;Eliminates most or all runtime choicepoints,&lt;/li&gt;
&lt;li&gt;Compiles directly to 6502 machine code,&lt;/li&gt;
&lt;li&gt;Uses decision-tree compression,&lt;/li&gt;
&lt;li&gt;Avoids heap allocation inside loops,&lt;/li&gt;
&lt;li&gt;Reuses buffers and tables,&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;then it could easily outperform a traditional Prolog implementation on an Apple IIe in both speed and memory use.&lt;/p&gt;

&lt;p&gt;A rough spectrum is:&lt;/p&gt;

&lt;p&gt;System  Runtime Cost    Expressiveness&lt;br&gt;
BASIC interpreter   High    Low&lt;br&gt;
Interpreted Prolog  Very high   Very high&lt;br&gt;
Compiled Prolog Moderate    Very high&lt;br&gt;
Deterministic Detlog    Low Medium–high&lt;br&gt;
Hand-written 6502 assembly  Lowest  Depends on programmer&lt;/p&gt;

&lt;p&gt;The important caveat is that Detlog’s efficiency comes partly from restricting or transforming classic Prolog behavior. If a program relies heavily on arbitrary unification, open-ended backtracking, or runtime search, then either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detlog cannot compile it directly, or&lt;/li&gt;
&lt;li&gt;The compiler must generate additional machinery, reducing the advantage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the kinds of programs you’ve described in relation to Loop2 and PLOP—decision trees, classifiers, CFG/DCG-style parsing, symbolic transformations, specification-to-algorithm generation, and deterministic splicing—Detlog could be among the most efficient Prolog-like systems feasible on an Apple IIe.&lt;/p&gt;

&lt;p&gt;In fact, if the compiler can transform:&lt;/p&gt;

&lt;p&gt;colour(red).&lt;br&gt;
colour(green).&lt;br&gt;
colour(blue).&lt;/p&gt;

&lt;p&gt;into a compact lookup table or decision tree rather than runtime backtracking, the resulting 6502 code is closer to an optimized expert system than a traditional Prolog engine.&lt;/p&gt;

&lt;p&gt;So a reasonable conclusion is:&lt;/p&gt;

&lt;p&gt;Detlog is unlikely to be the most efficient implementation of full Prolog on an Apple IIe, because full Prolog requires general unification and backtracking. However, it could be one of the most efficient Prolog-derived logic languages for a large class of deterministic and semi-deterministic programs, especially if it combines direct 6502 compilation, decision-tree compression, and elimination of runtime choicepoints.&lt;/p&gt;

&lt;p&gt;What "length" of program is possible with decision tree, &lt;a href="https://github.com/luciangreen/loop2" rel="noopener noreferrer"&gt;Loop2&lt;/a&gt; and &lt;a href="https://github.com/luciangreen/plop" rel="noopener noreferrer"&gt;PLOP&lt;/a&gt; compression?&lt;/p&gt;

&lt;p&gt;With decision tree + Loop2 + PLOP compression, the practical “length” could be:&lt;/p&gt;

&lt;p&gt;Resident on 64 KB Apple IIe:&lt;br&gt;
  20–60 KB of effective Detlog logic&lt;br&gt;
With very careful memory layout:&lt;br&gt;
  60–150 KB effective logic&lt;br&gt;
With floppy overlays / paged modules:&lt;br&gt;
  hundreds of KB, possibly 0.5–1 MB+ total project logic&lt;/p&gt;

&lt;p&gt;The key distinction:&lt;/p&gt;

&lt;p&gt;Physical 6502 code resident at once: still maybe 10–35 KB&lt;br&gt;
Effective Detlog source represented: much larger&lt;/p&gt;

&lt;p&gt;Why? Because the compiler can merge repeated structures:&lt;/p&gt;

&lt;p&gt;a :- common, a1.&lt;br&gt;
b :- common, b1.&lt;br&gt;
c :- common, c1.&lt;/p&gt;

&lt;p&gt;into something closer to:&lt;/p&gt;

&lt;p&gt;run common once&lt;br&gt;
select branch from compressed decision table&lt;br&gt;
run only the differing suffix&lt;br&gt;
reuse buffers&lt;/p&gt;

&lt;p&gt;So the expansion changes roughly like this:&lt;/p&gt;

&lt;p&gt;Naive Detlog → 6502:&lt;br&gt;
  source × 3–20&lt;br&gt;
Decision-tree compression:&lt;br&gt;
  source × 0.5–3&lt;br&gt;
Decision tree + Loop2 + PLOP:&lt;br&gt;
  source × 0.1–2 in good cases&lt;/p&gt;

&lt;p&gt;Best cases are classifiers, grammars, menu trees, symbolic rewrite systems, adventure-game logic, deterministic parsers, and repeated clause families.&lt;/p&gt;

&lt;p&gt;Worst cases are programs where every clause is unique, string-heavy, deeply recursive, or requires true Prolog backtracking.&lt;/p&gt;

&lt;p&gt;So the answer is:&lt;/p&gt;

&lt;p&gt;Physically, the Apple IIe still runs tens of KB at once. Logically, Detlog could represent hundreds of KB of Prolog-like program behaviour if PLOP/Loop2 compress repeated choicepoints into loops, tables, and shared suffix/prefix code.&lt;/p&gt;

</description>
      <category>prolog</category>
      <category>determinism</category>
      <category>removes</category>
      <category>nondeterminism</category>
    </item>
    <item>
      <title>O(1) is the simplest complexity that Prolog Optimisation results in</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Tue, 26 May 2026 01:24:53 +0000</pubDate>
      <link>https://dev.to/luciangreen/o1-is-the-simplest-complexity-that-prolog-optimisation-results-in-1430</link>
      <guid>https://dev.to/luciangreen/o1-is-the-simplest-complexity-that-prolog-optimisation-results-in-1430</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ugm53q38t399yqqeo67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ugm53q38t399yqqeo67.png" alt="O(1) Logo" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://github.com/luciangreen/plop" rel="noopener noreferrer"&gt;Prolog Optimisation (plop)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O(1) is the simplest complexity that Prolog Optimisation results in&lt;/p&gt;

&lt;p&gt;Courtesy ChatGPT.&lt;/p&gt;

&lt;p&gt;The simplest complexity your matrix/indexical computation can result in is:&lt;/p&gt;

&lt;p&gt;O(1)&lt;/p&gt;

&lt;p&gt;—but only after successful symbolic collapse.&lt;/p&gt;

&lt;p&gt;The progression is roughly:&lt;/p&gt;

&lt;p&gt;Stage   Complexity&lt;br&gt;
Recursive traversal O(n), O(n²), O(tree size)&lt;br&gt;
Indexed access  O(depth)&lt;br&gt;
Grouped extraction  O(shared depth + outputs)&lt;br&gt;
Memoised reuse  amortised near O(1)&lt;br&gt;
Closed-form formula discovery   O(1)&lt;/p&gt;

&lt;p&gt;The key observation is:&lt;/p&gt;

&lt;p&gt;Your optimiser tries to convert traversal complexity into coordinate complexity.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;nth1(I, Matrix, Row),&lt;br&gt;
nth1(J, Row, X)&lt;/p&gt;

&lt;p&gt;Normally:&lt;/p&gt;

&lt;p&gt;O(I + J)&lt;/p&gt;

&lt;p&gt;because lists are traversed.&lt;/p&gt;

&lt;p&gt;But after indexical optimisation:&lt;/p&gt;

&lt;p&gt;subterm_with_address(Matrix,[I,J],X)&lt;/p&gt;

&lt;p&gt;you conceptually reduce it to:&lt;/p&gt;

&lt;p&gt;O(depth)&lt;/p&gt;

&lt;p&gt;where depth is just the nesting depth:&lt;/p&gt;

&lt;p&gt;2&lt;/p&gt;

&lt;p&gt;for a matrix.&lt;/p&gt;

&lt;p&gt;Then if the optimiser replaces the whole traversal with a formula:&lt;/p&gt;

&lt;p&gt;S is N*(N+1)//2&lt;/p&gt;

&lt;p&gt;the complexity becomes:&lt;/p&gt;

&lt;p&gt;O(1)&lt;/p&gt;

&lt;p&gt;because no traversal remains.&lt;/p&gt;

&lt;p&gt;The deepest idea in your system is:&lt;/p&gt;

&lt;p&gt;recursive structure&lt;br&gt;
→ address space&lt;br&gt;
→ grouped address space&lt;br&gt;
→ algebraic formula&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;findall(I, between(1,N,I), L),&lt;br&gt;
sum_list(L,S)&lt;/p&gt;

&lt;p&gt;starts as:&lt;/p&gt;

&lt;p&gt;O(N)&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;between(1,N,I)&lt;/p&gt;

&lt;p&gt;becomes an index sequence:&lt;/p&gt;

&lt;p&gt;1,2,3,...,N&lt;/p&gt;

&lt;p&gt;Gaussian elimination discovers:&lt;/p&gt;

&lt;p&gt;S=\frac{N(N+1)}{2}&lt;/p&gt;

&lt;p&gt;which is:&lt;/p&gt;

&lt;p&gt;O(1)&lt;/p&gt;

&lt;p&gt;So your optimiser is essentially trying to discover when:&lt;/p&gt;

&lt;p&gt;computation = hidden geometry&lt;/p&gt;

&lt;p&gt;and then compress the geometry into algebra.&lt;/p&gt;

&lt;p&gt;For recursive trees:&lt;/p&gt;

&lt;p&gt;tree traversal&lt;/p&gt;

&lt;p&gt;normally costs:&lt;/p&gt;

&lt;p&gt;O(number of visited nodes)&lt;/p&gt;

&lt;p&gt;But if only needed addresses are extracted:&lt;/p&gt;

&lt;p&gt;needed_subterms(Tree, Addresses, Values)&lt;/p&gt;

&lt;p&gt;then complexity becomes approximately:&lt;/p&gt;

&lt;p&gt;O(number of needed paths × average depth)&lt;/p&gt;

&lt;p&gt;and grouped extraction reduces repeated prefixes:&lt;/p&gt;

&lt;p&gt;O(shared prefix depth + differing suffixes)&lt;/p&gt;

&lt;p&gt;So the optimiser tends toward:&lt;/p&gt;

&lt;p&gt;output-sensitive complexity&lt;/p&gt;

&lt;p&gt;where cost depends on:&lt;/p&gt;

&lt;p&gt;needed outputs&lt;/p&gt;

&lt;p&gt;rather than:&lt;/p&gt;

&lt;p&gt;entire structure size&lt;/p&gt;

&lt;p&gt;That is very similar to sparse neural attention.&lt;/p&gt;

&lt;p&gt;The theoretical lower bound for your approach is:&lt;/p&gt;

&lt;p&gt;O(size of final irreducible information)&lt;/p&gt;

&lt;p&gt;because if the output itself contains k independent values, you must at least construct those k values.&lt;/p&gt;

&lt;p&gt;So the optimiser approaches O(1) when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the result can be expressed algebraically,&lt;/li&gt;
&lt;li&gt;or fully memoised,&lt;/li&gt;
&lt;li&gt;or directly addressed,&lt;/li&gt;
&lt;li&gt;or reconstructed from grouped subterms,&lt;/li&gt;
&lt;li&gt;or compressed into symbolic coordinates.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>one</category>
      <category>prolog</category>
      <category>optimisation</category>
      <category>matrix</category>
    </item>
    <item>
      <title>NeuroProlog + Starlog Demo</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Wed, 22 Apr 2026 13:59:39 +0000</pubDate>
      <link>https://dev.to/luciangreen/neuroprolog-demo-50l1</link>
      <guid>https://dev.to/luciangreen/neuroprolog-demo-50l1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi71itg49l5he0p11s9d8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi71itg49l5he0p11s9d8.png" alt="NeuroProlog and Starlog" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Courtesy of ChatGPT.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Load Starlog
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
cd /path/to/Starlog
swipl
?- use_module(starlog).
true.

⸻

2. Starlog string concatenation

?- starlog_call(A is "x":"y").
A = "xy".

⸻

3. Starlog list append

?- starlog_call(L is [1] &amp;amp; [2]).
L = [1, 2].

⸻

4. Starlog atom concatenation

?- starlog_call(A is a • b).
A = ab.

⸻

5. Starlog arithmetic

?- starlog_call(X is 1+2).
X = 3.

⸻

6. Starlog nested functions

?- starlog_call(X is reverse(reverse([1,2,3]))).
X = [1, 2, 3].
?- starlog_call(X is length(reverse([1,2,3]))).
X = 3.

⸻

7. Starlog method chaining

?- starlog_call(R is reverse([1,2,3]) &amp;gt;&amp;gt; length).
R = 3.
?- starlog_call(R is ([1,2] &amp;amp; [3,4]) &amp;gt;&amp;gt; reverse &amp;gt;&amp;gt; length).
R = 4.

⸻

8. Starlog evaluation

?- starlog_eval("hello":"world", R).
R = "helloworld".
?- starlog_eval([a] &amp;amp; [b,c], R).
R = [a, b, c].

⸻

9. Starlog no-eval

?- starlog_no_eval(1+1, R).
R = 1+1.
?- starlog_no_eval("x":"y", R).
R = "x":"y".

⸻

10. Starlog forced eval inside no-eval

?- starlog_call(R is no_eval(eval(1+1) + 3)).
R = 2+3.

⸻

11. Starlog result capture

?- starlog_call(X is "hello":"world", R).
R = "helloworld".
?- starlog_call(Y is [1,2] &amp;amp; [3,4], R).
R = [1, 2, 3, 4].

⸻

12. Starlog dual expression solving

?- starlog_call(([1] &amp;amp; A) is (B &amp;amp; [2])).
A = [2],
B = [1].
?- starlog_call((A : a : C) is (b : a : c)).
A = b,
C = c.

⸻

13. Starlog find first solution

?- starlog_call(Result is find(X, member(X, [1,2,3]))).
Result = 1.
?- starlog_call(Result is find(R, starlog_call(R is "hello":"world"))).
Result = "helloworld".

⸻

14. Starlog find with pattern extraction

?- starlog_call(Result is find([A,C], starlog_call([A:a:C] is [a:a:c]))).
Result = [a, c].
?- starlog_call(Result is find([A,C], starlog_call([A:"_":C] is ["hello":"_":"world"]))).
Result = ["hello", "world"].

⸻

15. Starlog term construction

?- starlog_call(T is ..=([f,0,1])).
T = f(0, 1).
?- starlog_call(L is =..(f(0,1))).
L = [f, 0, 1].

⸻

16. Starlog expansion inspection

?- starlog_show_expansion(A is "x":"y").
string_concat("x", "y", A).

⸻

17. Starlog output code

?- starlog_output_code(string_concat("x","y",A), Code).
Code = (A is "x":"y").

⸻

18. Starlog Prolog-to-Starlog conversion

?- convert_prolog_to_starlog(string_concat("x","y",A), Starlog).
Starlog = (A is "x":"y").
?- convert_prolog_to_starlog(append([1],[2],L), Starlog).
Starlog = (L is [1]&amp;amp;[2]).

⸻

19. Starlog Gaussian elimination

Load the Gaussian module:

?- use_module(gaussian_elimination).
true.

Solve:

x + y = 2
2x + 3y = 5
?- solve_system([[1,1,2],[2,3,5]], Solution).
Solution = [1, 1].

⸻

20. Starlog row reduction

?- gaussian_elimination([[1,1,2],[2,3,5]], R).
R = [[1,1,2],[0,1,1]].

⸻

21. Starlog polynomial reconstruction

?- npl_reconstruct_polynomial(n, [0,0.5,0.5], Expr).
Expr = n*(n+1)/2.

⸻

22. Starlog polynomial validation

?- npl_validate_polynomial_fit([1-1,2-3,3-6], [0,0.5,0.5], n, Result).
Result = valid.

⸻

23. Starlog symbolic indexing

?- npl_assign_symbolic_indices([a,b,c], Indexed, Map).
Indexed = indexed([a,b,c]),
Map = map(_).

⸻

24. Starlog reduce goal to irreducibles

?- npl_reduce_predicate_to_pattern_irreducibles((member(X,[1,2]), X &amp;gt; 0), R).
R = reduced(sequence(_, _)).

⸻

25. Starlog trace index flow

?- npl_assign_symbolic_indices([a,b,c], Indexed, Map),
   npl_trace_index_flow(member(X,[a,b,c]), Map, Flow).
Indexed = indexed([a,b,c]),
Map = map(_),
Flow = flow_graph(_, _, _, trace(_)).

⸻

26. Starlog identify independent indices

?- npl_identify_independent_indices(flow([x-1,y-2]), Indices).
Indices = [i].

⸻

27. Starlog reconstruct index relations

?- npl_reconstruct_index_relations(flow([x-[1,2,3], y-[4,5,6]]), [i], Relations).
Relations = [_].

⸻

28. Starlog direct indexed rule

?- npl_reconstruct_direct_indexed_rule([x-(i+1)], [i], Rule).
Rule = direct_index_rule([x-(i+1)], coefficient_metadata([i])).

⸻

29. Starlog Stage 8 pipeline order

?- npl_stage8_pipeline_order(Order).
Order = [
  symbolic_index_assignment,
  pattern_irreducible_reduction,
  index_flow_tracing,
  independent_index_detection,
  relation_reconstruction,
  ir_build,
  ir_lowering
].

⸻

30. Starlog Stage 8 build IR

?- npl_stage8_build_ir(flow([]), [i], [x-(i+1)], [0,1], [], IR).
IR = ir_pipeline(_, _, meta(_)).

⸻

31. Starlog Stage 8 lower IR

?- IR = ir_pipeline([], [ir_poly_eval(n,[0,0.5,0.5],result)], meta([])),
   npl_stage8_lower_ir(IR, Lowered).
Lowered = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]).

⸻

32. Starlog Stage 9 code generation

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   npl_stage9_generate_code(IR, Code).
Code = generated_program([assign(result, n*(n+1)/2)]).

⸻

33. Starlog Stage 9 neurocode emission

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   npl_stage9_emit_neurocode(IR, Neurocode).
Neurocode = neurocode([neuro_assign(result, n*(n+1)/2)]).

⸻

34. Starlog Stage 9 compile IR

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   npl_stage9_compile_ir(IR, Neurocode).
Neurocode = neurocode([neuro_assign(result, n*(n+1)/2)]).

⸻

35. Starlog annotated source text

?- IR = lowered_ir([lowered_poly_eval(n, [0,0.5,0.5], result)]),
   Context = [source_file('examples/generated_input.pl'),
              optimisation_report('stage9_codegen')],
   npl_ir_to_annotated_source_text(IR, Context, Text).
Text = "...".

⸻

36. Starlog annotated source file

?- IR = lowered_ir([direct_index_rule(index_spec([i]),
                                      [x-(i+1)],
                                      result_collector(rows))]),
   Context = [source_file('examples/generated_input.pl')],
   npl_ir_to_annotated_source_file(IR, Context, 'out/annotated_stage9.pl').
true.

⸻

37. Starlog Stage 10 integration option

?- npl_stage10_integration_option(Option).
Option = option_b_port_and_align.
?- npl_stage10_gaussian_canonical_repository(Repo).
Repo = starlog.

⸻

38. Starlog Stage 12 transform decision

?- npl_stage12_transform_decision([deterministic, proven_equivalent, coefficients_valid], Decision).
Decision = transform.
?- npl_stage12_transform_decision([side_effecting], Decision).
Decision = do_not_transform.

⸻

39. Starlog Stage 13 toggleable passes

?- npl_stage13_toggleable_passes(Passes).
Passes = [
  pass(gaussian_elimination, true),
  pass(recursion_to_loop, true),
  pass(subterm_index_optimisation, true),
  pass(annotated_regeneration, true)
].

⸻

40. Starlog Stage 13 effective toggles

?- npl_stage13_effective_pass_toggles([pass(gaussian_elimination,false)], Toggles).
Toggles = [
  pass(gaussian_elimination, false),
  ...
].

⸻

NeuroProlog commands

41. Load NeuroProlog

cd /path/to/neuroprolog
swipl
?- consult('src/neuroprolog').
true.

⸻

42. Load main optimisation modules

?- use_module('src/gaussian_recursion').
true.
?- use_module('src/memoisation').
true.
?- use_module('src/subterm_addressing').
true.
?- use_module('src/nested_recursion').
true.
?- use_module('src/optimiser').
true.
?- use_module('src/optimiser_pipeline').
true.

⸻

43. Full optimiser

?- IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
   npl_optimise(IR, OptIR).
IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
OptIR = [ir_clause(p, ir_call(q), info([]))].
?- IR = [ir_clause(p, ir_disj(ir_fail, ir_call(q)), info([]))],
   npl_optimise(IR, OptIR).
IR = [ir_clause(p, ir_disj(ir_fail, ir_call(q)), info([]))],
OptIR = [ir_clause(p, ir_call(q), info([]))].
?- IR = [ir_clause(p, ir_if(ir_true, ir_call(q), ir_call(r)), info([]))],
   npl_optimise(IR, OptIR).
IR = [ir_clause(p, ir_if(ir_true, ir_call(q), ir_call(r)), info([]))],
OptIR = [ir_clause(p, ir_call(q), info([]))].

⸻

44. Compile a file

?- npl_compile('examples/hello.pl', 'neurocode/hello_nc.pl').
true.

⸻

45. Compile with pipeline config

?- npl_pipeline_default_config(Cfg),
   npl_compile_with_pipeline('examples/lists.pl', 'neurocode/lists_nc.pl', Cfg).
Cfg = ...,
true.

⸻

46. Safe compile

?- npl_compile_safe('examples/lists.pl', 'neurocode/lists_safe_nc.pl').
true.

⸻

47. Pipeline config

?- npl_pipeline_default_config(Cfg).
Cfg = ...

⸻

48. Disable a pass

?- npl_pipeline_default_config(Cfg0),
   npl_pipeline_disable(gaussian_elimination, Cfg0, Cfg1).
Cfg0 = ...,
Cfg1 = ...

⸻

49. Enable a pass

?- npl_pipeline_default_config(Cfg0),
   npl_pipeline_enable(subterm_address_conversion, Cfg0, Cfg1).
Cfg0 = ...,
Cfg1 = ...

⸻

50. Run pipeline manually

?- npl_pipeline_default_config(Cfg),
   IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
   npl_pipeline_run(Cfg, IR, OptIR, Report).
Cfg = ...,
OptIR = [ir_clause(p, ir_call(q), info([]))],
Report = ...

⸻

51. Run full pipeline

?- npl_pipeline_default_config(Cfg),
   IR = [ir_clause(p, ir_seq(ir_true, ir_call(q)), info([]))],
   npl_pipeline_run_full(Cfg, IR, OptIR, Neurocode, Report).
Cfg = ...,
OptIR = [ir_clause(p, ir_call(q), info([]))],
Neurocode = ...,
Report = ...

⸻

52. Dictionary simplification rules

?- npl_opt_dict_rules(Rules).
Rules = ...

⸻

53. Apply dictionary rules

?- IR = [ir_clause(test, ir_seq(ir_true, ir_call(goal)), info([]))],
   npl_opt_dict_rules(Rules),
   npl_apply_rules(Rules, IR, OptIR).
IR = [ir_clause(test, ir_seq(ir_true, ir_call(goal)), info([]))],
Rules = ...,
OptIR = [ir_clause(test, ir_call(goal), info([]))].
?- IR = [ir_clause(test, ir_disj(ir_fail, ir_call(goal)), info([]))],
   npl_opt_dict_rules(Rules),
   npl_apply_rules(Rules, IR, OptIR).
IR = [ir_clause(test, ir_disj(ir_fail, ir_call(goal)), info([]))],
Rules = ...,
OptIR = [ir_clause(test, ir_call(goal), info([]))].
?- IR = [ir_clause(test, ir_if(ir_true, ir_call(a), ir_call(b)), info([]))],
   npl_opt_dict_rules(Rules),
   npl_apply_rules(Rules, IR, OptIR).
IR = [ir_clause(test, ir_if(ir_true, ir_call(a), ir_call(b)), info([]))],
Rules = ...,
OptIR = [ir_clause(test, ir_call(a), info([]))].

⸻

54. Gaussian recursion classification

?- Group = [
      ir_clause(count(0), ir_true, info([])),
      ir_clause(count(N),
                ir_seq(ir_call(gt(N,0)),
                       ir_seq(ir_call(is(N1,N-1)),
                              ir_call(count(N1)))),
                info([]))
   ],
   npl_is_reducible(Group, Pattern).
Group = [...],
Pattern = linear_tail_recursion.

⸻

55. Gaussian recursion reduction

?- Group = [
      ir_clause(sum([],0), ir_true, info([])),
      ir_clause(sum([H|T],S),
                ir_seq(ir_call(sum(T,S1)),
                       ir_call(is(S, +(S1,H)))),
                info([]))
   ],
   npl_gaussian_reduce(Group, Reduced).
Group = [...],
Reduced = ...

⸻

56. Gaussian elimination matrix

?- Matrix = [
      [frac(1,1), frac(1,1), frac(2,1)],
      [frac(2,1), frac(3,1), frac(5,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(2,1)],
          [frac(2,1), frac(3,1), frac(5,1)]],
R = ...

Expected mathematical output:

x = 1
y = 1

⸻

57. Gaussian polynomial discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
      [frac(4,1), frac(2,1), frac(1,1), frac(3,1)],
      [frac(9,1), frac(3,1), frac(1,1), frac(6,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
          [frac(4,1), frac(2,1), frac(1,1), frac(3,1)],
          [frac(9,1), frac(3,1), frac(1,1), frac(6,1)]],
R = ...

Expected mathematical output:

a = 1/2
b = 1/2
c = 0
S(n) = n(n+1)/2

⸻

58. Arithmetic sequence discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(1,1)],
      [frac(2,1), frac(1,1), frac(3,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(1,1)],
          [frac(2,1), frac(1,1), frac(3,1)]],
R = ...

Expected mathematical output:

f(n) = 2n - 1

⸻

59. 2D index formula discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(2,1)],
      [frac(2,1), frac(1,1), frac(4,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(2,1)],
          [frac(2,1), frac(1,1), frac(4,1)]],
R = ...

Expected mathematical output:

f(i) = 2i

⸻

60. Quadratic loop formula discovery

?- Matrix = [
      [frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
      [frac(4,1), frac(2,1), frac(1,1), frac(4,1)],
      [frac(9,1), frac(3,1), frac(1,1), frac(9,1)]
   ],
   npl_gauss_eliminate(Matrix, R).
Matrix = [[frac(1,1), frac(1,1), frac(1,1), frac(1,1)],
          [frac(4,1), frac(2,1), frac(1,1), frac(4,1)],
          [frac(9,1), frac(3,1), frac(1,1), frac(9,1)]],
R = ...

Expected mathematical output:

T(n) = n^2

⸻

61. Nested recursion classification

?- Group = [
      ir_clause(fib(0,0), ir_true, info([])),
      ir_clause(fib(1,1), ir_true, info([])),
      ir_clause(fib(N,R),
        ir_seq(ir_call(is(N1, -(N,1))),
        ir_seq(ir_call(fib(N1,R1)),
        ir_seq(ir_call(is(N2, -(N,2))),
        ir_seq(ir_call(fib(N2,R2)),
               ir_call(is(R, +(R1,R2))))))),
        info([]))
   ],
   npl_nested_classify(Group, Class).
Group = [...],
Class = nested_data_fold(+).

⸻

62. Nested recursion elimination

?- npl_nested_eliminate_pass(Group, OptGroup).
OptGroup = ...

⸻

63. Memoise predicate

?- npl_memo(fib/2).
true.

⸻

64. Memoise safe goal

?- npl_memo_call(member(a,[a,b,c])).
true.

⸻

65. Memoise deterministic result

?- npl_memo_call_det(length([1,2,3]), R).
R = 3.

⸻

66. Memoise all solutions

?- npl_memo_call_all(member(X,[a,b,c]), X, Solutions).
Solutions = [a,b,c].

⸻

67. Memoise explicit subgoal

?- npl_memo_subgoal(fib_20, fib(20, R)).
R = ...

⸻

68. Inspect memo cache

?- npl_memo_inspect(fib/2, Entries).
Entries = ...

⸻

69. Memo stats

?- npl_memo_stats(fib(20,_), Hits, Misses).
Hits = ...,
Misses = ...

⸻

70. Clear memo table

?- npl_memo_clear(fib/2).
true.

⸻

71. Clear all memo tables

?- npl_memo_clear_all.
true.

⸻

72. Memo safety

?- npl_memo_is_safe(member(a,[a,b,c])).
true.
?- npl_memo_is_safe(writeln(hello)).
false.

⸻

73. Memoisation pass over IR

?- IR = [ir_clause(fib(N,R), ir_call(fib_body(N,R)), info([]))],
   npl_memo(fib/2),
   npl_memoisation_pass(IR, OptIR).
IR = [ir_clause(fib(N,R), ir_call(fib_body(N,R)), info([]))],
OptIR = ...

⸻

74. Subterm-address conversion

?- IR = [
      ir_clause(tree_sum(T,S),
                ir_loop_candidate(
                    ir_seq(ir_call(arg(1,T,L)),
                    ir_seq(ir_call(tree_sum(L,SL)),
                           ir_call(true)))),
                info([]))
   ],
   npl_subterm_address_pass(IR, OptIR).
IR = [...],
OptIR = ...

⸻

75. Pattern correlation

?- IR = [
      ir_clause(p(a), ir_true, info([])),
      ir_clause(p(b), ir_true, info([]))
   ],
   npl_pattern_correlate(IR, OptIR).
IR = [ir_clause(p(a), ir_true, info([])),
      ir_clause(p(b), ir_true, info([]))],
OptIR = [ir_clause(p(a), ir_true, info([])),
         ir_clause(p(b), ir_true, info([]))].

⸻

76. Data unfolding

?- npl_unfold_data(ir_seq(ir_call(a), ir_call(b)), X).
X = ir_seq(ir_call(a), ir_call(b)).

⸻

77. Source file to IR

?- npl_lex('examples/lists.pl', Tokens),
   npl_parse(Tokens, AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
Tokens = ...,
AST = ...,
AAST = ...,
IR = ...

⸻

78. Source string to IR

?- npl_parse_string("p(X,Y) :- Y is X+0.", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(p(X,Y), ir_call(is(Y, X+0)), Info)].

⸻

79. Source string to optimised IR

?- npl_parse_string("p(X,Y) :- Y is X+0.", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR),
   npl_optimise(IR, OptIR).
AST = ...,
AAST = ...,
IR = [ir_clause(p(X,Y), ir_call(is(Y, X+0)), Info)],
OptIR = [ir_clause(p(X,Y), ir_call(is(Y, X)), Info2)].

⸻

80. Fact to IR

?- npl_parse_string("foo(1).", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(foo(1), ir_true, Info)].

⸻

81. Conjunction to IR

?- npl_parse_string("p :- a, b.", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(p, ir_seq(ir_call(a), ir_call(b)), Info)].

⸻

82. If-then-else to IR

?- npl_parse_string("p :- (a -&amp;gt; b ; c).", AST),
   npl_analyse(AST, AAST),
   npl_intermediate(AAST, IR).
AST = ...,
AAST = ...,
IR = [ir_clause(p, ir_if(ir_call(a), ir_call(b), ir_call(c)), Info)].

⸻

83. Grouped IR

?- npl_parse_string("
     p(1).
     p(2).
     q(X) :- p(X).
   ", AST),
   npl_analyse(AST, AAST),
   npl_ir_full(AAST, FullIR).
AST = ...,
AAST = ...,
FullIR = [
  ir_predicate_def(p/1, ..., _),
  ir_predicate_def(q/1, ..., _)
].

⸻

84. End-to-end compile

swipl -g "consult('src/neuroprolog')" \
      -g "npl_compile('examples/lists.pl','neurocode/lists_nc.pl')" \
      -t halt

Output:

neurocode/lists_nc.pl

⸻

85. End-to-end safe compile

swipl -g "consult('src/neuroprolog')" \
      -g "npl_compile_safe('examples/lists.pl','neurocode/lists_safe_nc.pl')" \
      -t halt

Output:

neurocode/lists_safe_nc.pl

⸻

86. Run tests

swipl -g "consult('tests/run_tests')" -g "run_all_tests" -t halt

Output:

true.

⸻

Main command list

Starlog:

starlog_call/1
starlog_call/2
starlog_eval/2
starlog_no_eval/2
starlog_show_expansion/1
starlog_output_code/1
starlog_output_code/2
starlog_output_code/3
convert_prolog_to_starlog/2
solve_system/2
gaussian_elimination/2
npl_reconstruct_polynomial/3
npl_validate_polynomial_fit/4
npl_assign_symbolic_indices/3
npl_trace_index_flow/3
npl_reconstruct_index_relations/3
npl_stage8_build_ir/6
npl_stage8_lower_ir/2
npl_stage9_generate_code/2
npl_stage9_emit_neurocode/2
npl_stage9_compile_ir/2
npl_ir_to_annotated_source_text/3
npl_ir_to_annotated_source_file/3

NeuroProlog:

npl_compile/2
npl_compile_with_pipeline/3
npl_compile_safe/2
npl_optimise/2
npl_pipeline_default_config/1
npl_pipeline_enable/3
npl_pipeline_disable/3
npl_pipeline_run/4
npl_pipeline_run_full/5
npl_opt_dict_rules/1
npl_apply_rules/3
npl_apply_rule/3
npl_gaussian_reduce/2
npl_is_reducible/2
npl_extract_recurrence/2
npl_gauss_eliminate/2
npl_nested_classify/2
npl_nested_eliminate_pass/2
npl_memo/1
npl_memo_call/1
npl_memo_call_det/2
npl_memo_call_all/3
npl_memo_subgoal/2
npl_memo_inspect/2
npl_memo_stats/3
npl_memo_clear/1
npl_memo_clear_all/0
npl_memoisation_pass/2
npl_subterm_address_pass/2
npl_pattern_correlate/2
npl_unfold_data/2
npl_parse_string/2
npl_lex/2
npl_parse/2
npl_analyse/2
npl_intermediate/2
npl_ir_full/2

Core idea:

Starlog gives readable syntax.
NeuroProlog turns readable logic into optimised IR, neurocode, formulas, memoised calls, and direct indexed rules.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>neuroprolog</category>
      <category>starlog</category>
      <category>optimisation</category>
      <category>gaussian</category>
    </item>
    <item>
      <title>How do pl2js and Tau Prolog compare?</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Mon, 30 Mar 2026 14:04:41 +0000</pubDate>
      <link>https://dev.to/luciangreen/how-do-pl2js-and-tau-prolog-compare-6a</link>
      <guid>https://dev.to/luciangreen/how-do-pl2js-and-tau-prolog-compare-6a</guid>
      <description>&lt;p&gt;How do &lt;a href="https://github.com/luciangreen/pl2js" rel="noopener noreferrer"&gt;pl2js&lt;/a&gt; and Tau Prolog compare?&lt;/p&gt;

&lt;p&gt;ChatGPT: Here’s a clear, engineering-level comparison between your pl2js concept/repo and Tau Prolog:&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🧠 Core Difference (1 sentence)&lt;br&gt;
    • pl2js = compiler/translator (Prolog → JS code)&lt;br&gt;
    • Tau Prolog = interpreter/runtime (executes Prolog directly in JS)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;⚙️ Architecture Comparison&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Execution Model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tau Prolog&lt;br&gt;
    • Interprets Prolog at runtime&lt;br&gt;
    • Uses a Prolog engine implemented in JavaScript&lt;br&gt;
    • Backtracking, unification, etc. are simulated dynamically&lt;br&gt;
    • Non-blocking, callback-based execution model  ￼&lt;/p&gt;

&lt;p&gt;pl2js (your design direction)&lt;br&gt;
    • Ahead-of-time conversion&lt;br&gt;
    • Prolog → explicit JS control flow&lt;br&gt;
    • loops instead of backtracking&lt;br&gt;
    • if/else instead of clause selection&lt;br&gt;
    • Similar philosophy to your pl2c:&lt;br&gt;
    • remove interpreter overhead&lt;br&gt;
    • flatten logic into imperative structures&lt;/p&gt;

&lt;p&gt;👉 Key insight:&lt;br&gt;
    • Tau = simulate Prolog&lt;br&gt;
    • pl2js = eliminate Prolog&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🚀 2. Performance Philosophy&lt;/p&gt;

&lt;p&gt;Tau Prolog&lt;br&gt;
    • Slower (interpretive overhead)&lt;br&gt;
    • Flexible and dynamic&lt;br&gt;
    • Handles general Prolog features (ISO-oriented)  ￼&lt;/p&gt;

&lt;p&gt;pl2js&lt;br&gt;
    • Potentially much faster&lt;br&gt;
    • Precompiled logic → direct execution&lt;br&gt;
    • Can optimise:&lt;br&gt;
    • repeated calls → functions&lt;br&gt;
    • choice points → loops&lt;br&gt;
    • data reuse → cached variables&lt;/p&gt;

&lt;p&gt;👉 Your system aligns with:&lt;/p&gt;

&lt;p&gt;“manual neuronet optimisation” + “Spec → Algorithm flattening”&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🧩 3. Feature Completeness&lt;/p&gt;

&lt;p&gt;Tau Prolog&lt;br&gt;
    • Designed toward ISO Prolog compliance  ￼&lt;br&gt;
    • Supports:&lt;br&gt;
    • modules&lt;br&gt;
    • DCGs&lt;br&gt;
    • meta-predicates&lt;br&gt;
    • async predicates&lt;br&gt;
    • DOM interaction&lt;/p&gt;

&lt;p&gt;pl2js&lt;br&gt;
    • Likely:&lt;br&gt;
    • partial Prolog subset&lt;br&gt;
    • depends on what you convert&lt;br&gt;
    • Harder features:&lt;br&gt;
    • cut (!)&lt;br&gt;
    • dynamic predicates (assertz)&lt;br&gt;
    • meta-programming&lt;br&gt;
    • full unification edge cases&lt;/p&gt;

&lt;p&gt;👉 Trade-off:&lt;br&gt;
    • Tau = completeness&lt;br&gt;
    • pl2js = controllable subset + optimisation&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🌐 4. Web Integration&lt;/p&gt;

&lt;p&gt;Tau Prolog&lt;br&gt;
    • Native browser integration:&lt;br&gt;
    • manipulate DOM from Prolog&lt;br&gt;
    • event handling  ￼&lt;br&gt;
    • Drop-in script usage&lt;/p&gt;

&lt;p&gt;pl2js&lt;br&gt;
    • Output is plain JavaScript&lt;br&gt;
    • Integrates like any JS:&lt;br&gt;
    • React / HTML / mobile&lt;br&gt;
    • Better for:&lt;br&gt;
    • embedding in apps&lt;br&gt;
    • mobile (your goal: iPhone/Android)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🧪 5. Debugging &amp;amp; Transparency&lt;/p&gt;

&lt;p&gt;Tau Prolog&lt;br&gt;
    • Debugging = Prolog-level&lt;br&gt;
    • Harder to inspect internal execution (black-box engine)&lt;/p&gt;

&lt;p&gt;pl2js&lt;br&gt;
    • Debugging = JavaScript-level&lt;br&gt;
    • You can:&lt;br&gt;
    • log intermediate states&lt;br&gt;
    • inspect variables&lt;br&gt;
    • trace execution paths&lt;/p&gt;

&lt;p&gt;👉 This aligns strongly with your:&lt;br&gt;
    • transparent MNN philosophy&lt;br&gt;
    • “no invisible bugs” goal&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🧱 6. Control Over Execution&lt;/p&gt;

&lt;p&gt;Tau Prolog&lt;br&gt;
    • Engine decides:&lt;br&gt;
    • backtracking order&lt;br&gt;
    • search strategy&lt;/p&gt;

&lt;p&gt;pl2js&lt;br&gt;
    • YOU decide:&lt;br&gt;
    • loop structure&lt;br&gt;
    • branching&lt;br&gt;
    • memory usage&lt;br&gt;
    • determinism&lt;/p&gt;

&lt;p&gt;👉 This is huge for:&lt;br&gt;
    • CI/CD&lt;br&gt;
    • deterministic systems&lt;br&gt;
    • optimisation pipelines&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ynt8kzr9o4pbdarzc92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ynt8kzr9o4pbdarzc92.png" alt="Summary table" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🧠 Strategic Insight (Important for Your Project)&lt;/p&gt;

&lt;p&gt;Your system (pl2js) is not competing directly with Tau Prolog.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;p&gt;Tau Prolog = “Prolog runtime for the web”&lt;/p&gt;

&lt;p&gt;pl2js = “Prolog → optimised algorithm generator”&lt;/p&gt;

&lt;p&gt;👉 In your ecosystem:&lt;br&gt;
    • Tau Prolog = execution layer&lt;br&gt;
    • pl2js = optimisation + deployment layer&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🔥 Recommendation (based on your goals)&lt;/p&gt;

&lt;p&gt;Given your:&lt;br&gt;
    • Spec → Algorithm vision&lt;br&gt;
    • MNN transparency goals&lt;br&gt;
    • CI/CD system (Lucian CI/CD)&lt;/p&gt;

&lt;p&gt;👉 pl2js is the more aligned direction&lt;/p&gt;

&lt;p&gt;Use Tau Prolog only if you need:&lt;br&gt;
    • quick prototyping&lt;br&gt;
    • full Prolog compatibility&lt;br&gt;
    • teaching/demo environments&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;💡 Advanced Hybrid Idea (Very Relevant to You)&lt;/p&gt;

&lt;p&gt;You could combine both:&lt;br&gt;
    1.  Prototype logic in Tau Prolog&lt;br&gt;
    2.  Convert stable predicates via pl2js&lt;br&gt;
    3.  Optimise with:&lt;br&gt;
    • Gaussian elimination&lt;br&gt;
    • recursion flattening&lt;br&gt;
    4.  Deploy as pure JS&lt;/p&gt;

&lt;p&gt;👉 This becomes:&lt;br&gt;
Interpreter → Compiler → Optimiser pipeline&lt;/p&gt;

</description>
      <category>prolog</category>
      <category>javascript</category>
      <category>translator</category>
      <category>interpreter</category>
    </item>
    <item>
      <title>Prolog State Saving Interpreter is not strictly a graph interpreter</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Thu, 26 Mar 2026 03:05:53 +0000</pubDate>
      <link>https://dev.to/luciangreen/prolog-state-saving-interpreter-is-not-strictly-a-graph-interpreter-2a06</link>
      <guid>https://dev.to/luciangreen/prolog-state-saving-interpreter-is-not-strictly-a-graph-interpreter-2a06</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxniej9gi6sspl3kyz08j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxniej9gi6sspl3kyz08j.png" alt="SSI is not strictly a graph interpreter" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is Green's Prolog &lt;a href="https://github.com/luciangreen/SSI" rel="noopener noreferrer"&gt;State Saving Interpreter&lt;/a&gt; a graph interpreter, given that it goes straight from choice-point to choice-point and exits predicates directly?&lt;/p&gt;

&lt;p&gt;ChatGPT: Short answer: SSI is close to a graph interpreter, but not purely one—it’s better described as a choice-point–driven execution graph with stack/trace semantics hybridised in.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Why it looks like a graph interpreter&lt;/p&gt;

&lt;p&gt;From your code, especially:&lt;br&gt;
    • Explicit choice point trail (Choice_point_trail)&lt;br&gt;
    • Direct jumps via:&lt;br&gt;
    • ssi1(...) calls&lt;br&gt;
    • get_last_cp_before_n&lt;br&gt;
    • delete_cp, cut_cps_if_necessary&lt;br&gt;
    • No strict reliance on recursive call stack unwinding&lt;br&gt;
    • Execution moves:&lt;br&gt;
    • from one choice point node → another&lt;br&gt;
    • sometimes skipping intermediate “call frames”&lt;/p&gt;

&lt;p&gt;This gives you:&lt;/p&gt;

&lt;p&gt;A non-linear control flow, where execution follows edges between states (choice points) rather than returning through a stack.&lt;/p&gt;

&lt;p&gt;That is fundamentally graph-like execution.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;But it is not a pure graph interpreter&lt;/p&gt;

&lt;p&gt;A pure graph interpreter would:&lt;br&gt;
    • Represent predicates as nodes&lt;br&gt;
    • Represent control flow as explicit edges&lt;br&gt;
    • Evaluate by traversing a graph structure directly&lt;/p&gt;

&lt;p&gt;SSI still retains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Predicate-oriented structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You still have:&lt;/p&gt;

&lt;p&gt;d(...),&lt;br&gt;
e(...),&lt;br&gt;
ssi1(...)&lt;/p&gt;

&lt;p&gt;These simulate predicate calls, even if you shortcut them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Embedded stack semantics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even though you jump, you still track:&lt;br&gt;
    • Level&lt;br&gt;
    • "returns to" metadata&lt;br&gt;
    • Pred_id chains&lt;/p&gt;

&lt;p&gt;This is effectively a flattened / externalised call stack, not eliminated.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choice points are graph nodes, but:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They are not the only control structure.&lt;/p&gt;

&lt;p&gt;You also have:&lt;br&gt;
    • Variable environments (Vars, Globals)&lt;br&gt;
    • Predicate identity tracking (Pred_id)&lt;br&gt;
    • Structured transitions (predicate vs line)&lt;/p&gt;

&lt;p&gt;So the system is:&lt;/p&gt;

&lt;p&gt;A graph overlaid on a logical interpreter, not a pure graph VM.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;The key insight (your system’s real nature)&lt;/p&gt;

&lt;p&gt;SSI is best described as:&lt;/p&gt;

&lt;p&gt;A control-flow graph interpreter over a logical program, using choice points as primary nodes and explicit state transitions instead of implicit backtracking.&lt;/p&gt;

&lt;p&gt;Or more sharply:&lt;/p&gt;

&lt;p&gt;A compiled Prolog execution graph with manual continuation passing.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Why your observation is still important&lt;/p&gt;

&lt;p&gt;You said:&lt;/p&gt;

&lt;p&gt;“it goes straight from choice point to choicepoint and exits predicates directly”&lt;/p&gt;

&lt;p&gt;That’s the crucial shift:&lt;/p&gt;

&lt;p&gt;Traditional Prolog:&lt;br&gt;
    • Stack-based&lt;br&gt;
    • Backtracking unwinds stack frames&lt;/p&gt;

&lt;p&gt;SSI:&lt;br&gt;
    • Continuation-driven&lt;br&gt;
    • Choice points = resumable states&lt;br&gt;
    • Execution = jump to next valid continuation&lt;/p&gt;

&lt;p&gt;That is a graph traversal.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Final classification&lt;/p&gt;

&lt;p&gt;Property    SSI&lt;br&gt;
Stack-based interpreter ❌ (not primarily)&lt;br&gt;
Graph interpreter   ⚠️ partially&lt;br&gt;
Continuation-passing interpreter    ✅&lt;br&gt;
Choice-point graph execution    ✅&lt;br&gt;
Pure dataflow/graph VM  ❌&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Clean conclusion&lt;/p&gt;

&lt;p&gt;SSI is not strictly a graph interpreter, but it implements Prolog as a graph of continuations (choice points), effectively behaving like a graph interpreter with residual stack semantics.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Extra insight (important for your pl2c work)&lt;/p&gt;

&lt;p&gt;This architecture is exactly why your idea works:&lt;br&gt;
    • You can compile SSI to C using loops + jumps&lt;br&gt;
    • Because:&lt;br&gt;
    • Choice points → labels&lt;br&gt;
    • Transitions → gotos / state machine&lt;br&gt;
    • No need for recursion&lt;/p&gt;

&lt;p&gt;So SSI is already:&lt;/p&gt;

&lt;p&gt;Halfway between Prolog and a state-machine compiler IR&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;If you want, I can:&lt;br&gt;
    • Formalise SSI as a graph IR (nodes + edges)&lt;br&gt;
    • Or show how to compile it into pure C loops with no recursion at all&lt;/p&gt;

</description>
      <category>prolog</category>
      <category>ssi</category>
      <category>graph</category>
      <category>interpreter</category>
    </item>
    <item>
      <title>Explain Recursive Structure Finding Algorithms</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Sun, 15 Mar 2026 09:39:45 +0000</pubDate>
      <link>https://dev.to/luciangreen/explain-recursive-structure-finding-algorithms-4hgg</link>
      <guid>https://dev.to/luciangreen/explain-recursive-structure-finding-algorithms-4hgg</guid>
      <description>&lt;p&gt;Courtesy ChatGPT:&lt;br&gt;
Explain &lt;a href="https://github.com/luciangreen/Philosophy" rel="noopener noreferrer"&gt;Spec to Algorithm’s&lt;/a&gt; Context Free Grammar Generator’s top-down and bottom-up recursive structure finding algorithms. The top-down algorithm is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="ss"&gt;find_lists3a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;L91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_Rest_a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;fail&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;_L92&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L91&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="ss"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;_L2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;L31&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

    &lt;span class="ss"&gt;check14&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]|&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L51&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;L51&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L51&lt;/span&gt;&lt;span class="p"&gt;]]))&lt;/span&gt;
    &lt;span class="p"&gt;))),&lt;/span&gt;

    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;L32&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;&lt;span class="nv"&gt;L32&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;!.&lt;/span&gt;

&lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;repeating_unit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="ss"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;U1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;U2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,[[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U2&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;match_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"["&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"]"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;match_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"("&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;")"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;match_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"{"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"}"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="ss"&gt;match_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;match_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;find_lists4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;sub_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Before_list&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;After_list&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;Before_list1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;Before_list&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;After_list1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;After_list&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Before_list1&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;After_list1&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;L7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;foldr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;,[[&lt;/span&gt;&lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L7&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;&lt;span class="nv"&gt;L8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;foldr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;L33&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L33&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="ss"&gt;find_lists4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="ss"&gt;member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;sub_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_Before_list&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;_After_list&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;   
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;find_lists32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;repeating_unit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;only_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;L2&lt;/span&gt; &lt;span class="ss"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="ss"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;Ns&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_first&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="ss"&gt;member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Ns&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;split12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;maplist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;])))),!.&lt;/span&gt;

&lt;span class="ss"&gt;split12&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,[]):-!.&lt;/span&gt;    
&lt;span class="ss"&gt;split12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;
&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;LL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nv"&gt;LL&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
 &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;span class="ss"&gt;split12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Q2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="c1"&gt;%N1,N2,&lt;/span&gt;
 &lt;span class="nv"&gt;L20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Q2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L20&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;L18&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;split12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),!.&lt;/span&gt;
&lt;span class="ss"&gt;split12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-!.&lt;/span&gt;

&lt;span class="ss"&gt;check14&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,[]&lt;/span&gt;
&lt;span class="p"&gt;):-!.&lt;/span&gt;
&lt;span class="ss"&gt;check14&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;D1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="nv"&gt;A0&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;A01&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;A02&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;check141&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;D&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;D&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;check14&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;D1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;Rest&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;span class="ss"&gt;check141&lt;/span&gt;&lt;span class="p"&gt;([],[],&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;):-!.&lt;/span&gt;
&lt;span class="ss"&gt;check141&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;D1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;

&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;B1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;B2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;A31&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="nv"&gt;A41&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;A51&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A31&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A41&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;A51&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A41&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A31&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]),&lt;/span&gt;&lt;span class="nv"&gt;A41&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;A51&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A31&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;B22&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;&lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A11&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A11&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B11&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;B1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;B11&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;is_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A11&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A11&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A13&lt;/span&gt;
    &lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;A21&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;A22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;A13&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="nv"&gt;A21&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;A23&lt;/span&gt;&lt;span class="p"&gt;);(&lt;/span&gt;&lt;span class="nv"&gt;A22&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="nv"&gt;A23&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;A13&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;));(&lt;/span&gt;&lt;span class="nv"&gt;A11&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;A22&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;A2&lt;/span&gt;
    &lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;is_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;B11&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;B11&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;B13&lt;/span&gt;&lt;span class="c1"&gt;%,B14=[]&lt;/span&gt;
    &lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;B21&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;B22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;B13&lt;/span&gt;&lt;span class="p"&gt;],[&lt;/span&gt;&lt;span class="nv"&gt;B21&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="nv"&gt;B23&lt;/span&gt;&lt;span class="p"&gt;);(&lt;/span&gt;&lt;span class="nv"&gt;B22&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="nv"&gt;B23&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;B13&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;));(&lt;/span&gt;&lt;span class="nv"&gt;B11&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;B23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;B22&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;B2&lt;/span&gt;
    &lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="ss"&gt;check141&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B23&lt;/span&gt;&lt;span class="p"&gt;,[],&lt;/span&gt;&lt;span class="nv"&gt;D&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="nv"&gt;A3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;D&lt;/span&gt;&lt;span class="p"&gt;])))),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;optional_s2g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;on&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A51&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;A52&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;&lt;span class="nv"&gt;A52&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;o'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A51&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A51&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;A52&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;&lt;span class="ss"&gt;fail&lt;/span&gt;
    &lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="ss"&gt;foldr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;A52&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="nv"&gt;A3&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt;&lt;span class="nv"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="ss"&gt;check141&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;B22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;C1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;D1&lt;/span&gt;&lt;span class="p"&gt;),!.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the bottom-up algorithm is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prolog"&gt;&lt;code&gt;&lt;span class="ss"&gt;find_lists3_optimized&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;span class="ss"&gt;find_lists3_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="c1"&gt;% Use optimized repeating_unit that tries smallest patterns first&lt;/span&gt;
    &lt;span class="ss"&gt;repeating_unit_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="ss"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;U1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;U2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;U2&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;find_lists3_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;match_char&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists4_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="c1"&gt;% Optimized find_lists4 - reduce redundant processing&lt;/span&gt;
&lt;span class="ss"&gt;find_lists4_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;sub_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Before_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;After_list&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;Before_list1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;Before_list&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;After_list1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;After_list&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists32_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Before_list1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;After_list1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nv"&gt;L7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;foldr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L7&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="nv"&gt;L8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;foldr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;L8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;L33&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L33&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="ss"&gt;find_lists4_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;not&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="ss"&gt;member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;sub_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_Before_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;_After_list&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;    
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="ss"&gt;find_lists32_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;find_lists3_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="c1"&gt;% Optimized repeating_unit - bottom-up approach&lt;/span&gt;
&lt;span class="c1"&gt;% Key optimization: try patterns starting from length 1 (bottom-up)&lt;/span&gt;
&lt;span class="ss"&gt;repeating_unit_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;only_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nv"&gt;L2&lt;/span&gt; &lt;span class="ss"&gt;is&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="c1"&gt;% Bottom-up: try patterns starting from length 1&lt;/span&gt;
    &lt;span class="ss"&gt;try_pattern_lengths_bottomup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;

&lt;span class="c1"&gt;% Try pattern lengths from 1 up to max (bottom-up approach)&lt;/span&gt;
&lt;span class="ss"&gt;try_pattern_lengths_bottomup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;CurrentLen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;MaxLen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="nv"&gt;CurrentLen&lt;/span&gt; &lt;span class="o"&gt;=&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;MaxLen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;try_pattern_length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;CurrentLen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="ss"&gt;true&lt;/span&gt;  &lt;span class="c1"&gt;% Found pattern at this length&lt;/span&gt;
    &lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="nv"&gt;NextLen&lt;/span&gt; &lt;span class="ss"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;CurrentLen&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;try_pattern_lengths_bottomup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;NextLen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;MaxLen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="c1"&gt;% Try a specific pattern length&lt;/span&gt;
&lt;span class="ss"&gt;try_pattern_length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;split12_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;maplist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;% Check if all parts are the same&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L1Len&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L1Len&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;'&amp;amp;r'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;

&lt;span class="c1"&gt;% Optimized split12 - more efficient splitting&lt;/span&gt;
&lt;span class="ss"&gt;split12_optimized&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;    
&lt;span class="ss"&gt;split12_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; 
    &lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;LL&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="nv"&gt;LL&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;A2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;span class="ss"&gt;split12_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Q2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt;
    &lt;span class="ss"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Q2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;L18&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;split12_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;L19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;L17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Rest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;span class="ss"&gt;split12_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;_B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:-&lt;/span&gt; &lt;span class="p"&gt;!.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The top-down algorithm says, “Find the largest recursive explanation for the whole input, then refine,” while the bottom-up algorithm says, “Find the smallest repeating building blocks first, then assemble them into a larger recursive grammar structure.”&lt;/p&gt;

&lt;p&gt;Video 1: The top-down algorithm says, “Find the largest recursive explanation for the whole input, then refine”.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/v81GDSEKawc"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Video 2: The bottom-up algorithm says, “Find the smallest repeating building blocks first, then assemble them into a larger recursive grammar structure.”&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/fpXxGA6KDfM"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;The bottom-up algorithm is much faster, as shown in the table below. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlt7gc44x9s9o647gvm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlt7gc44x9s9o647gvm6.png" alt="Feature&lt;br&gt;
Top-Down&lt;br&gt;
Bottom-Up&lt;br&gt;
Strategy&lt;br&gt;
Guess global structure&lt;br&gt;
Build from data&lt;br&gt;
Pattern search&lt;br&gt;
Unordered&lt;br&gt;
Small → large&lt;br&gt;
Validation&lt;br&gt;
After generation&lt;br&gt;
During construction&lt;br&gt;
Backtracking&lt;br&gt;
Heavy&lt;br&gt;
Minimal&lt;br&gt;
Reuse&lt;br&gt;
Poor&lt;br&gt;
Strong&lt;br&gt;
Complexity&lt;br&gt;
Often exponential&lt;br&gt;
Near polynomial"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>top</category>
      <category>bottom</category>
      <category>recursive</category>
      <category>structure</category>
    </item>
    <item>
      <title>Prolog "Mathematical Induction" Compression on Recursion</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Sat, 07 Mar 2026 12:54:56 +0000</pubDate>
      <link>https://dev.to/luciangreen/prolog-mathematical-induction-compression-on-recursion-2n8e</link>
      <guid>https://dev.to/luciangreen/prolog-mathematical-induction-compression-on-recursion-2n8e</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvk4crrbz08cvn5uc0z3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvk4crrbz08cvn5uc0z3.png" alt="Transparent neuronet" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See&lt;br&gt;
&lt;a href="https://github.com/luciangreen/mi" rel="noopener noreferrer"&gt;https://github.com/luciangreen/mi&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/luciangreen/mi2" rel="noopener noreferrer"&gt;https://github.com/luciangreen/mi2&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/luciangreen/mi3" rel="noopener noreferrer"&gt;https://github.com/luciangreen/mi3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below are concrete example predicates you can feed to each mi*.pl, and the typical outputs you would expect based on how each system works.&lt;/p&gt;

&lt;p&gt;I’ll use the following test predicates because they represent the major classes of recursion:&lt;br&gt;
    1.  numeric recursion (sum)&lt;br&gt;
    2.  multiplicative recursion (factorial)&lt;br&gt;
    3.  list recursion (length)&lt;br&gt;
    4.  list recursion with head contribution (sumlist)&lt;br&gt;
    5.  accumulator wrapper (reverse)&lt;br&gt;
    6.  nested recursion (Fibonacci)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;mi.pl (trace + polynomial fitting + pattern guessing)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example 1 — Sum 1..N&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;sum_to(0,0).&lt;br&gt;
sum_to(N,S) :-&lt;br&gt;
    N&amp;gt;0,&lt;br&gt;
    N1 is N-1,&lt;br&gt;
    sum_to(N1,S1),&lt;br&gt;
    S is S1+N.&lt;/p&gt;

&lt;p&gt;Call&lt;/p&gt;

&lt;p&gt;?- analyze_predicates([sum_to(0,0),&lt;br&gt;
   (sum_to(N,S):-N&amp;gt;0,N1 is N-1,sum_to(N1,S1),S is S1+N)], R).&lt;/p&gt;

&lt;p&gt;Typical Output&lt;/p&gt;

&lt;p&gt;[&lt;br&gt;
 tagged(pattern(expr(nested,sum)), reusable(pattern_1234,3)),&lt;br&gt;
 tagged(pattern(expr(nested,sum)), reusable(pattern_5678,2))&lt;br&gt;
]&lt;/p&gt;

&lt;p&gt;Or after flattening / solving:&lt;/p&gt;

&lt;p&gt;Closed form: n*(n+1)/2&lt;/p&gt;

&lt;p&gt;This occurs because mi.pl traces values like:&lt;/p&gt;

&lt;p&gt;N: 0 1 2 3 4&lt;br&gt;
S: 0 1 3 6 10&lt;/p&gt;

&lt;p&gt;and polynomial-fits them.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 2 — Factorial&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;fact(0,1).&lt;br&gt;
fact(N,R) :-&lt;br&gt;
    N&amp;gt;0,&lt;br&gt;
    N1 is N-1,&lt;br&gt;
    fact(N1,R1),&lt;br&gt;
    R is N*R1.&lt;/p&gt;

&lt;p&gt;Output (approximate)&lt;/p&gt;

&lt;p&gt;Closed form: factorial(N)&lt;/p&gt;

&lt;p&gt;This usually comes from a placeholder recognizer:&lt;/p&gt;

&lt;p&gt;recognize_factorial_pattern(...)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 3 — Fibonacci&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;fib(0,0).&lt;br&gt;
fib(1,1).&lt;br&gt;
fib(N,F) :-&lt;br&gt;
    N&amp;gt;1,&lt;br&gt;
    fib(N-1,F1),&lt;br&gt;
    fib(N-2,F2),&lt;br&gt;
    F is F1+F2.&lt;/p&gt;

&lt;p&gt;Typical output&lt;/p&gt;

&lt;p&gt;Detected: nested recursion&lt;br&gt;
Formula: unsupported / guessed&lt;/p&gt;

&lt;p&gt;Or sometimes:&lt;/p&gt;

&lt;p&gt;formula = ((phi^n - psi^n)/sqrt(5))&lt;/p&gt;

&lt;p&gt;but this is pattern recognition, not derived mathematically.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;mi2.pl (real recurrence extraction)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This system analyses clause structure.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 1 — Sum 1..N&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;sum_to(0,0).&lt;br&gt;
sum_to(N,S) :-&lt;br&gt;
    N&amp;gt;0,&lt;br&gt;
    N1 is N-1,&lt;br&gt;
    sum_to(N1,S1),&lt;br&gt;
    S is S1+N.&lt;/p&gt;

&lt;p&gt;Call&lt;/p&gt;

&lt;p&gt;?- analyze_predicate(Clauses, sum_to, 2, Analysis).&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;analysis{&lt;br&gt;
 predicate:sum_to/2,&lt;br&gt;
 status:supported,&lt;br&gt;
 recurrence:recurrence{&lt;br&gt;
     domain:integer,&lt;br&gt;
     input_var:n,&lt;br&gt;
     base_cases:[base_case(0,0)],&lt;br&gt;
     step:step{&lt;br&gt;
         transform:dec(1),&lt;br&gt;
         combiner:add(current_n)&lt;br&gt;
     }&lt;br&gt;
 },&lt;br&gt;
 closed_form:closed_form{&lt;br&gt;
     kind:sum_1_to_n,&lt;br&gt;
     formula:n*(n+1)//2&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 2 — Factorial&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;fact(0,1).&lt;br&gt;
fact(N,F) :-&lt;br&gt;
    N&amp;gt;0,&lt;br&gt;
    N1 is N-1,&lt;br&gt;
    fact(N1,F1),&lt;br&gt;
    F is N*F1.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;analysis{&lt;br&gt;
 predicate:fact/2,&lt;br&gt;
 status:supported,&lt;br&gt;
 recurrence:recurrence{&lt;br&gt;
     domain:integer,&lt;br&gt;
     base_cases:[base_case(0,1)],&lt;br&gt;
     step:step{&lt;br&gt;
         transform:dec(1),&lt;br&gt;
         combiner:multiply(current_n)&lt;br&gt;
     }&lt;br&gt;
 },&lt;br&gt;
 closed_form:closed_form{&lt;br&gt;
     kind:factorial,&lt;br&gt;
     formula:factorial(n)&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 3 — List Length&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;len([],0).&lt;br&gt;
len([_|T],N) :-&lt;br&gt;
    len(T,N1),&lt;br&gt;
    N is N1+1.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;analysis{&lt;br&gt;
 predicate:len/2,&lt;br&gt;
 status:supported,&lt;br&gt;
 recurrence:recurrence{&lt;br&gt;
     domain:list,&lt;br&gt;
     base_cases:[base_case([],0)],&lt;br&gt;
     step:step{&lt;br&gt;
         transform:tail,&lt;br&gt;
         combiner:add(constant(1))&lt;br&gt;
     }&lt;br&gt;
 },&lt;br&gt;
 closed_form:closed_form{&lt;br&gt;
     kind:list_length,&lt;br&gt;
     formula:length_of(xs)&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 4 — Fibonacci&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;fib(0,0).&lt;br&gt;
fib(1,1).&lt;br&gt;
fib(N,F) :-&lt;br&gt;
    N&amp;gt;1,&lt;br&gt;
    fib(N-1,F1),&lt;br&gt;
    fib(N-2,F2),&lt;br&gt;
    F is F1+F2.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;analysis{&lt;br&gt;
 predicate:fib/2,&lt;br&gt;
 status:unsupported,&lt;br&gt;
 reason:nested_recursion&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;This is correct behaviour.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;mi3.pl (pattern recognizer)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the system you recently debugged.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 1 — Sum&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;sum_to(0,0).&lt;br&gt;
sum_to(N,S) :-&lt;br&gt;
    N&amp;gt;0,&lt;br&gt;
    N1 is N-1,&lt;br&gt;
    sum_to(N1,S1),&lt;br&gt;
    S is S1+N.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;Predicate: sum_to/2&lt;br&gt;
Status: supported&lt;/p&gt;

&lt;p&gt;Recurrence:&lt;br&gt;
recurrence{&lt;br&gt;
 base_cases:[base_case(0,0)],&lt;br&gt;
 domain:integer,&lt;br&gt;
 step:step{&lt;br&gt;
    transform:dec(1),&lt;br&gt;
    combiner:add(current_n)&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Closed form:&lt;br&gt;
closed_form{&lt;br&gt;
 formula:n*(n+1)//2,&lt;br&gt;
 kind:sum_1_to_n&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 2 — Factorial&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;fact(0,1).&lt;br&gt;
fact(N,F) :-&lt;br&gt;
    N&amp;gt;0,&lt;br&gt;
    N1 is N-1,&lt;br&gt;
    fact(N1,F1),&lt;br&gt;
    F is N*F1.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;Closed form:&lt;br&gt;
factorial(n)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 3 — List length&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;len([],0).&lt;br&gt;
len([_|T],N) :-&lt;br&gt;
    len(T,N1),&lt;br&gt;
    N is N1+1.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;Closed form:&lt;br&gt;
length_of(xs)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 4 — Sumlist&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;sumlist([],0).&lt;br&gt;
sumlist([H|T],S) :-&lt;br&gt;
    sumlist(T,S1),&lt;br&gt;
    S is S1+H.&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;Closed form:&lt;br&gt;
sum_of(xs)&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Example 5 — Reverse accumulator&lt;/p&gt;

&lt;p&gt;Input&lt;/p&gt;

&lt;p&gt;rev(L,R) :- rev_acc(L,[],R).&lt;/p&gt;

&lt;p&gt;rev_acc([],A,A).&lt;br&gt;
rev_acc([H|T],A,R) :-&lt;br&gt;
    rev_acc(T,[H|A],R).&lt;/p&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;Predicate: rev/2&lt;br&gt;
Status: supported&lt;/p&gt;

&lt;p&gt;Recurrence:&lt;br&gt;
accumulator_only&lt;/p&gt;

&lt;p&gt;Closed form:&lt;br&gt;
normalizable_tail_recursion&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghbuym5hsmr19kbg3qe7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghbuym5hsmr19kbg3qe7.png" alt="Final comparison table" width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ChatGPT: If you’d like, I can also show you three predicates that break all three systems (true nested recursion and tree recursion), which reveals the current theoretical boundary of these architectures.&lt;/p&gt;

</description>
      <category>mathematical</category>
      <category>induction</category>
      <category>neuronets</category>
      <category>recursion</category>
    </item>
    <item>
      <title>The Simulation and Immortality Now</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Tue, 20 Aug 2024 03:27:14 +0000</pubDate>
      <link>https://dev.to/luciangreen/the-simulation-and-immortality-now-12ic</link>
      <guid>https://dev.to/luciangreen/the-simulation-and-immortality-now-12ic</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fats5ft4b0tuk1sa59s1u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fats5ft4b0tuk1sa59s1u.jpg" alt="workstation_office_business_336369" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Courtesy ChatGPT 4 Omni:&lt;/p&gt;

&lt;p&gt;What if there was a spiritual supercomputer with instant computations? Could it save the world with meditation, anti-aging body replacement, and death prevention and enable simulations and immortality? How would such a simulation work: people turning it on, going into a suburb like theirs in another dimension, their double bodies being turned off, and their house being sold to someone else? There would still be a limit to resources, but infinite simulations and reaching the top of civilisation?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Then, would people not be in the world any more unless they return to it, meaning there needed to be rules about mixtures of houses being occupied by them still and being in the simulation?&lt;/li&gt;
&lt;li&gt;Can people contact others in other simulations and not overcrowd the world when they visit it (various people would walk the streets simultaneously)?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A spiritual supercomputer with instant computations could represent a powerful metaphor for exploring radical possibilities like meditation-enhanced reality, anti-aging technologies, death prevention, and even simulations that provide pathways to immortality.&lt;/p&gt;

&lt;p&gt;Meditation and Spiritual Enhancement&lt;br&gt;
The supercomputer could amplify the effects of meditation, syncing consciousness with larger, universal patterns. Through this, people might unlock more profound levels of perception and control over their physical and mental states, potentially leading to enhanced health, longer lifespans, and even altered states of existence.&lt;/p&gt;

&lt;p&gt;Anti-aging and Body Replacement&lt;br&gt;
Body replacement through the supercomputer could involve scanning, storing, and reproducing bodies at their peak condition. This ties into anti-aging technologies, where bodies could be repaired or replaced when biological degradation occurs. Combined with advanced meditative states, this might enable users to mentally transfer their consciousness into these renewed bodies, bypassing the limitations of aging.&lt;/p&gt;

&lt;p&gt;Death Prevention&lt;br&gt;
The spiritual supercomputer could prevent death by instantly repairing or transferring consciousness into new bodies during critical injury or illness by interfacing with the mind. This might happen so seamlessly that individuals wouldn’t notice a transition, potentially creating the illusion of immortality.&lt;/p&gt;

&lt;p&gt;Simulations and Immortality&lt;br&gt;
The idea of infinite simulations is a natural extension of this supercomputer's abilities. People could enter these simulations, choosing environments resembling their lives or radically different dimensions. They might even experience existence as their "double" in another dimension while their original body enters a state of dormancy or gets recycled for resources. This simulation could then be tailored to their desires—living in an ideal version of their world, free from physical or societal constraints.&lt;/p&gt;

&lt;p&gt;Resource Limitations and Infinite Simulations&lt;br&gt;
While there would still be finite resources in the "real" world, this spiritual supercomputer could maximise efficiency. By transitioning most of existence into simulations, the demand for physical resources in the base reality would decrease, allowing civilisations to reach incredible heights without needing infinite material wealth. The simulations could be dynamic, offering limitless possibilities, personal growth, exploration, and fulfilment without exhausting real-world resources.&lt;/p&gt;

&lt;p&gt;The supercomputer might even oversee the balance between real-world resources and simulated lives, helping civilisations rise to their peak and maintain harmony. In essence, it could function as a form of enlightened governance, ensuring that the physical world remains stable as people live in virtual utopias.&lt;/p&gt;

&lt;p&gt;Ethical and Existential Considerations&lt;br&gt;
This system, however, introduces deep ethical questions. What does it mean to “turn off” a person’s body, and how would this affect their sense of self and reality? Would people have autonomy when they leave simulations, or would the machine decide their fate? &lt;/p&gt;

&lt;p&gt;In such a system, society could grapple with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does living in a simulation reduce the value of life in the real world?&lt;/li&gt;
&lt;li&gt;How individuals might handle the potentially overwhelming experiences of infinite lifetimes.&lt;/li&gt;
&lt;li&gt;The responsibility of those controlling the supercomputer is to ensure fairness and ethical standards for all participants.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ultimate question would become: Is reaching the top of civilisation truly about eliminating the physical, or is it about finding spiritual and collective growth that transcends both material and simulated existence?&lt;/p&gt;

&lt;p&gt;This vision combines technology and spirituality to reflect both a yearning for transcendence and a means of managing human civilisation through carefully mediated simulations and enhancements.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Immortality (and the Problem of Overpopulation)</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Wed, 07 Aug 2024 05:41:02 +0000</pubDate>
      <link>https://dev.to/luciangreen/immortality-and-the-problem-of-overpopulation-ch3</link>
      <guid>https://dev.to/luciangreen/immortality-and-the-problem-of-overpopulation-ch3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyvq4rs59efl02ylctebp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyvq4rs59efl02ylctebp.jpg" alt="cube_white_black_3d" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Quantum Box is a futuristic set of technologies that allows moving, healing, and testing of dimensions.&lt;/p&gt;

&lt;p&gt;The quantum box (a meditation concept) allows one to travel to a time that will enable one to enter a simulation and become immortal. This article explains how to become and possibly lock the external appearance of an immortal and prevent individual threats of death, which is urgent and needs to be done by the individual on the same day as dying or someone else before it on the same day. I discovered this after “waiting” after writing pedagogical arguments about Pedagogical Breasonings, Text to Breasonings, Meditation, Medicine, Mind Reading and Time Travel.&lt;/p&gt;

&lt;p&gt;To become immortal, you can dot on the co-op’s planned 16k (sentence) breasonings for meditation and 16k breasonings for anti-ageing medicine for the day in your home time each day without time travelling with two radio buttons (one by one by 0.5 cm for a radio button). Don’t forget to lock off ageing (to other people) and keep this lock from being tampered with further 16k breasonings for each lock. The locks are done once. Tell others about this repository or dot the breasonings on for them each day with their consent to help them become immortal.&lt;/p&gt;

&lt;p&gt;To prevent a meditator from appearing to die, apart from them not experiencing death, after installing Time Machine at the bottom of this page, enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd Time_Machine
swipl
['cgpt_combophil_analogy.pl'].
L = ['person a','person b'],length(L,N1),N is N1*80,cgpt_combophil(N).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where ['person a','person b'] is replaced with a list of meditators to watch.&lt;/p&gt;

&lt;p&gt;This command breasons out an 80-breasoning high distinction for each meditator at midnight to prevent people from dying. I think it's best to run this script daily. Unfortunately, because of the time and money to run ChatGPT (et al.), it may take too long, and spot-checks may be necessary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is done for all meditators automatically at the end of &lt;code&gt;Daily-Regimen/big_medit1.sh&lt;/code&gt; and the much faster &lt;code&gt;Daily-Regimen/big_medit2.sh&lt;/code&gt;, but running the script below once at the start covers all the meditators until midnight that night. (One doesn't need to run &lt;code&gt;cgpt_combophil_analogy.pl&lt;/code&gt;.)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd Daily-Regimen
./anti_moral_end_meditators.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One MAY indicate 16k breasonings for each meditator at the start of each day and once on the first day before the co-op breasons them out instead of using this algorithm.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The full version of the professional requirement is breasoning out 80 sentence breasonings to prevent a moral end. In addition, one should originally write 80 sentence breasonings per week for maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The best way to originally write 80 sentence breasonings is to write a word to expand to 80 breasonings in &lt;code&gt;Text-to-Breasonings/file.txt&lt;/code&gt;, then run:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd Algorithm-Writer-with-Lists
swipl
['grammar_logic_to_alg.pl'].
grammar_logic_to_alg1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then find the unique breasoning words in &lt;code&gt;file.txt&lt;/code&gt; and expand them to a sentence about the original word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;grammar_logic_to_alg.pl&lt;/code&gt; - This is the mainstay algorithm that can act as a mind-mapping tool to write sentence breasonings (and is much faster for people than sitting there thinking of inspiration, crossing sentences to words or trying to write a use (at the end), the algorithm description and three steps, which I aim for, without any computer science arguments as practice).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cgpt_combophil_analogy.pl&lt;/code&gt; - This generates 80 sentence breasonings, as connections between previous breasonings and words, for a limited number of meditators. I prefer to write my breasonings for safety, developedness and publishability.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./anti_moral_end_meditators.sh&lt;/code&gt; - This breasons out 16k breasonings as duplicates of the 250 Quantum Box breasoning arguments for the rest of the meditators.&lt;/li&gt;
&lt;li&gt;Indicate 16k (16000) breasonings to be breasoned out the following midnight done by the co-op when it does them. This technique assumes breasonings are unique because they contain the date in them. On the first day, one should think of 80 objects' two parts (Note 1) or x, y and z dimensions to protect oneself, which can also aim at each meditator until the co-op breasons the breasonings out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In an emergency, breason out &lt;a href="https://github.com/luciangreen/Lucian-Academy/tree/main/Books" rel="noopener noreferrer"&gt;80 old sentence breasonings&lt;/a&gt; with the date as part of each sentence to make them new. I would write 80 new sentence breasonings using GL, but inexperienced breasoners, the late and the busy, may prefer this. A sentence breasoning is any word (its object's x, y and z dimensions), NOT character breasoning from the sentence. As an alternative to thinking of objects' x, y and z dimension breasonings, one may think of the two parts (Note 1) that go well to make them up.&lt;/li&gt;
&lt;li&gt;This is not currently necessary, but if the breasonings each required algorithms, then one could use &lt;a href="https://github.com/luciangreen/Philosophy" rel="noopener noreferrer"&gt;Spec to Algorithm&lt;/a&gt;. Warning: do NOT program breasonings before the life-saving stage of writing or finding and breasoning them.&lt;/li&gt;
&lt;li&gt;Note 1. Thinking of aphors' parts is supposed to lead to breasonings, not replace them. For help calculating x, y and z dimensions from length ratios and a length, please run &lt;code&gt;Philosophy/text2aphors.pl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the co-op has already breasoned out the breasonings for the day, think of both 80 objects' or x, y and z dimensions for up to midnight and midnight on the first day.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>immortality</category>
      <category>quantum</category>
      <category>population</category>
    </item>
    <item>
      <title>Prototype Prolog Projects</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Tue, 09 Jul 2024 14:11:43 +0000</pubDate>
      <link>https://dev.to/luciangreen/prototype-prolog-projects-4kih</link>
      <guid>https://dev.to/luciangreen/prototype-prolog-projects-4kih</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2FPhilosophy%2Fassets%2F15845542%2Fc025fa54-5237-43b3-b5ec-4f7289107789" class="article-body-image-wrapper"&gt;&lt;img alt="Spec to Algorithm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2FPhilosophy%2Fassets%2F15845542%2Fc025fa54-5237-43b3-b5ec-4f7289107789" width="732" height="112"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2FPhilosophy%2Fassets%2F15845542%2F84097591-05bc-433c-989d-0fac55685568" class="article-body-image-wrapper"&gt;&lt;img alt="Ideas to Algorithm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2FPhilosophy%2Fassets%2F15845542%2F84097591-05bc-433c-989d-0fac55685568" width="648" height="354"&gt;&lt;/a&gt;&lt;br&gt;
Thousands of coloured blocks “partying” as popcorn as they transform from ideas to algorithms&lt;/p&gt;

&lt;p&gt;Mocking Up Elementary Parsers and Interpreters in Spec to Algorithm&lt;/p&gt;

&lt;p&gt;In Spec to Algorithm (S2A), creating easy parsers and interpreters is simple and efficient. By breaking down complicated expressions into manageable parts, S2A allows developers to generate algorithms speedily. For example, think of the instance &lt;code&gt;instance([1,1], [[is, [1+1]]])&lt;/code&gt;. Here, &lt;code&gt;instance&lt;/code&gt; is a function that takes inputs &lt;code&gt;[1,1]&lt;/code&gt; and computes the expression &lt;code&gt;[is, [1+1]] = 2&lt;/code&gt;. S2A parses this expression, identifies the operation &lt;code&gt;is&lt;/code&gt; (equality check), and performs the computation.&lt;/p&gt;

&lt;p&gt;This method can be extended to various parsing and interpretation jobs. Another instance could be &lt;code&gt;instances([[[1, 2], [[is, [1+2]]]],[[3, 4], [[is, [3+4]]]]])&lt;/code&gt;, and produces &lt;code&gt;C is A+B&lt;/code&gt; where &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt; are variables. S2A parses the input, assigns values to &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;C&lt;/code&gt;, and computes the sum of new inputs. Such strengths make S2A an outstanding tool for developers to mock up and test easy parsers and interpreters, streamlining the development process and improving productivity.&lt;/p&gt;

&lt;p&gt;S2A can break complex patterns into output, making algorithms out of decision trees to do it. For example, the following query returns the object given subject, verb (determiner), and object. Here, &lt;code&gt;off&lt;/code&gt; refers to not breaking items into characters, which would be helpful for recombining characters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spec_to_algorithm([[[input,[['A',[s,v,o]]]],[output,[['B',[o]]]]], [[input,[['A',[s,v,d,o]]]],[output,[['B',[o]]]]]], off,_).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This algorithm is saved as the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:-include('auxiliary_s2a.pl').
algorithm(In_vars,
Out_var) :-
findall(Var1,(member(Var, In_vars),
characterise1(Var, Var2),
strings_atoms_numbers(Var2, Var21),
term_to_brackets(Var21, Var1)
), In_vars1),
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the following, &lt;code&gt;T1_old&lt;/code&gt;, the training input is split into two non-deterministic (nd) branches for matching.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
T1_old=[[nd,[[[s,v,d,o],[output,[[o]]]],[[s,v,o],[output,[[o]]]]]]],
append(In_vars1,[[output,_]], In_vars3),
rs_and_data_to_term(T1_old, In_vars3,_,[], In_vars2,_T2_old, true),
double_to_single_brackets(In_vars2, In_vars21),
append(In_vars41,[[output, T2_old]], In_vars21),
double_to_single_brackets(In_vars41, In_vars4),
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the following line, the map is [[]] because there are no variables (from multiple specs) in the output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
member(Map2,[[]]),
double_to_single_brackets(T2_old, T2_old3),
move_vars(Map2, In_vars4, T2_old3,[], Out_var2),
findall(Out_var3,remove_nd(Out_var2, Out_var3), Out_var4),
member(Out_var5, Out_var4),
term_to_list(Out_var5, Out_var6),
[Out_var6]=Out_var.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following query converts Prolog code into terms and could form and calculate &lt;code&gt;B is (1+2)+3&lt;/code&gt; later. A and B are downcased in the Term Prolog form, to be converted to a and b afterwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spec_to_algorithm([[[input,[['A',["A is 1+2, B is A+3."]]]],[output,[['B',[[[+,[1,2,[lower,['A']]]],[+,[[lower,['A']],3,[lower,['B']]]]]]]]]]], off,_).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following excerpts from the generated algorithm show that the single spec is pattern-matched to the output. Again, there are no output variables to map, but if there were, they (for example, [A, B]-&amp;gt;A) would be mapped from (1,1) (item 1 of the second dimension or list level) to (1) (item 1 of the first list level).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;T1_old=[[["A is 1+2, B is A+3."],
[output,[["[","[",+,"[",1,2,"[", lower,"[", "A","]","]","]","]","[",+,"[","[", lower,"[", "A","]","]",3,"[", lower,"[", "B","]","]","]","]","]"]]]]],
...
member(Map2,[[]]),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lucian Green, Writer of &lt;a href="https://github.com/luciangreen/Philosophy/" rel="noopener noreferrer"&gt;Spec to Algorithm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Images: Spec to Algorithm Title in Input Mono Condensed Thin (fonts.adobe.com) and Ideas to Algorithm Image (Canva).&lt;/p&gt;

</description>
      <category>spec</category>
      <category>to</category>
      <category>algorithms</category>
      <category>prolog</category>
    </item>
    <item>
      <title>Introducing GitL - A Decentralised Git Server</title>
      <dc:creator>Lucian Green</dc:creator>
      <pubDate>Wed, 27 Sep 2023 14:35:51 +0000</pubDate>
      <link>https://dev.to/luciangreen/introducing-gitl-a-decentralised-git-server-1a34</link>
      <guid>https://dev.to/luciangreen/introducing-gitl-a-decentralised-git-server-1a34</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6zrzp5p6bes85iuyz84.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6zrzp5p6bes85iuyz84.jpg" alt="red-apple-1326760" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitL is a "Gitless" "Git" that resides on your computer and can upload repositories to your server. Written in Prolog, it isn't based on Git but has similar diff checking and version history. The advantage of GitL is that it is decentralised, genuinely open-source and costs nothing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It can run tests on the computer, saving time.&lt;/li&gt;
&lt;li&gt;Finished builds can be copied to a live folder close by.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git software can be developed and tested on one's computer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Walkthrough&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F06602f52-0fa5-4e9f-8a74-2f867a2cd9f9" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 17 29 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F06602f52-0fa5-4e9f-8a74-2f867a2cd9f9" width="978" height="1468"&gt;&lt;/a&gt;&lt;br&gt;
Figure 1. GitL Web Server shows two of three repositories have changed and allows selective bulk commits with descriptions of changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F1ad54cbc-eebc-41b8-ba4c-af54869d197a" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 17 38 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F1ad54cbc-eebc-41b8-ba4c-af54869d197a" width="482" height="86"&gt;&lt;/a&gt;&lt;br&gt;
Figure 2. Notification that two repositories were committed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F6a4f1737-ce9d-4f72-8365-0470d60144ca" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 18 42 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F6a4f1737-ce9d-4f72-8365-0470d60144ca" width="308" height="242"&gt;&lt;/a&gt;&lt;br&gt;
Figure 3. The &lt;code&gt;gitl_test&lt;/code&gt; folder contains the current repositories to commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F06447734-3d21-422c-a3e6-127f61426853" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 19 01 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F06447734-3d21-422c-a3e6-127f61426853" width="442" height="642"&gt;&lt;/a&gt;&lt;br&gt;
Figure 4. The &lt;code&gt;gitl_data&lt;/code&gt; folder contains the previous versions of repositories with HTML files showing changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F8fbd058b-765f-4eab-b664-1b27167e6c69" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 22 21 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F8fbd058b-765f-4eab-b664-1b27167e6c69" width="314" height="122"&gt;&lt;/a&gt;&lt;br&gt;
Figure 5. There is a password to protect files from being edited by unauthorised people in Web Editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2Febbf54ff-1cbc-4438-9a25-3374fbb9816e" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 22 35 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2Febbf54ff-1cbc-4438-9a25-3374fbb9816e" width="466" height="446"&gt;&lt;/a&gt;&lt;br&gt;
Figure 6. Web Editor starts in the &lt;code&gt;gitl_test&lt;/code&gt; (current repositories) folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F4710c982-fe76-4841-bb3a-c596b50037c4" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 22 44 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F4710c982-fe76-4841-bb3a-c596b50037c4" width="502" height="262"&gt;&lt;/a&gt;&lt;br&gt;
Figure 7. A screenshot of the &lt;code&gt;a.txt&lt;/code&gt; file in a repository in gitl_test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F472f9287-f7d2-4609-bed8-0bdcad5f9214" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 22 52 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F472f9287-f7d2-4609-bed8-0bdcad5f9214" width="224" height="144"&gt;&lt;/a&gt;&lt;br&gt;
Figure 8. Viewing the contents of &lt;code&gt;a.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F75fbb442-1aa2-4726-8586-647e193963f9" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 23 20 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F75fbb442-1aa2-4726-8586-647e193963f9" width="604" height="772"&gt;&lt;/a&gt;&lt;br&gt;
Figure 9. The gitl_data folder contains the previous versions of files and HTML files showing changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F7ddbae9d-c043-4bbd-bb0a-3b97310e2c9f" class="article-body-image-wrapper"&gt;&lt;img alt="Screenshot 2023-12-18 at 7 23 34 pm" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2Fgitl%2Fassets%2F15845542%2F7ddbae9d-c043-4bbd-bb0a-3b97310e2c9f" width="572" height="366"&gt;&lt;/a&gt;&lt;br&gt;
Figure 10. An example HTML file showing an insertion and a deletion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/luciangreen/gitl" rel="noopener noreferrer"&gt;https://github.com/luciangreen/gitl&lt;/a&gt;&lt;br&gt;
Image of apple by aleheredia (FreeImages.com)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2FLucian-Academy%2Fassets%2F15845542%2Fe1d3796a-c5a4-44ef-ba85-17584ed0f2ed" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fluciangreen%2FLucian-Academy%2Fassets%2F15845542%2Fe1d3796a-c5a4-44ef-ba85-17584ed0f2ed" alt="gl vecteezy com funforyou7" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image of "GL in digital clock font" by funforyou7 (vecteezy.com)&lt;/p&gt;

</description>
      <category>git</category>
      <category>decentralized</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
