• Stars
    star
    179
  • Rank 214,039 (Top 5 %)
  • Language
    Haskell
  • License
    BSD 3-Clause "New...
  • Created almost 9 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

a collection of cellular automata written in Haskell with Diagrams

Cellular Automata

Pretty cellular automata in Haskell. The aim is to have most Cellular Automata implemented in this package so it can serve as a reference / library to write Cellular Automata.

1. Game of Life

game-of-life-gif

Ruleset
stepCell :: Grid -> Cell
stepCell grid = 
    cell'
    where
        cell' = if numNeighbours > 3 then Off
                else if numNeighbours < 2 then Off
                else if cell == Off && numNeighbours == 3 then On
                else cell
        cell = extract grid 
        numNeighbours = liveNeighbourCount $ grid

2. Seeds

seeds-gif

Ruleset
stepCell :: Grid -> Cell
stepCell grid = 
    cell'
    where
        cell' = if numNeighbours == 2 then On
                else Off
        numNeighbours = liveNeighbourCount $ grid

3. Brian's brain

brians-brain-gif

Ruleset
stepCell :: Grid -> Cell
stepCell grid = 
    cell'
    where
        cell' = if cell == Off && numNeighbours == 2 then On
                else if cell == On then Dying
                else Off
        cell = extract grid 
        numNeighbours = liveNeighbourCount $ grid

3. 1D cyclic Cellular Automata

1d-cyclic.gif

Ruleset
stepCell :: Simulation -> Cell
stepCell s =
    cell'
    where
        cell = extract s 
        cell' = if hasNextNeighbour (getRingZipperNeighbours s)
           then Cell { value = (Cyclic1D.value cell + 1) `mod` (total cell), total = total cell}
           else cell
        hasNextNeighbour neighbours = any (\c -> Cyclic1D.value c == ((Cyclic1D.value cell) + 1) `mod` (total cell)) neighbours

4. 2D cyclic Cellular Automata

2d-cyclic.gif

Ruleset
stepCell :: Grid -> Cell
stepCell s =
    cell'
    where
        cell = extract s 
        cell' = if hasNextNeighbour (getUnivNeighbours s)
           then Cell { val = (val cell + 1) `mod` (total cell), total = total cell}
           else cell
        hasNextNeighbour neighbours = any (\c -> val c == ((val cell) + 1) `mod` (total cell)) neighbours

More to encode

https://qlfiles.net/the-ql-files/next-nearest-neighbors-cellular-automata

Design

This is an exploration of the Haskell design space to create Cellular Automata.

I finally settled on using Comonads to represent the grid space of the cellular automata. The difference between this implementation and many others in the wild is that this one has a finite grid, which makes writing the instances for Zipper and Comonad harder.

This will be refactored into a library that allows one to create cellular automata by simply specifying the ruleset and the way to draw a single cell. The library will extrapolate the data to allow rendering the entire grid.

Contributing

Please send a PR to create more Cellular Automata by using an existing cellular automata file (for example, Seeds(https://github.com/bollu/cellularAutomata/blob/master/src/Seeds.hs)).

If someone knows how to make GIF rendering faster, that would be of great help as well!

As a college student, I write code for passion projects like this on my free time. If you want to support me to see more stuff like this, please

Support via Gratipay

Theory

Motivating Comonads

As stated before, this simulation uses the Comonad typeclass to model cellular automata. There are multiple ways of looking at this algebra, and one way to think of them is a structure that can automatically convert "global-to-local" transforms into "global-to-global" transforms.

For example, in a cellular automata, the "global-to-local" transformation is updating the state of one Cell by reading the cell's neighbours. The neighbour state is the global state, which is used to update the local state of the cell. This can be thought of as the type

Grid -> Cell

where Grid is the grid in which the cellular automata is running, and Cell is the new state of the cell. However, the question that immediately arises is - which cell? the answer is that, the Grid not only encodes the state of the cellular automata, but also a focused cell which is updated.

The Grid is not just a grid, it is a grid with a cell that it is targeted on. However, this seems ridiculous, since we have simply added extra complexity (that of focusing on a particular cell) with zero gains in benefit.

The nice part of a Comonad is that if we have a structure that knows how to do a "focused update", the Comonad enables us to extend this to the entire structure. Written in types, it is along the lines of

Grid -> (Grid -> Cell) -> Grid

If we think of grid as a container of cells (or as a functor w), this gives us the new type

Grid -> (Grid -> Cell) -> Grid
-- replace Grid with w Cell
w Cell -> (w Cell -> Cell) -> w Cell
-- replace Cell with type variable a
w a -> (w a -> a) -> w a
-- generalize type even further, by allowing the
-- output type to differ
-- (this is shown to be possible with an implementation later on)
w a -> (w a -> b) -> w b

Note that this rewrite exploited the fact that a Grid is simply a functor (collection) of Cells, and then used this to rewrite the type signature.

The type signature

w a -> (w a -> b) -> w b

can be sharply contrasted with the monadic >>= (bind) as

>>= :: m a -> (a -> m b) -> m b

Indeed, these structures are dual, which is why there are called as Comonad, which is also why I picked w as the symbol for Comonad (which is an upside-down m for Monad). It is usually called as "cobind", and is written as

=>> :: w a -> (w a -> b) -> w b

with the interpretation that it takes a global structure w a which is focused on some a in the w a, and then takes a transform that updates the focused a in the w a to a b. Given these two pieces of information, the Comonad automatically updates every single a, to produce an updated w b.

The Store comonad

Now, we will show a particular comonad, the Store, which forms the underlying comonad for this implementation

data Store s a = Store {
  sextract :: s -> a,
  sval :: s
}

instance Functor (Store s) where
   fmap f (Store xtract v) = Store (f . xtract) v
   
instance Comonad (Store s) where
   extract :: Store s a -> a
   extract (Store xtract v) = xtract v
   
   (>>=) :: Store s a -> (Store s a -> b) -> Store s b
   store@(Store xtract v) >>= f = 
       let b = f store
           xtract' s = f (Store xtract s) 
       in Store b xtract'

Weird Template Haskell stuff I've noticed

-- this works

deriveMonoElement :: Type -> Type -> Q[Dec]
deriveMonoElement tnewtype telem = [d| type instance Element (tnewtype) = $(return telem) |]


-- this doesn't
deriveMonoElement :: Type -> Type -> Q[Dec]
deriveMonoElement tnewtype telem = [d| type instance Element (tnewtype) = telem |]

-- Why can I use `tnewtype` as a "raw" value while I can't with `telem`?
-- Why does `$(return telem)`  work while raw `telem` doesn't?

License - MIT

The MIT License (MIT)
Copyright (c) 2016 Siddharth Bhat

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
``

More Repositories

1

bollu.github.io

code + contents of my website, and programming life
HTML
361
star
2

mathemagic

Toybox of explanations of mathematics. Initial focus on (discrete) differential geometry
JavaScript
276
star
3

tiny-optimising-compiler

A tiny *optimising* compiler for an imperative programming language written in haskell
Haskell
154
star
4

sublimeBookmark

a better bookmark system for SublimeText
Python
129
star
5

teleport

A CLI in haskell to quickly move through the filesystem
HTML
108
star
6

simplexhc

compiler with polyhedral optmization for a lazy functional programming language
Haskell
67
star
7

timi

A visual interpreter of the template instantiation machine to understand evaluation of lazy functional languages
Rust
64
star
8

blaze

Haskell re-implementation of STOKE, the stochastic superoptimizer
Jupyter Notebook
62
star
9

notes

Latex notes on papers, courses, ideas: Pure math and computer science.
TeX
61
star
10

SublimeRealityCheck

Sublime text plugin for live value watching for interpreted languages
Python
36
star
11

discrete-differential-geometry

An elegant implementation of discrete diffgeo in haskell
Haskell
33
star
12

simplexhc-cpp

optimising compiler for Haskell's intermediate representation (STG) to LLVM IR
C++
31
star
13

minitt

bollu learns implementation of dependent typing
Haskell
24
star
14

lean-to

Jupyter notebook for the Lean4 programming language
C++
24
star
15

ward

WARD is a minimal, performant infinite whiteboard app for wacom tablets
C
21
star
16

coremlir

Encoding of GHC Core inside MLIR
Haskell
16
star
17

mlir-hs

Pure haskell encoding of MLIR for printing, parsing, and mutating MLIR within haskell
Haskell
15
star
18

lz

A minimal in MLIR dialect along the lines of STG to represent laziness.
LLVM
15
star
19

koans

Short pieces of code that are "plays" - mostly haskell, sometimes math / other things
Haskell
13
star
20

linker-koans

Snippets that explore how linkers work, one flag at a time.
Makefile
11
star
21

rete

An implementation of the rete algorithm from 'Production Matching for Large Learning Systems'
C++
11
star
22

polymage

PolyMage is a domain-specific language and optimizing code generator for auto-parallelisation
Python
10
star
23

hask-error-messages-catalog

A catalog of broken Haskell programs to improve error messages
9
star
24

diffgeo

A formalization of synthetic differential geometry in Coq using infinitesimal analysis
Coq
9
star
25

quantum-course-exercises

Solutions to coursework in Q#
C#
9
star
26

soundsynth

Bollu learns physically based sound sythesis
C++
7
star
27

w

algorithms implemented in C++, written in the arthur whitney style
C++
7
star
28

llama.lean

Reimplementation of llama.cpp in Lean4
C
7
star
29

IIIT-H-Code

code written for assignments and whatnot at IIIT-H
C
7
star
30

myriad

A library for manifold algorithms, as I learn discrete diferential geometry and general relativity
Haskell
5
star
31

dependence-analysis-hask

Dependence Analysis for Haskell code using the polyhedral framework
5
star
32

elide

Elide: Elegant Metamodal Lean4 IDE.
C++
5
star
33

polyir

A semantics for the types of loops that can be modelled by polyhedral compilation techniques, developed in Coq.
Coq
5
star
34

TaleOfTwoDialects

nontrivial lowering examples for MLIR that are ignored by the MLIR tutorials
C++
5
star
35

software-foundations-solutions

My solutions to the software foundations book
HTML
5
star
36

qoc

Quite Obfuscated Constructions
Haskell
4
star
37

equinox

game to experiment with Rust, Carmack's ideas
Rust
4
star
38

lean4-entemology

Where we collect lean4 bugs
Lean
4
star
39

minos

There are many OSes, this one is mine
Makefile
4
star
40

mlir-hoopl-rete

rewrites for MLIR with hoopl / rete
MLIR
4
star
41

smol

smol IDE for a smol language that permits insane static analysis because smol
C
4
star
42

shakuni

An exploration of minimality and parallelism in probabilstic programming languages.
Jupyter Notebook
4
star
43

pico-mlir

A mini language written using MLIR + MAKEFILES! so you get to see all the commands, no CMake magic.
C++
4
star
44

polybench-c

PolyBench/C from http://web.cse.ohio-state.edu/~pouchet/software/polybench/
C
3
star
45

pisigma

A reference copy of PiSigma: dependent types with without the sugar
Haskell
3
star
46

lean.egraphs

Egraphs & ematching in Lean
C++
3
star
47

biter

library / CLI as a swiss-army knife for low level bit fiddling debugging.
Haskell
3
star
48

fbip-demos

Demos to test out Lean's functional but in place.
Lean
3
star
49

hugs

A copy of the hugs haskell98 implementation; hoping to eliminate bitrot
Haskell
3
star
50

sdl2.lean

bindings to SDL2 (Simple DirectMedia library) in Lean
C
3
star
51

dotfiles

my dotfiles for easy access
Vim Script
3
star
52

master-thesis

My master's thesis on NLP and representation learning
TeX
3
star
53

SCEV-coq

LLVM's loop analysis theory (Scalar Evolution) formalized in Coq
Makefile
3
star
54

warren

The warren abstract machine for Pascal, in Hakell
Haskell
3
star
55

functionalconf-2019-slides-probabilistic-programming

Slides for my talk at functional conf 2019 on probabilistic programming
Haskell
3
star
56

polly

A personal fork of the Polly-LLVM project
C
2
star
57

ppcg

A fork of the original PPCG with debug code: http://repo.or.cz/w/ppcg.git
C
2
star
58

mips-bsv

an implementation of a MIPS processor in BlueSpec System Verilog
Bluespec
2
star
59

haskell-tutorial

Files for a haskell tutorial I'm teaching at IIIIT-Hyderabad
Haskell
2
star
60

freejit

Try to JIT Free monads in Haskell.
Haskell
2
star
61

slides-haskell-exchange-2020-smallpt

Slides for haskell exchange 2020 talk on smallpt
TeX
2
star
62

llvm

A fork of the LLVM project for personal use
LLVM
2
star
63

dataflow

A view of dataflow architectures, with a modern haskell perspective
Haskell
2
star
64

paper-deltas

Deltas: An algebraic theory of diffs in haskell
TeX
2
star
65

hask-lisp-interp

Lisp interpreter in Haskell
Haskell
2
star
66

alok-bollu

A repo for work between Alok Debnath and Siddharth Bhat
C
2
star
67

sicm

structure and interpretation of classical mechanics
Scheme
2
star
68

CASette

Mixtape of computer algebra system (CAS) algorithms
Lean
2
star
69

captainslog

Documenting the PhD slog, one day at a time
2
star
70

amalgam

amalgam ~ composite | A small library for interactive symbolic number theory explorations in haskell
Haskell
2
star
71

gde-game

Game on using text generation to trigger empathy
Python
2
star
72

unification

polymorphic type inference with unification from the Dragon book
C++
2
star
73

warren-cpp

An implementation of warren, the abstract machine for Prolog. Is a transcription of the lecture notes "warren's abstract machine a tutorial reconstruction"
C++
2
star
74

proGenY

procedurally generated 2d shooter
C++
2
star
75

lent-2024-logic-and-proof

Lean notes for "Logic & Proof" : Cambridge Tripos Part 1B, Lent 2024
Lean
1
star
76

clisparkline

Tiny haskell library to prettyprint sparklines onto the CLI!
Haskell
1
star
77

polybench-hs

Polybench HS
C
1
star
78

tabledtypeclass

tabled typeclass resolution implementation
C++
1
star
79

functional-fluids-on-surfaces

implementation of the paper "functional fluids on surfaces"
Python
1
star
80

sunnyside

Equality saturation for fun and profit
Rust
1
star
81

optics

optics and refraction simulation in C++
C
1
star
82

gutenberger

fast vectorized presburger automata
Haskell
1
star
83

hs-stockfighter

Haskell bindings to Stockfighter using Servant
Haskell
1
star
84

decompile-transformer

The one where bollu decompiles attention models
Jupyter Notebook
1
star
85

musquared

Demand-agnostic managed language compiler using MLIR
Haskell
1
star
86

smallpths

Smallpt rewrite that's fast!
Haskell
1
star
87

tinyfort

Minimal fortran-ish language with LLVM backend, written for a compilers course
C++
1
star
88

languagemodels

Me messing around with language models, trying to make NLP run on commodity hardware with weird ideas.
C++
1
star
89

haikus

detect haikus
Python
1
star
90

lean-koans

A dumping ground for short Lean programs that demonstrate a point: a kลan
Lean
1
star
91

geometric-algebra

Implementation of geometric algebra primitives
Haskell
1
star
92

propogators-coq

A formalisation of propogators as ekmett speaks about them on the livestream: https://www.twitch.tv/ekmett
Coq
1
star
93

pegasos-svm

An implmentation of the pegasos SVM learning algorithm
Python
1
star
94

ppsspp-help

Help for ppsspp
CSS
1
star
95

competitive

Competitive coding solutions
C++
1
star
96

prettyprinter-core

quchen's prettyprinter library, stolen and stripped of other code for GHC.
Haskell
1
star
97

ghc-asterius

For of terrorjack/GHC to hack on austerius
Haskell
1
star
98

lispInterpreter

A lisp interpreter in C++ for fun :)
C++
1
star
99

FPGA-playground

Code written using BlueSpec Verilog, general FPGA messing around for my course
Bluespec
1
star
100

absint

abstract interpreters for a tiny SSA language in haskell
Haskell
1
star