icp-dag-crystallizer / src /lattice-kernel /lattice_kernel.pl
SNAPKITTYWEST's picture
Relicense under the Sovereign Leviathan covenant; remove MIT and Apache
055a27e verified
Raw History Blame Contribute Delete
8.78 kB
%% SPDX-License-Identifier: LicenseRef-Sovereign-Leviathan-SL-AGPL3-001
%% CLONE_GATE: lattice_kernel_pl
%%
%% lattice_kernel.pl — Relational Lattice Kernel (ISO Prolog)
%%
%% Same relations as mu_kanren.scm as portable ISO predicates.
%% Optional CLP(FD) adder via use_module(library(clpfd)).
%% Compatible with SWI-Prolog, GNU Prolog, SICStus.
%%
%% Run: swipl -s lattice_kernel.pl
%% ?- demo.
:- use_module(library(lists)).
%% ============================================================
%% 1. LIST RELATIONS
%% ============================================================
conso(A, D, [A|D]).
nullo([]).
caro([A|_], A).
cdro([_|D], D).
pairo([_|_]).
listo([]).
listo([_|D]) :- listo(D).
appendo([], S, S).
appendo([A|D], S, [A|R]) :- appendo(D, S, R).
membero(X, [X|_]).
membero(X, [_|T]) :- membero(X, T).
rembero(_, [], []).
rembero(X, [X|D], D) :- !.
rembero(X, [A|D], [A|R]) :- X \= A, rembero(X, D, R).
reverseo(L, O) :- rev_acco(L, [], O).
rev_acco([], Acc, Acc).
rev_acco([A|D], Acc, O) :- rev_acco(D, [A|Acc], O).
lengtho([], z).
lengtho([_|D], s(N)) :- lengtho(D, N).
distincto([]).
distincto([A|D]) :- \+ member(A, D), distincto(D).
permuteo([], []).
permuteo([A|D], O) :-
permuteo(D, R),
inserto(A, R, O).
inserto(X, L, [X|L]).
inserto(X, [A|D], [A|R]) :- inserto(X, D, R).
zipo([], [], []).
zipo([A|DA], [B|DB], [[A,B]|R]) :- zipo(DA, DB, R).
takeo(0, _, []) :- !.
takeo(s(N), [A|D], [A|R]) :- takeo(N, D, R).
dropo(0, L, L) :- !.
dropo(s(N), [_|D], O) :- dropo(N, D, O).
filtero(_, [], []).
filtero(P, [A|D], Out) :-
( call(P, A) ->
filtero(P, D, R), Out = [A|R]
; filtero(P, D, Out)
).
%% ============================================================
%% 2. PEANO ARITHMETIC
%% ============================================================
zeroo(z).
succo(N, s(N)).
nato(z).
nato(s(N)) :- nato(N).
addo(z, Y, Y).
addo(s(X), Y, s(Z)) :- addo(X, Y, Z).
mulo(z, _, z).
mulo(s(X), Y, Z) :-
mulo(X, Y, Z1),
addo(Y, Z1, Z).
leq_nato(z, _).
leq_nato(s(X), s(Y)) :- leq_nato(X, Y).
%% ============================================================
%% 3. BIT ARITHMETIC — FULL ADDER
%% ============================================================
bito(0).
bito(1).
half_addo(0, 0, 0, 0).
half_addo(0, 1, 1, 0).
half_addo(1, 0, 1, 0).
half_addo(1, 1, 0, 1).
full_addo(A, B, Cin, S, Cout) :-
bito(A), bito(B), bito(Cin),
half_addo(A, B, W, C1),
half_addo(W, Cin, S, C2),
( C1 =:= 1 ; C2 =:= 1 -> Cout = 1 ; Cout = 0 ).
%% CLP(FD) adder (loaded conditionally)
:- ( catch(use_module(library(clpfd)), _, true) ->
assert(clpfd_available)
; true
).
full_addo_clp(A, B, Cin, S, Cout) :-
clpfd_available, !,
[A, B, Cin, S, Cout] ins 0..1,
S #= (A + B + Cin) mod 2,
Cout #= (A + B + Cin) // 2.
full_addo_clp(A, B, Cin, S, Cout) :-
full_addo(A, B, Cin, S, Cout).
%% n-bit ripple-carry adder
addero([], [], [], Cin, Cin).
addero([A|As], [B|Bs], [S|Ss], Cin, Cout) :-
full_addo(A, B, Cin, S, Cmid),
addero(As, Bs, Ss, Cmid, Cout).
%% ============================================================
%% 4. RELATIONAL INTERPRETER (evalo)
%% ============================================================
:- dynamic edb/3, edb/4, fsm_transition/5.
lookupo(X, [[X,V]|_], V) :- !.
lookupo(X, [[Y,_]|Rest], V) :-
X \= Y,
lookupo(X, Rest, V).
eval_expro(quote(Q), _, Q).
eval_expro(X, Env, V) :-
atom(X), \+ X = quote, \+ X = lambda, \+ X = cons,
\+ X = car, \+ X = cdr, \+ X = if, \+ X = 'null?',
lookupo(X, Env, V).
eval_expro(lambda(P, B), Env, closure(P, B, Env)).
eval_expro(app(Rator, Rand), Env, V) :-
eval_expro(Rator, Env, Clo),
eval_expro(Rand, Env, Arg),
applyo(Clo, Arg, V).
eval_expro(cons(A, D), Env, [VA|VD]) :-
eval_expro(A, Env, VA),
eval_expro(D, Env, VD).
eval_expro(car(E), Env, V) :-
eval_expro(E, Env, [V|_]).
eval_expro(cdr(E), Env, V) :-
eval_expro(E, Env, [_|V]).
eval_expro(if(C, T, El), Env, V) :-
eval_expro(C, Env, CV),
( CV \= false -> eval_expro(T, Env, V)
; eval_expro(El, Env, V)
).
applyo(closure(P, B, Env), Arg, V) :-
eval_expro(B, [[P,Arg]|Env], V).
evalo(Exp, Val) :- eval_expro(Exp, [], Val).
%% ============================================================
%% 5. SMT STUB
%% ============================================================
smt_and(A, B, and(A, B)).
smt_not(A, not(A)).
smt_var(N, var(N)).
is_sat(Phi) :-
collect_atoms(Phi, [], Atoms),
\+ contradiction(Atoms).
collect_atoms(and(A, B), Acc, Out) :- !,
collect_atoms(A, Acc, Acc1),
collect_atoms(B, Acc1, Out).
collect_atoms(X, Acc, [X|Acc]).
contradiction(Atoms) :-
member(not(P), Atoms),
member(P, Atoms).
%% ============================================================
%% 6. EDB FACT STORE
%% ============================================================
assert_edb(Rel, A, B) :- assertz(edb(Rel, A, B)).
assert_edb(Rel, A, B, C) :- assertz(edb(Rel, A, B, C)).
factso(Rel, A, B) :- edb(Rel, A, B).
factso(Rel, A, B, C) :- edb(Rel, A, B, C).
%% ============================================================
%% 7. PARAMETERIZED PATH / REACHABILITY
%% ============================================================
%% patho(+Rel, +X, ?Y, -Path, -Phi)
patho(Rel, X, Y, path(Y), Phi) :-
factso(Rel, X, Y, Phi),
is_sat(Phi).
patho(Rel, X, Y, path(Z, P), and(E, Phi2)) :-
factso(Rel, X, Z, E),
is_sat(E),
patho(Rel, Z, Y, P, Phi2).
reacho(_, S, S).
reacho(Rel, S, T) :-
edb(Rel, S, M),
reacho(Rel, M, T).
%% ============================================================
%% 8. FSM RELATIONS
%% ============================================================
register_fsm(Id) :-
assertz(fsm_transition(Id, s0, 0, s0, 0)),
assertz(fsm_transition(Id, s0, 1, s1, 0)),
assertz(fsm_transition(Id, s1, 0, s0, 1)),
assertz(fsm_transition(Id, s1, 1, s1, 1)).
fsmo(Id, St, Inp, Nst, Out) :-
fsm_transition(Id, St, Inp, Nst, Out).
%% fsm_traceo(+Id, +S0, +Inputs, -Outputs)
fsm_traceo(_, _, [], []).
fsm_traceo(Id, S, [I|Rest], [O|RestO]) :-
fsmo(Id, S, I, S1, O),
fsm_traceo(Id, S1, Rest, RestO).
%% ============================================================
%% 9. REFINEMENT LATTICE
%% ============================================================
refineo(conc(C), C, refined).
refineo(top, _, refined).
refineo(interval(Lo, Hi), N, refined) :-
leq_nato(Lo, N),
leq_nato(N, Hi).
refineo_nat(conc(C), C).
refineo_nat(top, _).
refineo_nat(interval(Lo, Hi), N) :-
integer(Lo), integer(Hi), integer(N),
Lo =< N, N =< Hi.
%% ============================================================
%% 10. HIGHER-ORDER LIST OPERATIONS
%% ============================================================
mapo(_, [], []).
mapo(Goal, [A|D], [B|R]) :-
call(Goal, A, B),
mapo(Goal, D, R).
foldo(_, [], Acc, Acc).
foldo(Goal, [A|D], Acc, Out) :-
call(Goal, A, Acc, NAcc),
foldo(Goal, D, NAcc, Out).
%% ============================================================
%% 11. SEED DATA
%% ============================================================
seed_db :-
retractall(edb(_, _, _)),
retractall(edb(_, _, _, _)),
retractall(fsm_transition(_, _, _, _, _)),
assert_edb(edge, 0, 1, bv_slt(var(x), var(y))),
assert_edb(edge, 1, 2, bv_slt(var(y), var(z))),
assert_edb(edge, 2, 3, and(var(p), not(var(q)))),
assert_edb(edge, 0, 2),
assert_edb(edge, 1, 3),
register_fsm(fsm0).
%% ============================================================
%% 12. DEMO / SMOKE TEST
%% ============================================================
demo :-
seed_db,
format('=== lattice_kernel.pl ===~n'),
format('~nappendo([1,2],[3],?): '),
findall(Q, appendo([1,2],[3],Q), R1),
format('~w~n', [R1]),
format('addo(s(z),s(s(z)),?): '),
findall(Q, addo(s(z),s(s(z)),Q), R2),
format('~w~n', [R2]),
format('full_addo(1,1,0,S,C): '),
findall(S-C, full_addo(1,1,0,S,C), R3),
format('~w~n', [R3]),
format('evalo: '),
findall(V, evalo(app(lambda(x,x),quote(hello)),V), R4),
format('~w~n', [R4]),
format('reacho from 0: '),
findall(T, reacho(edge,0,T), R5),
sort(R5, R5s),
format('~w~n', [R5s]),
format('fsm_traceo [0,1,0]: '),
findall(O, fsm_traceo(fsm0,s0,[0,1,0],O), R6),
format('~w~n', [R6]),
format('refineo interval: '),
findall(R, refineo(interval(s(z),s(s(s(z)))),s(s(z)),R), R7),
format('~w~n', [R7]),
format('is_sat true: '),
( is_sat(and(var(p), not(var(q)))) -> format('sat~n') ; format('unsat~n') ),
format('is_sat contradiction: '),
( is_sat(and(var(p), not(var(p)))) -> format('sat~n') ; format('unsat~n') ),
format('~n=== COMPLETE ===~n').
:- initialization(demo, main).