Trivia Pattern Matching Compiler
repository·master·Indexed 18 days ago
https://github.com/guicho271828/triviaA pattern matching compiler for Common Lisp designed as a drop-in replacement for Optima. It includes the Trivia.Balland2006 optimizer, which reduces conditional tests through Fusion, Interleaving, and Swapping transformations. The library supports custom pattern definitions via `defpattern` and provides a configurable optimization system.
What's inside Trivia
- Swapping (IfSwapping) does not directly reduce the number of tests, but it reorders adjacent conditional blocks. This reordering is a prerequisite for the Fusion rule, allowing the optimizer to bring compatible blocks together so they can be merged.
How pattern matching optimization works in Trivia.Balland2006
masterTheTrivia.Balland2006implementation focuses on reducing the number of conditional checks (tests) in pattern matching compilation, as these often involve costly function calls. While the original Balland (2006) paper also addresses assignment optimization (like Constant Propagation or Let-Fusion), this implementation skips those because modern Common Lisp implementations (SBCL, CCL) handle them automatically. Instead, it focuses on three primary transformation rules: Fusion, Interleaving, and Swapping.Fusion: Merging common type checks
masterFusion reduces redundant tests by identifying common checks across different match clauses. If multiple clauses share a common predicate (e.g., both check if a variable is a
cons), the optimizer merges these into a single check and then uses a nestedmatch*to handle the specific differences in the subsequent branches.;; Original: Two clauses both checking (consp it) (match1 what ((guard1 it (consp it) (car it) (guard1 x (= 1 x)) (cdr it) (guard1 y (null y))) body1) ((guard1 it (consp it) (car it) (guard1 x (stringp x)) (cdr it) (guard1 y (null y))) body2)) ;; Optimized: One (consp it) check, then nested match* (match what ((guard1 it (consp it) (car it) #:car (cdr it) #:cdr) (match* (#:car #:cdr) (((guard x (= 1 x)) (guard y (null y))) body1) (((guard x (stringp x)) (guard y (null y))) body2))))Interleaving: Reducing tests via exhaustive partitions
masterInterleaving optimizes matches when the predicates form an exhaustive partition of a type. For example, if a variable is known to be a
list, and the clauses check forconsandnull, the optimizer can replace the second check with a wildcard_because if it isn't acons, it must benull.;; Original: Explicitly checking both cons and null (match1 what ((guard1 it (consp it)) body1) ((guard1 it (null it)) body2)) ;; Optimized: Using a wildcard for the exhaustive case (match1 what ((guard1 it (consp it)) body1) (_ body2))Run Trivia tests and benchmarks
masterYou can execute the system's test suite and benchmark suite using ASDF commands.
To run tests:
(asdf:test-system :trivia)To run benchmarks:
(asdf:test-system :trivia.benchmark)Use Trivia as a drop-in replacement for Optima
masterTrivia is a pattern matching compiler compatible with Optima. It is designed to act as a drop-in replacement for 99% of Optima's usage, often providing better performance. To switch from Optima to Trivia, update your package definition to use
:triviainstead of:optima.(defpackage :playwithit (:use :cl :trivia)) ; Changed from :optima (in-package :playwithit) (match '(something #(0 1 2)) ((list a (vector 0 _ b)) (values a b))) ;; --> SOMETHING, 2Configure the Trivia optimizer
masterThe Balland2006 optimizer is the default. However, you can specify a different optimizer in the lexical environment using a
declareform with thetrivia:optimizerkeyword.(declare (trivia:optimizer :trivial))Debug optimization with *trace-optimization*
masterThe*trace-optimization*flag can be used to enable debug printing during the fusing and grounding operations of the optimizer. This is useful for inspecting how pattern matching rules are being applied.*trace-optimization*Define custom patterns with `defpattern`
masterTrivia is highly extensible. You can use
defpatternto implement your own patterns. Trivia'sdefpatternis powerful enough to implement the entire unmodifiable core pattern language of Optima within itself.(defpattern cons (a b) (with-gensyms (it) `(guard1 (,it :type cons) (consp ,it) (car ,it) ,a (cdr ,it) ,b)))