3 #include <carl-common/datastructures/carlTree.h>
17 std::map<std::string,std::string>
mMap;
22 auto it =
mMap.find(raw);
23 if (it ==
mMap.end()) {
24 it =
mMap.emplace(raw,
mPrefix +
"_" + std::to_string(
mMap.size())).first;
31 std::vector<std::optional<std::string>>
steps;
33 void add(std::size_t step,
const std::string&
data) {
34 while (
steps.size() < step)
steps.emplace_back();
38 if (step >=
steps.size())
return false;
39 return bool(
steps[step]);
41 const std::string&
data(std::size_t step)
const {
42 assert(
steps.size() > step);
51 std::string
printableID(
const std::string& raw,
const std::string&
prefix, std::map<std::string,std::string>& map)
const {
52 auto it = map.find(raw);
53 if (it == map.end()) {
54 it = map.emplace(raw,
prefix +
"_" + std::to_string(map.size())).first;
59 virtual void addNode(std::size_t level,
const std::string& parent,
const std::string& node,
const std::string& data) = 0;
60 virtual void addEdge(
const std::string& src,
const std::string& dst,
const std::string& data) = 0;
65 virtual void writeTo(std::ostream& os,
int xBase)
const = 0;
67 virtual std::size_t
width()
const = 0;
76 using Level = std::map<std::string, Node>;
77 using NodeIDs = std::map<std::string, Level::iterator>;
82 void addNode(std::size_t level,
const std::string&,
const std::string& node,
const std::string& data)
override {
83 while (level >=
mData.size())
mData.emplace_back();
86 auto newIt =
mData[level].emplace(node,
Node()).first;
87 it =
mNodeIDs.emplace(node, newIt).first;
89 it->second->second.data.add(
mStep, data);
91 void addEdge(
const std::string& src,
const std::string& dst,
const std::string& data)
override {
94 auto outid = it->second->second.outgoing.find(dst);
95 if (outid == it->second->second.outgoing.end()) {
96 outid = it->second->second.outgoing.emplace(dst,
UnifiedData()).first;
98 outid->second.add(
mStep, data);
102 for (
const auto& l:
mData) {
106 void writeTo(std::ostream& os,
int xBase)
const override {
108 for (std::size_t level = 0; level <
mData.size(); level++) {
111 if (
mData[level].size() > 1) {
114 for (
const auto& entry:
mData[level]) {
116 if (!entry.second.data.showsOn(
step))
continue;
117 std::size_t cur =
step;
118 while (cur <
mStep && entry.second.data.showsOn(cur) && entry.second.data.data(cur) == entry.second.data.data(
step)) cur++;
119 os <<
"\t\\onslide<" << (
step+1) <<
"-" << (cur+1) <<
">{" << std::endl;
120 os <<
"\t\t\\node [align=center] (" << sanitizer(entry.first) <<
") at (" << (xBase + curX) <<
"," << level <<
") {" << entry.second.data.data(
step) <<
"};"<< std::endl;
121 os <<
"\t};" << std::endl;
125 for (
const auto& edge: entry.second.outgoing) {
127 if (!edge.second.showsOn(
step))
continue;
128 std::size_t cur =
step;
129 while (cur <
mStep && edge.second.showsOn(cur) && edge.second.data(cur) == edge.second.data(
step)) cur++;
130 os <<
"\t\\onslide<" << (
step+1) <<
"-" << (cur+1) <<
">{" << std::endl;
131 os <<
"\t\t\\path (" << sanitizer(entry.first) <<
") edge (" << sanitizer(edge.first) <<
") node {" << edge.second.data(
step) <<
"};" << std::endl;
132 os <<
"\t};" << std::endl;
140 std::size_t
width()
const override {
167 using Tree = carl::tree<UnifiedNode>;
168 using TreeIDs = std::map<std::string, Tree::iterator>;
175 int cur = it->position - int(it->subtreeWidth / 2);
176 for (
auto cit =
mTree.begin_children(it); cit !=
mTree.end_children(it); cit++) {
177 cit->position = cur + int(cit->subtreeWidth / 2);
179 cur += int(cit->subtreeWidth);
182 template<
typename It>
184 std::vector<It> children;
185 for (
auto it =
mTree.begin_children(source); it !=
mTree.end_children(source); it++) {
186 children.push_back(it);
188 std::sort(children.begin(), children.end(), [](
auto l,
auto r){ return l->id < r->id; });
189 for (
const auto& c: children) {
190 auto it = newTree.append(target, *c);
195 void setRoot(
const std::string& node,
const std::string& data) {
199 it =
mTreeIDs.emplace(node, rit).first;
200 it->second->id = node;
202 it->second->add(
mStep, data);
204 void addNode(std::size_t level,
const std::string& parent,
const std::string& node,
const std::string& data)
override {
205 if (level == 0)
return setRoot(node, data);
210 nit =
mTreeIDs.emplace(node, newit).first;
211 nit->second->id = node;
213 assert(
mTree.get_parent(nit->second) == pit);
214 assert(nit->second.depth() == level);
215 nit->second->add(
mStep, data);
217 void addEdge(
const std::string& src,
const std::string& dst,
const std::string& data)
override {
218 auto it =
mEdges.find(std::make_pair(src,dst));
222 it->second.add(
mStep, data);
226 newTree.setRoot(*
mTree.begin());
229 for (
auto it =
mTree.begin_postorder(); it !=
mTree.end_postorder(); it++) {
230 it->subtreeWidth = 0;
231 for (
auto cit =
mTree.begin_children(it); cit !=
mTree.end_children(it); cit++) {
232 it->subtreeWidth += cit->subtreeWidth;
234 if (it->subtreeWidth == 0) it->subtreeWidth = 1;
236 mTree.begin()->position = 0;
239 void writeTo(std::ostream& os,
int xBase)
const override {
241 for (
auto it =
mTree.begin(); it !=
mTree.end(); it++) {
243 if (!it->showsOn(
step))
continue;
244 std::size_t cur =
step;
245 while (cur < mStep && it->showsOn(cur) && it->data(cur) == it->data(
step)) cur++;
246 os <<
"\t\\onslide<" << (
step+1) <<
"-" << (cur+1) <<
">{" << std::endl;
247 os <<
"\t\t\\node [align=center] (" << sanitizer(it->id) <<
") at (" << (xBase + it->position) <<
"," << it.depth() <<
") {" << it->data(
step) <<
"};"<< std::endl;
248 os <<
"\t};" << std::endl;
252 for (
const auto& e:
mEdges) {
254 if (!e.second.showsOn(
step))
continue;
255 std::size_t cur =
step;
256 while (cur <
mStep && e.second.showsOn(cur) && e.second.data(cur) == e.second.data(
step)) cur++;
257 os <<
"\t\\onslide<" << (
step+1) <<
"-" << (cur+1) <<
">{" << std::endl;
258 os <<
"\t\t\\path (" << sanitizer(e.first.first) <<
") edge (" << sanitizer(e.first.second) <<
") node {" << e.second.data(
step) <<
"};" << std::endl;
259 os <<
"\t};" << std::endl;
264 virtual std::size_t
width()
const override {
265 return mTree.begin()->subtreeWidth;
279 std::stringstream ss;
284 std::stringstream ss;
285 if (asTex) ss <<
"$";
286 if (s.
value().is_numeric()) ss << s.
value().value();
287 else ss << s.
value().interval();
289 if (s.
isRoot()) ss <<
"_R";
296 if (s.
value().is_numeric()) val = carl::to_double(s.
value().value());
297 else val = carl::to_double(carl::center(s.
value().interval()));
298 if (val < 0) val = -1 / (val - 1);
300 return std::to_string(val);
302 template<
typename Tree,
typename It>
303 std::string
nodeID(
const Tree& t,
const It& it)
const {
304 std::stringstream ss;
305 for (
auto i = t.begin_path(it); i != t.end_path(); i++) {
310 std::string
polyID(std::size_t level, std::size_t
id)
const {
311 return std::to_string(level) +
"_" + std::to_string(
id);
314 template<
typename Pr
inter>
316 mPrinter.emplace(name,
new Printer());
319 template<
typename ID1,
typename ID2,
typename T>
320 void addNode(
const std::string& printer, std::size_t level,
const ID1& parent,
const ID2& node,
const T& data) {
323 template<
typename ID1,
typename ID2,
typename T>
324 void addEdge(
const std::string& printer,
const ID1& src,
const ID2& dst,
const T& data) {
330 const auto& t = l.getTree();
331 for (
auto node = t.begin(); node != t.end(); node++) {
335 const auto& p = t.get_parent(node);
343 for (std::size_t level = 1; level <= p.dim(); level++) {
344 for (std::size_t
id = 0;
id < p.size(level);
id++) {
345 if (!p.hasPolynomialById(level,
id))
continue;
346 const auto& poly = p.getPolynomialById(level,
id);
348 if (level == 0)
continue;
349 for (
const auto& parent: p.getOrigin(level,
id)) {
351 if (parent.first != parent.second) {
361 for (
auto& p:
mPrinter) p.second->step();
365 for (
auto& p:
mPrinter) p.second->layout();
368 void writeTo(
const std::string& filename)
const {
369 std::size_t width = 0;
371 width += p.second->width();
373 std::ofstream out(filename);
374 out <<
"\\documentclass[8pt]{beamer}" << std::endl;
375 out <<
"\\usepackage{tikz}" << std::endl;
376 out <<
"\\tikzset{font=\\tiny}" << std::endl;
377 out <<
"\\setbeamertemplate{navigation symbols}{}" << std::endl;
378 out <<
"\\begin{document}" << std::endl;
379 out <<
"\\eject \\pdfpagewidth=" << (0.5*double(width) + 2) <<
"cm" << std::endl;
380 out <<
"\\begin{frame}<1-" <<
mStep <<
">" << std::endl;
381 out <<
"\\begin{tikzpicture}[x=0.5cm, y=1cm]" << std::endl;
383 p.second->writeTo(out, 0);
385 out <<
"\\end{tikzpicture}" << std::endl;
386 out <<
"\\end{frame}" << std::endl;
387 out <<
"\\end{document}" << std::endl;
const RAN & value() const
virtual void writeTo(std::ostream &os, int xBase) const =0
virtual void addEdge(const std::string &src, const std::string &dst, const std::string &data)=0
virtual std::size_t width() const =0
virtual void addNode(std::size_t level, const std::string &parent, const std::string &node, const std::string &data)=0
std::string printableID(const std::string &raw, const std::string &prefix, std::map< std::string, std::string > &map) const
void writeTo(std::ostream &os, int xBase) const override
std::map< std::string, Level::iterator > NodeIDs
std::size_t width() const override
std::vector< Level > mData
void addEdge(const std::string &src, const std::string &dst, const std::string &data) override
std::map< std::string, Node > Level
void addNode(std::size_t level, const std::string &, const std::string &node, const std::string &data) override
std::string sampleID(const Sample &s) const
std::string asString(const T &t) const
std::string polyID(std::size_t level, std::size_t id) const
void addEdge(const std::string &printer, const ID1 &src, const ID2 &dst, const T &data)
void configure(const std::string &name)
TikzBasePrinter * getPrinter(const std::string &id)
void addLifting(const L &l)
void addProjection(const P &p)
std::map< std::string, TikzBasePrinter * > mPrinter
void addNode(const std::string &printer, std::size_t level, const ID1 &parent, const ID2 &node, const T &data)
std::string nodeID(const Tree &t, const It &it) const
void writeTo(const std::string &filename) const
std::string nodeValue(const Sample &s, bool asTex=false) const
void doLayout(const Tree::iterator &it)
void addNode(std::size_t level, const std::string &parent, const std::string &node, const std::string &data) override
carl::tree< UnifiedNode > Tree
std::map< std::pair< std::string, std::string >, UnifiedData > Edges
void setRoot(const std::string &node, const std::string &data)
void addEdge(const std::string &src, const std::string &dst, const std::string &data) override
virtual std::size_t width() const override
std::map< std::string, Tree::iterator > TreeIDs
void reorderTree(Tree &newTree, const It &source, const It &target) const
void writeTo(std::ostream &os, int xBase) const override
void sort(T *array, int size, LessThan lt)
std::vector< T > prefix(const std::vector< T > vars, std::size_t prefixSize)
Class to create the formulas for axioms.
std::map< std::string, std::string > mMap
std::string operator()(const std::string &raw)
IDSanitizer(const std::string &prefix)
std::map< std::string, UnifiedData > outgoing
void add(std::size_t step, const std::string &data)
friend std::ostream & operator<<(std::ostream &os, const UnifiedNode &un)
bool showsOn(std::size_t step) const
const std::string & data(std::size_t step) const
const std::string & data(std::size_t step) const
std::vector< std::optional< std::string > > steps
void add(std::size_t step, const std::string &data)
bool showsOn(std::size_t step) const