Skip to main content

Active logic meets Prolog — three-valued reasoning engine

Project description

Proact

Prolog has two truth values: succeed and fail. Proact adds a third: contwork/reasoning in progress.

Every goal returns a status. Conjunction is a sequence. Disjunction is a selector. Backtracking only triggers on failure — cont and done cut the search. Between ticks, queries returning cont are automatically re-evaluated while the database persists, giving you a stateless tick loop for free.

Applications:

  • Reasoning under uncertainty. The three values map onto epistemic states: verified, undetermined, refuted. A conjunction of checks naturally implements iterative deepening — work focuses on the earliest unresolved premise. Unary operators give you cognitive control: demote means "don't commit yet" (done→cont); promote means "don't give up yet" (fail→cont). This is relevant to validation layers for LLM reasoning, where forcing every check into true/false is lossy compression of the actual epistemic state.

  • Behavior modeling. Reactive agents, planners, robot controllers — anything where logic meets time. Prolog gives you unification, backtracking, and pattern matching. Active logic adds temporal flow. You get behavior trees with the expressiveness of logic programming, without the trees.

Install

pip install git+https://github.com/eelstork/proact.git

Requires a C compiler (gcc, clang, or MSVC).

from proact import Proact

p = Proact()
p.add("mortal(X) :- human(X). human(socrates).")
print(p.query("mortal(socrates)"))  # Result(status='done')

Tutorials

Build

make

Usage

./proact                          # REPL
./proact file.pa                  # consult file, then REPL
./proact file.pa -e "goal."      # evaluate goal and exit
./proact --max-ticks 100 -e "g." # limit tick count

The Transform

Conjunction (,) — Active logic AND / Sequence

         fail  cont  done
  fail   fail  fail  fail
  cont   cont  cont  cont
  done   fail  cont  done

If the left goal is cont, the whole conjunction is cont — don't evaluate the right side yet.

Disjunction (;) — Active logic OR / Selector

         fail  cont  done
  fail   fail  cont  done
  cont   cont  cont  cont
  done   done  done  done

If the left goal is done or cont, don't try alternatives.

Clause resolution

Multiple clauses for the same predicate provide choice points. Backtracking occurs only on fail — if a clause body returns cont or done, stop searching.

Tick loop

Queries returning cont are automatically re-evaluated on the next tick with a fresh environment. The database (asserted facts) persists between ticks.

Built-ins

Predicate Status Description
done / true done Always succeeds
fail / false fail Always fails
cont cont Always continues
inv(G) / \+ G swap done/fail, keep cont Inverter
condone(G) fail→done Forgive failure
promote(G) fail→cont, cont→done Optimistic
demote(G) done→cont, cont→fail Pessimistic
par_any(A,B) max(A,B) Lenient parallel
par_all(A,B) min(A,B) Strict parallel
tick(N) done Unify N with current tick

Plus standard Prolog: write/1, writeln/1, nl, assert/1, retract/1, is/2, =/2, \=/2, </2, >/2, >=/2, =</2, call/1, consult/1.

Examples

Wait N ticks, then succeed

wait(N) :- tick(T), T >= N.
wait(N) :- tick(T), T < N, cont.
?- wait(3), writeln(hello).
[tick 0] cont
[tick 1] cont
[tick 2] cont
hello
done.

Counter (stateful, using assert/retract)

:- assert(count(0)).

count_to(Target) :- count(N), N >= Target.
count_to(Target) :-
    count(N), N < Target,
    retract(count(N)), N1 is N + 1, assert(count(N1)),
    cont.

Reactive behavior (condition-gated sequence)

:- assert(agent_pos(0)).

move_to(X) :- agent_pos(P), P =:= X.
move_to(X) :- agent_pos(P), P < X,
    retract(agent_pos(P)), P1 is P + 1, assert(agent_pos(P1)), cont.

patrol :-
    agent_pos(P), P < 3, move_to(3), cont.
patrol :-
    agent_pos(P), P >= 3, P < 5, move_to(5), cont.
patrol :-
    agent_pos(P), P >= 5.

Reasoning under uncertainty

% reason.pa — three-valued validation for multi-step arguments

:- assert(known(premise_a)).
:- assert(investigation(premise_b, 2)).
:- assert(investigation(premise_c, 1)).

check(P) :- known(P).
check(P) :- known_false(P), fail.
check(P) :-
    investigation(P, N), N > 0,
    retract(investigation(P, N)), N1 is N - 1,
    (N1 > 0 -> assert(investigation(P, N1)) ; assert(known(P))),
    cont.

argument :- check(premise_a), check(premise_b), check(premise_c).

The conjunction is the search strategy — it focuses work on the earliest unresolved premise and doesn't waste computation on steps whose preconditions haven't been met:

[tick 0] a=done, b=cont          → cont  (c never reached)
[tick 1] a=done, b=done, c=cont  → cont  (work shifts to c)
[tick 2] a=done, b=done, c=done  → done

The epistemic operators give cognitive control over the validation:

cautious(X)       :- demote(check(X)).    % "verified but needs review"  (done→cont)
keep_exploring(X) :- promote(check(X)).   % "refuted but try harder"     (fail→cont)
viable_theory     :- par_any(hyp_a, hyp_b). % first hypothesis verified wins

Relation to active-logic

This prototype implements the core operators from activelogic-cs in a logic programming context:

C# (activelogic-cs) Proact BT equivalent
status && status Goal, Goal Sequence
status || status Goal ; Goal Selector
+ (lenient) par_any(A, B) Parallel (any)
* (strict) par_all(A, B) Parallel (all)
!status inv(G) Inverter
~status condone(G) Condone
+status (unary) promote(G) Promoter
-status (unary) demote(G) Demoter
cont cont Running

The key addition over Prolog is cont — a single built-in that bridges logic programming with reactive, tick-based behavior.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proact_py-0.1.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

proact_py-0.1.0-py3-none-win_amd64.whl (100.9 kB view details)

Uploaded Python 3Windows x86-64

proact_py-0.1.0-cp311-cp311-win_amd64.whl (100.9 kB view details)

Uploaded CPython 3.11Windows x86-64

File details

Details for the file proact_py-0.1.0.tar.gz.

File metadata

  • Download URL: proact_py-0.1.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for proact_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 df75099415ceaf942327555a0b28bb8ed5dc6c76529be8df65ee1cc1ec5dcac0
MD5 74de37fcb09600c9dee5dcc32f195839
BLAKE2b-256 0c95baf12f778aa955509fe65e3b698595419708316cfa3fcad335b254700b2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for proact_py-0.1.0.tar.gz:

Publisher: release.yml on eelstork/proact

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proact_py-0.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: proact_py-0.1.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 100.9 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for proact_py-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 b2cca34cf6c331594a27999f70b958309d9576155fb041c4262a3c94c9292f91
MD5 da7e9fce5aa81823a714d816884dbb59
BLAKE2b-256 0f9dc289c3f23062f0ff2e34c20a49078476bf9478e6e5fecb31927de6b7e017

See more details on using hashes here.

Provenance

The following attestation bundles were made for proact_py-0.1.0-py3-none-win_amd64.whl:

Publisher: release.yml on eelstork/proact

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proact_py-0.1.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: proact_py-0.1.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 100.9 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for proact_py-0.1.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 35922e93ffd162529602e3603b01fa27665e8c0514dd36e4bb7db0676582048a
MD5 78120138b8acd1ea05aa2df08839507b
BLAKE2b-256 53b84c6606428aac030573cc81595973c78d651400c2d4141e4ebfeed14c59d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for proact_py-0.1.0-cp311-cp311-win_amd64.whl:

Publisher: release.yml on eelstork/proact

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page