Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca-dot.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
42#ifndef CA_DOT_H
43#define CA_DOT_H
44
45#include <concepts>
46#include <filesystem>
47#include <fstream>
48#include <ostream>
49#include <sstream>
50#include <string>
51#include <utility>
52
53#include <ah-errors.H>
54
55#include <ca-frame-stream.H>
57
58namespace Aleph {
59namespace CA {
60
63{
64 std::string graph_name = "CA";
65 bool undirected = true;
66 bool include_labels = true;
67};
68
73template <typename State>
75{
76 State dead{};
77 std::string dead_colour = "white";
78 std::string alive_colour = "black";
79
84 [[nodiscard]] std::string operator()(const State &value) const
85 {
86 return value == dead ? dead_colour : alive_colour;
87 }
88};
89
90namespace ca_dot_detail {
91
92inline std::string quote(const std::string &s)
93{
94 std::ostringstream out;
95 out << '"';
96 for (const char c : s)
97 {
98 if (c == '"' or c == '\\')
99 out << '\\';
100 out << c;
101 }
102 out << '"';
103 return out.str();
104}
105
110inline std::string quote_id_if_needed(const std::string &s)
111{
112 if (s.empty())
113 return quote(s);
114 const auto is_id_start = [](unsigned char c)
115 {
116 return (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or c == '_';
117 };
118 const auto is_id_cont = [&](unsigned char c)
119 {
120 return is_id_start(c) or (c >= '0' and c <= '9');
121 };
122 if (not is_id_start(static_cast<unsigned char>(s[0])))
123 return quote(s);
124 for (std::size_t i = 1; i < s.size(); ++i)
125 if (not is_id_cont(static_cast<unsigned char>(s[i])))
126 return quote(s);
127 return s;
128}
129
130} // namespace ca_dot_detail
131
145template <typename Graph, typename Palette>
146inline void render_graph_lattice_dot(std::ostream &out,
147 const Graph &graph,
149 const DOT_Render_Options &opts = {})
150 requires requires(const Graph &g, std::size_t n, Palette &&p, const typename Graph::state_type &v) {
151 g.size();
152 g.neighbours(n);
153 g.at_node(n);
154 { p(v) } -> std::convertible_to<std::string>;
155 }
156{
157 const char *kind = opts.undirected ? "graph" : "digraph";
158 const char *edge = opts.undirected ? "--" : "->";
159 out << kind << ' ' << ca_dot_detail::quote_id_if_needed(opts.graph_name) << " {\n";
160 out << " node [shape=circle, style=filled, fixedsize=true, width=0.42];\n";
161
162 for (std::size_t n = 0; n < graph.size(); ++n)
163 {
164 const std::string fill = palette(graph.at_node(n));
165 out << " n" << n << " [fillcolor=" << ca_dot_detail::quote(fill);
166 if (opts.include_labels)
167 out << ", label=" << ca_dot_detail::quote(std::to_string(n));
168 else
169 out << ", label=\"\"";
170 if (fill == "black" or fill == "#000000")
171 out << ", fontcolor=\"white\"";
172 out << "];\n";
173 }
174
175 for (std::size_t n = 0; n < graph.size(); ++n)
176 {
177 const auto &row = graph.neighbours(n);
178 for (std::size_t k = 0; k < row.size(); ++k)
179 {
180 const std::size_t m = row[k];
181 if (opts.undirected and m < n)
182 continue;
183 out << " n" << n << ' ' << edge << " n" << m << ";\n";
184 }
185 }
186 out << "}\n";
187 ah_runtime_error_if(not out) << "render_graph_lattice_dot: output stream failed";
188}
189
206template <typename Graph, typename Palette>
207[[nodiscard]] inline std::string render_graph_lattice_dot_string(const Graph &graph,
209 const DOT_Render_Options &opts = {})
210{
211 std::ostringstream out;
212 render_graph_lattice_dot(out, graph, std::forward<Palette>(palette), opts);
213 return out.str();
214}
215
220template <typename Palette>
222{
223 std::filesystem::path pattern_;
226 std::size_t zero_pad_ = 6;
227
228public:
237 Dot_Frame_Sink(std::filesystem::path path_pattern,
240 const std::size_t zero_pad = 6)
241 : pattern_(std::move(path_pattern)), palette_(std::move(palette)), opts_(std::move(opts)),
242 zero_pad_(zero_pad)
243 {}
244
255 template <typename Graph>
256 void accept(const std::size_t step, const Graph &graph)
257 {
258 const std::filesystem::path path = format_step_path(pattern_, step, zero_pad_);
259 if (const auto parent = path.parent_path(); not parent.empty())
260 std::filesystem::create_directories(parent);
261 std::ofstream out(path);
262 ah_runtime_error_if(not out) << "Dot_Frame_Sink::accept: cannot open '" << path.string() << "'";
264 }
265
267 static void flush() {}
268};
269
270template <typename Palette>
271Dot_Frame_Sink(std::filesystem::path, Palette, DOT_Render_Options = {}, std::size_t = 6)
273
274} // namespace CA
275} // namespace Aleph
276
277#endif // CA_DOT_H
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:271
size_t size_t int32_t value
Definition ca-c-api.h:116
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t row
Definition ca-c-api.h:115
Directory-backed frame sinks for CA trajectories.
Path-pattern sink that writes GraphViz DOT frames.
Definition ca-dot.H:222
DOT_Render_Options opts_
Definition ca-dot.H:225
std::filesystem::path pattern_
Definition ca-dot.H:223
std::size_t zero_pad_
Definition ca-dot.H:226
Dot_Frame_Sink(std::filesystem::path path_pattern, Palette palette, DOT_Render_Options opts={}, const std::size_t zero_pad=6)
Build a DOT frame sink.
Definition ca-dot.H:237
void accept(const std::size_t step, const Graph &graph)
Write one DOT frame.
Definition ca-dot.H:256
static void flush()
DOT frames are written eagerly; this is a no-op.
Definition ca-dot.H:267
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::string quote(const std::string &s)
Definition ca-dot.H:92
std::string quote_id_if_needed(const std::string &s)
Return s as a bare DOT identifier when it matches [A-Za-z_][A-Za-z_0-9]*, otherwise return quote(s).
Definition ca-dot.H:110
std::filesystem::path format_step_path(const std::filesystem::path &pattern, const std::size_t step, const std::size_t zero_pad=6)
Format a step-indexed file path.
void render_graph_lattice_dot(std::ostream &out, const Graph &graph, Palette &&palette, const DOT_Render_Options &opts={})
Render a graph CA frame as GraphViz DOT.
Definition ca-dot.H:146
std::string render_graph_lattice_dot_string(const Graph &graph, Palette &&palette, const DOT_Render_Options &opts={})
Return a graph frame rendered as DOT.
Definition ca-dot.H:207
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
void fill(Itor beg, const Itor &end, const T &value)
Fill a range with a value.
Definition ahAlgo.H:707
and
Check uniqueness with explicit hash + equality functors.
STL namespace.
Default binary DOT fill-colour palette.
Definition ca-dot.H:75
std::string dead_colour
fill colour for dead cells
Definition ca-dot.H:77
std::string alive_colour
fill colour for live cells
Definition ca-dot.H:78
State dead
state considered dead
Definition ca-dot.H:76
std::string operator()(const State &value) const
Map a cell state to a GraphViz colour.
Definition ca-dot.H:84
DOT rendering options.
Definition ca-dot.H:63
bool undirected
use graph/-- and suppress duplicate edges
Definition ca-dot.H:65
bool include_labels
label nodes with their numeric id
Definition ca-dot.H:66
std::string graph_name
DOT graph identifier.
Definition ca-dot.H:64
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
static int * k
CA whose underlying topology is an arbitrary undirected graph.