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.
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"]
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"]]
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 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 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]]
A copy of the lastest released paclet is in the Wolfram Paclet Repository (WPR): https://resources.wolframcloud.com/PacletRepository/resources/DanielS/Wireworld/
- Build the
Wireworld
paclet using thebuild_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
- Install the built paclet:
PacletInstall["./build/Wireworld-1.0.0.paclet"]
The LibraryLink
library libWireworld
contains the low-level functions Wireworld`Library`WireworldStepImmutable
and Wireworld`Library`WireworldStepMutable
. There are two ways to build it:
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
.
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(...);