daneelsan / Wireworld

Wireworld: a Turing-complete cellular automaton suited for simulating logic gates and other real-world computer elements

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wireworld

Wireworld is a Turing-complete cellular automaton first proposed by Brian Silverman in 1987 suited for simulating logic gates and other real-world computer elements.

Installation

Install the paclet (version 1.0.0) from github releases:

PacletInstall["https://github.com/daneelsan/Wireworld/releases/download/v1.0.0/Wireworld-1.0.0.paclet"]

Usage

Load the Wireworld` package:

Needs["Wireworld`"]

Wireworld symbols:

In[]:= Names["Wireworld`*"]
Out[]= {
	"WireworldDraw",
	"WireworldEvolve",
	"WireworldPlot",
	"WireworldStateQ",
	"$WireworldFunctionRule",
	"$WireworldNumberRule",
	"$WireworldRule"
}

Open the documentation of the WireworldEvolve function:

NotebookOpen[Information[WireworldEvolve, "Documentation"]["Local"]]

ref/WireworldEvolve

Examples

A Clock Generator

A period 12 electron clock generator:

In[]:= state = {
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 3, 3, 3, 0, 3, 2, 1, 3, 3, 0, 0, 0},
	{0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0},
	{0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0},
	{0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0},
	{0, 0, 3, 3, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0}
};

In[]:= ListAnimate[WireworldPlot /@ WireworldEvolve[state, 11]]

A clock generator

The Diode

A diode allows electrons to flow in only one direction:

In[]:= state = {
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{3, 3, 2, 1, 3, 3, 3, 3, 2, 1, 3, 0, 3, 3, 2, 1, 3, 3, 3, 3, 2},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{3, 3, 2, 1, 3, 3, 3, 3, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

In[]:= ListAnimate[WireworldPlot /@ WireworldEvolve[state, 8]]

Two diodes

The OR gate

Two clock generators sending electrons into an OR gate:

In[]:= state = {
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 3, 3, 3, 1, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 1, 3},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 2, 1, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0},
	{0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

In[]:= ListAnimate[WireworldPlot /@ WireworldEvolve[state, 20]]

An OR gate

Wolfram Paclet Repository

A copy of the lastest released paclet is in the Wolfram Paclet Repository (WPR): https://resources.wolframcloud.com/PacletRepository/resources/DanielS/Wireworld/

Build

  1. Build the Wireworld paclet using the build_paclet.wls wolframscript:
./scripts/build_paclet.wls

The paclet will be placed under the build directory:

ls build/*.paclet # build/Wireworld-1.0.0.paclet
  1. Install the built paclet:
PacletInstall["./build/Wireworld-1.0.0.paclet"]

Build libWireworld

The LibraryLink library libWireworld contains the low-level functions Wireworld`Library`WireworldStepImmutable and Wireworld`Library`WireworldStepMutable. There are two ways to build it:

build_library.wls

Run scripts/build_library.wls:

./scripts/build_library.wls

The library will be stored in LibraryResources/$SystemID/:

ls LibraryResources/MacOSX-ARM64 # libWireworld.dylib

Note: this script only builds the library for your builtin $SystemID.

zig build

Use zig build (https://ziglang.org) to build the library:

zig version # 0.9.0
zig build

The library will be stored in LibraryResources/$SystemID/:

ls LibraryResources/MacOSX-ARM64 # libWireworld.dylib

One can also cross compile specifying the target:

zig build -Dtarget=x86_64-linux
ls LibraryResources/Linux-x86-64 # libWireworld.so

The mapping between zig targets and $SystemID is:

{
	"Linux-x86-64" -> "x86_64-linux",
	"MacOSX-x86-64" -> "x86_64-macos",
	"Windows-x86-64" -> "x86_64-windows",
	"MacOSX-ARM64" -> "aarch64-macos",
}

Note: other targets will be stored in zig-out/lib.

The build configuration is specified in build.zig. If necessary, change the location of the Wolfram libraries and headers:

lib.addIncludeDir(...);
lib.addLibPath(...);

About

Wireworld: a Turing-complete cellular automaton suited for simulating logic gates and other real-world computer elements


Languages

Language:Mathematica 99.7%Language:C 0.3%Language:Zig 0.1%