Skip to content

Instantly share code, notes, and snippets.

@GeoffChurch
GeoffChurch / derive_accessors.pl
Created August 17, 2024 21:24
Prolog getters, setters, mutators using term_expansion
user:term_expansion((:- derive_accessors(ClassTemplate)), Clauses) :-
ClassTemplate =.. [ClassName|Fields],
functor(ClassTemplate, ClassName, Arity),
functor(Skel, ClassName, Arity),
term_variables(Skel, Vars),
foldl(build_accessors(Skel), Fields, Vars, [], Clauses).
return(G), [Ret] --> { call(G, Ret) }.
build_accessors(Skel, Field, Var) -->
@GeoffChurch
GeoffChurch / speculative_if.py
Created May 7, 2024 01:53
Speculative execution on both branches of a conditional
"""
Provides speculative_if(cond, branch1, branch2), which runs branch1 followed by
branch2 while cond is running.
"""
from dataclasses import dataclass
import itertools
import multiprocessing as mp
import time
:- op(700, xfx, .=).
A:AFs .= B:BFs =>
gets(AFs, A, Val),
gets(BFs, B, Val).
X:Fs .= Val => gets(Fs, X, Val).
Val .= X:Fs => gets(Fs, X, Val).
A .= B => A = B.
colon_list(X:Xs0, Out) => colon_list(Xs0, Xs), Out = [X|Xs].
@GeoffChurch
GeoffChurch / mi_dcg.pl
Last active January 26, 2024 15:18
SWI-Prolog-compatible DCG-ification of Power of Prolog's 'mi_list3' (www.metalevel.at/acomip/)
% The following is a 3-line meta-interpreter for pure Prolog (no
% cuts/negation). It reifies conjunction and dispatch, leaving
% unification and backtracking implicit. It is written for brevity,
% leveraging DCG notation and using lists to denote conjunctions of
% goals. It implements the semantics of a program (in the sense of a
% set of rules or "immediate consequence operator") as the program's
% least fixed point, obtained by "reflexive transitive closure" /
% exponential / "Kleene iteration".
%%%%%
@GeoffChurch
GeoffChurch / rule30_animation.py
Last active May 14, 2023 23:03
Wolfram's "rule 30" cellular automaton. Read it, download it, and then execute `python rule30_animation.py` from your terminal in the same directory.
from os import get_terminal_size
from time import sleep
terminal_size = get_terminal_size()
num_cells = terminal_size.columns # We'll have as many cells as can fit in the terminal's width
sleep_time = 4.0 / terminal_size.lines # Animation speed will be proportional to the terminal's height
# Lookup table for Wolfram's "rule 30" cellular automaton
RULE_30 = {
(0,0,0) : 0,
@GeoffChurch
GeoffChurch / cata.pl
Last active May 16, 2023 18:22
Declarative catamorphism with meta-language escapes which can be used e.g. to solve for variable bindings in the codomain.
unescape(\X, X). % Subterms, and in particular logic variables, can be marked as pre-evaluated.
cata(Alg) --> unescape *-> {} ; mapargs(cata(Alg)), call(Alg).
% Example:
alg( 0 + 0, 0).
alg( 0 + 1, 1).
alg( 1 + 0, 1).
alg( 1 + 12, 13).
foldargs(Goal, A, B) -->
{ maplist(functor_arity_term_args(_, _), [A, B], [As, Bs]) },
foldl(Goal, As, Bs).
functor_arity_term_args(Functor, Arity, Term, Args) :-
functor(Term, Functor, Arity),
Term =.. [_|Args].
@GeoffChurch
GeoffChurch / unifier.pl
Created June 16, 2022 21:11
Like SWI Prolog's unifiable/3, but maintains the left-right order of the terms in the unifier, rather than placing variables on the left.
%! unifier(@Term1, @Term2, ?Unifier) is semidet.
%
% Like SWI Prolog's unifiable/3, but maintains the left-right order of the terms in the unifier, rather than placing variables on the left.
unifier(A, B, Unifier) :-
rb_empty(Seen),
unifier_(Seen, A, B, [], Unifier0),
exclude(unifier_is_reflexive, Unifier0, Unifier1),
sort(Unifier1, Unifier).
unifier_(Seen0, A, B, Unifier0, Unifier) :-
copy_term(VarsIn, In, VarsOut, Out) :-
term_variables(In, AllVarsIn),
maplist(list_to_ord_set, [AllVarsIn, VarsIn], [AllVarsInOrdSet, VarsInOrdSet]),
ord_subtract(AllVarsInOrdSet, VarsInOrdSet, PreservedVars),
copy_term(PreservedVars-VarsIn-In, PreservedVars-VarsOut-Out).
@GeoffChurch
GeoffChurch / reif_dcg.pl
Last active March 23, 2022 14:49
Reified DCG utils
:- use_module(library(reif)).
phrase_t(P, I, O, T) :- phrase(call(P, T), I, O).
if_(If, Then, Else, I, O) :-
if_(phrase_t(If, I, M),
phrase(Then, M, O),
phrase(Else, M, O)).
% Example: