Skip to content

Instantly share code, notes, and snippets.

@GeoffChurch
GeoffChurch / subgroup_lattice.sage
Last active January 19, 2022 16:30
Plot subgroup lattice with short labels and normal subgroups highlighted. Works with Sage 9.2, Python 3.9.5
def relabel(xs, f):
clazz = type(xs[0])
new_clazz = type(f"{clazz}_relabeled", (clazz,), {"__str__" : f})
for x in xs:
x.__class__ = new_clazz
def norms_abnorms(subgroups, G):
norms = []
abnorms = []
for s in subgroups:
@GeoffChurch
GeoffChurch / mi_dcg.pl
Last active February 25, 2022 19:47
DCG-ification of mi_list3 from Power of Prolog chapter on meta-interpreters
mi_dcg_clause, [] --> [natnum(0)].
mi_dcg_clause, [natnum(X)] --> [natnum(s(X))].
mi_dcg_clause, [always_infinite] --> [always_infinite].
mi_dcg --> [].
mi_dcg --> mi_dcg_clause, mi_dcg.
%% Original version from https://www.metalevel.at/acomip/ :
mi_ldclause(natnum(0), Rest, Rest).
@GeoffChurch
GeoffChurch / npda_palindrome.pl
Created March 6, 2022 03:37
Nondeterministic pushdown automaton interpreter adapted from Art of Prolog 2e, Ch 17
accept(DCG, Xs) :-
call(DCG, initial, Q),
accept(DCG, Q, Xs, []).
accept(DCG, Q, [], []) :-
call(DCG, final, Q).
accept(DCG, Q, [X|Xs], S) :-
call(DCG, delta, Q, X, S, Q1, S1),
accept(DCG, Q1, Xs, S1).
@GeoffChurch
GeoffChurch / double_negation_elimination.hs
Last active March 22, 2022 20:24
Double negation elimination in Haskell assuming universe of only 2 types: () and Void
import Data.Void ( Void )
dneFalse :: ((Void -> Void) -> Void) -> Void
dneFalse f = f id
dneTrue :: ((() -> Void) -> Void) -> ()
dneTrue _ = ()
@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:
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 / 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) :-
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 / 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).
@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,