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
Wireworldpaclet using thebuild_paclet.wlswolframscript:
./scripts/build_paclet.wlsThe 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.wlsThe library will be stored in LibraryResources/$SystemID/:
ls LibraryResources/MacOSX-ARM64 # libWireworld.dylibNote: this script only builds the library for your builtin $SystemID.
Use zig build (https://ziglang.org) to build the library:
zig version # 0.14.0
zig buildThe library will be stored in LibraryResources/$SystemID/:
ls LibraryResources/MacOSX-ARM64 # libWireworld.dylibOne can also cross compile specifying the target:
zig build -Dtarget=x86_64-linux
ls LibraryResources/Linux-x86-64 # libWireworld.soThe 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(...);