|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Hashlife engine for outer-totalistic binary cellular automata. More...
#include <tpl_ca_hashlife.H>
Classes | |
| struct | BBox |
Inclusive bounding box (returned by bbox). More... | |
| struct | Stats |
Diagnostics returned by stats. More... | |
Public Types | |
| using | Rule = Outer_Totalistic_Binary_Rule |
| Rule type used by the engine. | |
Public Member Functions | |
| Hashlife_Engine (Rule rule=Conway_Life, std::size_t cache_capacity=std::size_t{1}<< 22) | |
| Build an engine with the given rule and result-cache capacity. | |
| void | set_rule (const Rule &r) |
| Replace the rule. Invalidates the result cache. | |
| Rule | rule () const noexcept |
| Current rule. | |
| void | set_alive (const std::int64_t x, const std::int64_t y, const bool alive=true) |
Set or clear the cell at world coordinates (x, y). | |
| bool | alive_at (const std::int64_t x, const std::int64_t y) const |
Read the cell at world coordinates (x, y). | |
| std::uint64_t | advance (const unsigned k) |
Advance the universe by 2^k generations. | |
| std::uint64_t | run (std::uint64_t generations) |
Advance by exactly generations steps. | |
| std::uint64_t | population () const noexcept |
| Number of alive cells. | |
| std::int64_t | generation () const noexcept |
Number of generations elapsed since construction (or the last clear). | |
| BBox | bbox () const |
Tight bounding box of the alive cells (empty if population() == 0). | |
| void | clear () |
| Reset the universe to empty (preserves rule, capacity and node cache). | |
| Stats | stats () const noexcept |
| Diagnostic counters and current root level. | |
| std::size_t | cache_capacity () const noexcept |
| Maximum allowed canonical-node count before the result cache is dropped. | |
| template<typename F > | |
| void | for_each_alive (F &&f) const |
Iterate over all alive cells, calling f(x, y) for each. | |
| void | load_rle (std::istream &in) |
Load an RLE pattern from in (centred at the origin). | |
| void | load_rle_string (const std::string &s) |
| Convenience overload that reads the pattern from a string. | |
| void | save_rle (std::ostream &out, const std::string &comment={}) const |
| Write the alive cells in RLE format. | |
| std::string | save_rle_string (const std::string &comment={}) const |
| Convenience overload returning the RLE serialisation as a string. | |
Private Types | |
| using | Node = ca_hashlife_detail::Node |
| using | Node_Key = ca_hashlife_detail::Node_Key |
Private Member Functions | |
| Node * | make_leaf (const std::uint8_t bits) |
| Node * | make_node (Node *nw, Node *ne, Node *sw, Node *se) |
| Node * | empty_node (const std::uint8_t level) |
| void | clear_result_cache () |
| Node * | expand (const Node *n) |
| Node * | horizontal_centered (Node *w, Node *e) |
| Node * | vertical_centered (Node *n, Node *s) |
| Node * | center_of_4 (Node *nw, Node *ne, Node *sw, Node *se) |
| Node * | evolve_level_2 (Node *n) |
| Node * | evolve (Node *n) |
| Node * | set_in_node (const Node *n, const std::int64_t x, const std::int64_t y, const bool alive) |
| template<typename F > | |
| void | visit_alive (Node *n, std::int64_t x, std::int64_t y, F &&f) const |
Static Private Member Functions | |
| static bool | is_centered_well (const Node *n) noexcept |
Standard Hashlife "centered well" predicate: every quadrant of n has its population concentrated in the sub-quadrant closest to the centre. | |
| static bool | get_in_node (const Node *n, const std::int64_t x, const std::int64_t y) noexcept |
| static std::int64_t | parse_header_value (const std::string &line, const char key) |
| static std::optional< Outer_Totalistic_Binary_Rule > | parse_rule_field (const std::string &line) |
Private Attributes | |
| Rule | rule_ |
| std::size_t | cache_capacity_ |
| std::deque< Node > | pool_ |
| std::unordered_map< Node_Key, Node *, ca_hashlife_detail::Node_Key_Hash > | table_ |
| Array< Node * > | empty_by_level_ |
| Aleph::Array of canonical empties per level. | |
| Node * | root_ = nullptr |
| std::int64_t | generation_ = 0 |
| std::size_t | result_hits_ = 0 |
| std::size_t | result_misses_ = 0 |
| std::size_t | result_cache_clears_ = 0 |
Static Private Attributes | |
| static constexpr std::uint8_t | initial_level_ = 3 |
| 8 × 8 starting universe | |
Hashlife engine for outer-totalistic binary cellular automata.
Implements Bill Gosper's Hashlife algorithm on top of a hash-consed quadtree. Suitable for very large patterns (10⁶+ cells) advanced by enormous numbers of generations (10⁹+) — uses cases that are out of reach for the dense Synchronous_Engine.
2^k × 2^k square; level-1 leaves pack their 4 cells into a single byte. evolve(n) returns the central 2^(k-1) × 2^(k-1) area of n after 2^(k-2) generations: it builds the 9 overlapping level k-1 sub-squares of n, evolves each (giving 9 level k-2 results), recombines them into 4 level k-1 macrocells advanced by 2^(k-3) generations, and evolves those for another 2^(k-3) generations — totalling 2^(k-2).evolve result. Because identical subtrees share the same Node *, the recursion sees an effective subset of nodes that grows with the pattern's complexity, not its size. Patterns with strong spatial / temporal self-similarity (gliders, repeating engines, regular gun outputs) are accelerated by orders of magnitude.cache_capacity(), the per-node result pointers are invalidated (the canonical nodes themselves are kept alive). This bounds the memoisation footprint while preserving correctness; future evolve calls simply recompute.result cache are written during evolution. Definition at line 300 of file tpl_ca_hashlife.H.
Definition at line 712 of file tpl_ca_hashlife.H.
Definition at line 713 of file tpl_ca_hashlife.H.
Rule type used by the engine.
Definition at line 304 of file tpl_ca_hashlife.H.
|
inlineexplicit |
Build an engine with the given rule and result-cache capacity.
| rule | outer-totalistic rule (default: Conway's Game of Life). |
| cache_capacity | maximum number of canonical nodes before the per-node result cache is dropped (default: 4 Mi). |
| std::domain_error | if cache_capacity < 1024. |
Definition at line 350 of file tpl_ca_hashlife.H.
Advance the universe by 2^k generations.
The universe is automatically padded so that evolution is well-defined. If the alive pattern is too dense to fit at level k + 2, the engine expands further and the call advances by 2^L generations for some L > k. Use the return value to discover the actual advance.
| k | logarithm of the desired step size. |
≥ 2^k). | std::domain_error | if k > 62. |
Definition at line 417 of file tpl_ca_hashlife.H.
References ah_domain_error_if, Aleph::blossom_maximum_cardinality_matching(), cache_capacity_, clear_result_cache(), evolve(), expand(), generation_, is_centered_well(), k, Aleph::CA::ca_hashlife_detail::Node::level, root_, steps, and table_.
Referenced by run(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
inline |
Read the cell at world coordinates (x, y).
Cells outside the root area are reported as dead.
Definition at line 397 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching(), get_in_node(), Aleph::CA::ca_hashlife_detail::Node::level, root_, and y.
|
inline |
Tight bounding box of the alive cells (empty if population() == 0).
Definition at line 475 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::CA::ca_hashlife_detail::Node::level, Aleph::CA::ca_hashlife_detail::Node::population, root_, visit_alive(), and y.
|
inlinenoexcept |
Maximum allowed canonical-node count before the result cache is dropped.
Definition at line 510 of file tpl_ca_hashlife.H.
References cache_capacity_.
|
inlineprivate |
Definition at line 844 of file tpl_ca_hashlife.H.
References make_node(), Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::se, and Aleph::CA::ca_hashlife_detail::Node::sw.
Referenced by evolve().
|
inline |
Reset the universe to empty (preserves rule, capacity and node cache).
Definition at line 497 of file tpl_ca_hashlife.H.
References empty_node(), generation_, initial_level_, and root_.
Referenced by TEST().
|
inlineprivate |
Definition at line 785 of file tpl_ca_hashlife.H.
References pool_, result_cache_clears_, result_hits_, and result_misses_.
Referenced by advance(), and set_rule().
Definition at line 767 of file tpl_ca_hashlife.H.
References Aleph::Array< T >::append(), Aleph::blossom_maximum_cardinality_matching(), empty_by_level_, make_leaf(), make_node(), and Aleph::Array< T >::size().
Definition at line 892 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching(), center_of_4(), evolve(), evolve_level_2(), horizontal_centered(), Aleph::CA::ca_hashlife_detail::Node::level, make_node(), Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::result, result_hits_, result_misses_, Aleph::CA::ca_hashlife_detail::Node::se, Aleph::CA::ca_hashlife_detail::Node::sw, and vertical_centered().
Definition at line 851 of file tpl_ca_hashlife.H.
References Aleph::CA::Outer_Totalistic_Binary_Rule::apply(), Aleph::CA::ca_hashlife_detail::Node::bits, Aleph::count(), make_leaf(), Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, r, rule_, Aleph::CA::ca_hashlife_detail::Node::se, and Aleph::CA::ca_hashlife_detail::Node::sw.
Referenced by evolve().
Definition at line 796 of file tpl_ca_hashlife.H.
References Aleph::CA::ca_hashlife_detail::Node::bits, Aleph::blossom_maximum_cardinality_matching(), empty_node(), Aleph::CA::ca_hashlife_detail::Node::level, make_leaf(), make_node(), Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::se, and Aleph::CA::ca_hashlife_detail::Node::sw.
Referenced by advance(), and set_alive().
Iterate over all alive cells, calling f(x, y) for each.
Visits each alive cell exactly once, in unspecified order.
| F | callable accepting (std::int64_t, std::int64_t). |
| f | visitor. |
Definition at line 523 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::CA::ca_hashlife_detail::Node::level, Aleph::CA::ca_hashlife_detail::Node::population, root_, and visit_alive().
|
inlinenoexcept |
Number of generations elapsed since construction (or the last clear).
Definition at line 469 of file tpl_ca_hashlife.H.
References generation_.
|
inlinestaticprivatenoexcept |
Definition at line 984 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching(), get_in_node(), and y.
Referenced by alive_at(), and get_in_node().
Definition at line 834 of file tpl_ca_hashlife.H.
References make_node(), Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::se, Aleph::CA::ca_hashlife_detail::Node::sw, and w.
Referenced by evolve().
|
inlinestaticprivatenoexcept |
Standard Hashlife "centered well" predicate: every quadrant of n has its population concentrated in the sub-quadrant closest to the centre.
This guarantees that, after evolve (which advances 2^(L-2) generations and returns only the central area), no alive cell escapes the new root — for any rule whose maximum signal speed is at most c/2 (which holds for every life-like outer-totalistic rule, including Conway's B3/S23).
Definition at line 822 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching().
Referenced by advance().
|
inline |
Load an RLE pattern from in (centred at the origin).
Parses the standard RLE dialect (# comments, x = W, y = H, rule = R header, b/o/$/! body, run-length prefixes). The rule field is parsed and replaces the engine's current rule when valid.
| in | input stream positioned at the start of the pattern. |
Definition at line 543 of file tpl_ca_hashlife.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), parse_header_value(), parse_rule_field(), r, rule_, run(), and set_alive().
Referenced by load_rle_string().
Convenience overload that reads the pattern from a string.
Definition at line 604 of file tpl_ca_hashlife.H.
References Aleph::blossom_maximum_cardinality_matching(), and load_rle().
Definition at line 733 of file tpl_ca_hashlife.H.
References Aleph::CA::ca_hashlife_detail::Node::level, pool_, and table_.
Referenced by empty_node(), evolve_level_2(), expand(), and set_in_node().
|
inlineprivate |
Definition at line 748 of file tpl_ca_hashlife.H.
References Aleph::CA::ca_hashlife_detail::Node::level, Aleph::CA::ca_hashlife_detail::Node::ne, pool_, Aleph::CA::ca_hashlife_detail::Node::population, Aleph::CA::ca_hashlife_detail::Node::se, Aleph::CA::ca_hashlife_detail::Node::sw, and table_.
Referenced by center_of_4(), empty_node(), evolve(), expand(), horizontal_centered(), set_in_node(), and vertical_centered().
|
inlinestaticprivate |
Definition at line 1023 of file tpl_ca_hashlife.H.
References Aleph::and, and Aleph::blossom_maximum_cardinality_matching().
Referenced by load_rle().
|
inlinestaticprivate |
Definition at line 1049 of file tpl_ca_hashlife.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), and Aleph::CA::parse_rule().
Referenced by load_rle().
|
inlinenoexcept |
|
inlinenoexcept |
|
inline |
Advance by exactly generations steps.
Decomposes generations into a sum of powers of two and chains the corresponding advance calls. The actual advance may slightly exceed the request when the pattern outgrows the chosen level.
| generations | target step count (0 is a no-op). |
≥ generations). Definition at line 447 of file tpl_ca_hashlife.H.
References advance(), Aleph::blossom_maximum_cardinality_matching(), and k.
Referenced by load_rle(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST_P().
|
inline |
Write the alive cells in RLE format.
Emits a single-line header (x = W, y = H, rule = ...) and a run-length-encoded body wrapped at ~70 characters per line.
| out | output stream. |
| comment | optional #C comment line (ignored if empty). |
Definition at line 618 of file tpl_ca_hashlife.H.
|
inline |
Convenience overload returning the RLE serialisation as a string.
Definition at line 704 of file tpl_ca_hashlife.H.
|
inline |
Set or clear the cell at world coordinates (x, y).
Coordinates are signed 64-bit. The universe automatically expands to contain the requested cell.
| x | column (positive = east). |
| y | row (positive = south, RLE convention). |
| alive | new state (default true). |
Definition at line 382 of file tpl_ca_hashlife.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), expand(), Aleph::CA::ca_hashlife_detail::Node::level, root_, set_in_node(), and y.
Referenced by load_rle(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
inlineprivate |
Definition at line 950 of file tpl_ca_hashlife.H.
References Aleph::CA::ca_hashlife_detail::Node::bits, Aleph::blossom_maximum_cardinality_matching(), Aleph::CA::ca_hashlife_detail::Node::level, make_leaf(), make_node(), Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::se, set_in_node(), Aleph::CA::ca_hashlife_detail::Node::sw, and y.
Referenced by set_alive(), and set_in_node().
Replace the rule. Invalidates the result cache.
Definition at line 359 of file tpl_ca_hashlife.H.
References clear_result_cache(), r, and rule_.
Referenced by TEST().
|
inlinenoexcept |
Diagnostic counters and current root level.
Definition at line 504 of file tpl_ca_hashlife.H.
References Aleph::CA::ca_hashlife_detail::Node::level, result_cache_clears_, result_hits_, result_misses_, root_, and table_.
Definition at line 839 of file tpl_ca_hashlife.H.
References make_node(), Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::se, and Aleph::CA::ca_hashlife_detail::Node::sw.
Referenced by evolve().
|
inlineprivate |
Definition at line 998 of file tpl_ca_hashlife.H.
References Aleph::CA::ca_hashlife_detail::Node::bits, Aleph::blossom_maximum_cardinality_matching(), Aleph::CA::ca_hashlife_detail::Node::level, Aleph::CA::ca_hashlife_detail::Node::ne, Aleph::CA::ca_hashlife_detail::Node::nw, Aleph::CA::ca_hashlife_detail::Node::population, Aleph::CA::ca_hashlife_detail::Node::se, Aleph::CA::ca_hashlife_detail::Node::sw, visit_alive(), and y.
Referenced by bbox(), for_each_alive(), and visit_alive().
|
private |
Definition at line 718 of file tpl_ca_hashlife.H.
Referenced by advance(), and cache_capacity().
Aleph::Array of canonical empties per level.
Definition at line 722 of file tpl_ca_hashlife.H.
Referenced by empty_node().
|
private |
Definition at line 725 of file tpl_ca_hashlife.H.
Referenced by advance(), clear(), and generation().
|
staticconstexprprivate |
|
private |
Definition at line 720 of file tpl_ca_hashlife.H.
Referenced by clear_result_cache(), make_leaf(), and make_node().
|
private |
Definition at line 729 of file tpl_ca_hashlife.H.
Referenced by clear_result_cache(), and stats().
|
mutableprivate |
Definition at line 727 of file tpl_ca_hashlife.H.
Referenced by clear_result_cache(), evolve(), and stats().
|
mutableprivate |
Definition at line 728 of file tpl_ca_hashlife.H.
Referenced by clear_result_cache(), evolve(), and stats().
|
private |
Definition at line 724 of file tpl_ca_hashlife.H.
Referenced by advance(), alive_at(), bbox(), clear(), for_each_alive(), population(), set_alive(), and stats().
|
private |
Definition at line 717 of file tpl_ca_hashlife.H.
Referenced by evolve_level_2(), load_rle(), rule(), and set_rule().
|
private |
Definition at line 721 of file tpl_ca_hashlife.H.
Referenced by advance(), make_leaf(), make_node(), and stats().