I've recently been amazed, if not mind-blown, by how a very simple, "one-line" SAT solver on Interaction Nets can outperform brute-force by orders of magnitude by exploiting "superposed booleans" and optimal evaluation of λ-expressions. In this brief note, I'll provide some background for you to understand how this works, and then I'll present a simple code you can run in your own computer to observe and replicate this effect. Note this is a new observation, so I know little about how this algorithm behaves asymptotically, but I find it quite
// A nano dependent type-checker featuring inductive types via self encodings. | |
// All computation rules are justified by interaction combinator semantics, | |
// resulting in major simplifications and improvements over old Kind-Core. | |
// Specifically, computable annotations (ANNs) and their counterpart (ANN | |
// binders) and a new self encoding based on equality (rather than dependent | |
// motives) greatly reduce code size. A more complete file, including | |
// superpositions (for optimal unification) is available on the | |
// Interaction-Type-Theory repository. | |
// Credits also to Franchu and T6 for insights. |
Every once in a while I investigate low-level backend options for PL-s, although so far I haven't actually written any such backend for my projects. Recently I've been looking at precise garbage collection in popular backends, and I've been (like on previous occasions) annoyed by limitations and compromises.
I was compelled to think about a system which accommodates precise relocating GC as much as possible. In one extreme configuration, described in this note, there
This is a minimalistic OCaml implementation of the type system from chapter 30 of TAPL, "Higher-Order Polymorphism".
The implementation uses bidirectional typing and does not feature existential types. Binders are represented as metalanguage functions (HOAS-style); free variables (TyFreeVar
& FreeVar
) are represented as De Bruijn levels.
See also:
type cps_var = | |
(* Taken from the lambda term during CPS conversion. *) | |
| CLamVar of string | |
(* Generated uniquely during CPS conversion. *) | |
| CGenVar of int | |
type cps_term = | |
| CFix of (cps_var * cps_var list * cps_term) list * cps_term | |
| CAppl of cps_var * cps_var list | |
| CRecord of cps_var list * binder |
(* A variable identifier of the lambda language [term]. *) | |
type var = string [@@deriving eq] | |
(* The lambda language; direct style. *) | |
type term = | |
| Var of var | |
| Fix of (var * var list * term) list * term | |
| Appl of term * term list | |
| Record of term list | |
| Select of term * int |
namespace ADTs | |
/- | |
In the game we have two banks of a river: left and right, | |
and four characters: a wolf, a goat, a cabbage, and a farmer. | |
The farmer prevents abybody from eathing anything, otherweise | |
the wolf eats the goat, or the goat eats the cabbage. | |
The game starts with all the characters on the left bank and | |
the goal is to move everyone to the right bank safe and sound. | |
The farmer can carry a single other character at a time |
{-# language BlockArguments, LambdaCase, Strict, UnicodeSyntax #-} | |
{-| | |
Minimal dependent lambda caluclus with: | |
- HOAS-only representation | |
- Lossless printing | |
- Bidirectional checking | |
- Efficient evaluation & conversion checking | |
Inspired by https://gist.github.com/Hirrolot/27e6b02a051df333811a23b97c375196 |
type term = | |
| Lam of (term -> term) | |
| Pi of term * (term -> term) | |
| Appl of term * term | |
| Ann of term * term | |
| FreeVar of int | |
| Star | |
| Box | |
let unfurl lvl f = f (FreeVar lvl) |