Introduce mealy_prod

Product between mealy machines
with propagation of synthesis outputs
and additional assertions.
Currently it only supports input complete machines

* spot/twaalgos/mealy_machine.cc,
  spot/twaalgos/mealy_machine.hh: Here
* bin/ltlsynt.cc: Use
* tests/python/except.py,
  tests/python/synthesis.ipynb: Test
This commit is contained in:
Philipp Schlehuber-Caissier 2022-03-18 01:02:45 +01:00
parent 5cd0ce14b0
commit 86de4d4052
5 changed files with 288 additions and 16 deletions

View file

@ -545,7 +545,8 @@ namespace
&& "ltlsynt: Cannot handle TGBA as strategy."); && "ltlsynt: Cannot handle TGBA as strategy.");
tot_strat = mealy_machines.front().mealy_like; tot_strat = mealy_machines.front().mealy_like;
for (size_t i = 1; i < mealy_machines.size(); ++i) for (size_t i = 1; i < mealy_machines.size(); ++i)
tot_strat = spot::product(tot_strat, mealy_machines[i].mealy_like); tot_strat = spot::mealy_product(tot_strat,
mealy_machines[i].mealy_like);
printer.print(tot_strat, timer_printer_dummy); printer.print(tot_strat, timer_printer_dummy);
} }

View file

@ -34,6 +34,7 @@
#include <spot/misc/minato.hh> #include <spot/misc/minato.hh>
#include <spot/twaalgos/game.hh> #include <spot/twaalgos/game.hh>
#include <spot/twaalgos/hoa.hh> #include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/product.hh>
#include <spot/twaalgos/synthesis.hh> #include <spot/twaalgos/synthesis.hh>
#include <picosat/picosat.h> #include <picosat/picosat.h>
@ -55,6 +56,7 @@
namespace namespace
{ {
using namespace spot;
bool is_deterministic_(const std::vector<bdd>& ins) bool is_deterministic_(const std::vector<bdd>& ins)
{ {
const unsigned n_ins = ins.size(); const unsigned n_ins = ins.size();
@ -64,6 +66,24 @@ namespace
return false; return false;
return true; return true;
} }
bool is_complete_(const const_twa_graph_ptr& m,
const bdd& outs)
{
auto* sp = m->get_named_prop<region_t>("state-player");
const auto N = m->num_states();
for (auto s = 0u; s < N; ++s)
{
if (sp && sp->at(s))
continue; // No need tpo check player states
bdd all_cond = bddfalse;
for (const auto& e : m->out(s))
all_cond |= bdd_exist(e.cond, outs);
if (all_cond != bddtrue)
return false;
}
return true;
}
} }
@ -3843,4 +3863,38 @@ namespace spot
return true; return true;
} }
twa_graph_ptr
mealy_product(const const_twa_graph_ptr& left,
const const_twa_graph_ptr& right)
{
bdd outs[] = {get_synthesis_outputs(left),
get_synthesis_outputs(right)};
#ifndef NDEBUG
for (const auto& [m, n, o] : {std::tuple{left, "left", outs[0]},
{right, "right", outs[1]}})
{
if (!is_mealy(m))
throw std::runtime_error(std::string("mealy_prod(): ") + n
+ " is not a mealy machine");
if (!is_complete_(m, o))
throw std::runtime_error(std::string("mealy_prod(): ") + n
+ " is not input complete");
}
#endif
auto p = product(left, right);
bdd pouts = outs[0] & outs[1];
set_synthesis_outputs(p, pouts);
#ifndef NDEBUG
if (!is_mealy(p))
throw std::runtime_error("mealy_prod(): Prooduct is not mealy");
if (!is_complete_(p, pouts))
throw std::runtime_error("mealy_prod(): Prooduct is not input complete. "
"Incompatible machines?");
#endif
return p;
}
} }

View file

@ -128,4 +128,14 @@ namespace spot
is_split_mealy_specialization(const_twa_graph_ptr left, is_split_mealy_specialization(const_twa_graph_ptr left,
const_twa_graph_ptr right, const_twa_graph_ptr right,
bool verbose = false); bool verbose = false);
/// \brief Product between two mealy machines \a left and \a right.
/// \pre The machines have to be both either split or unsplit,
/// input complete and compatible. All of this is check by assertion
/// \result The mealy machine representing the shared behaviour.
/// The resulting machine has the same class (mealy/separated/split)
/// as the input machines
SPOT_API twa_graph_ptr
mealy_product(const const_twa_graph_ptr& left,
const const_twa_graph_ptr& right);
} }

View file

@ -331,3 +331,20 @@ except RuntimeError as e:
tc.assertIn("already registered", se) tc.assertIn("already registered", se)
else: else:
report_missing_exception() report_missing_exception()
si = spot.synthesis_info()
si.s = spot.synthesis_info.algo_LAR
g1 = spot.ltl_to_game("G((i0 xor i1) <-> o0)", ["o0"], si)
g2 = spot.ltl_to_game("G((i0 xor i1) <-> (!o0 & !o1))", ["o0", "o1"], si)
spot.solve_game(g1)
spot.solve_game(g2)
strat1 = spot.solved_game_to_separated_mealy(g1)
strat2 = spot.solved_game_to_separated_mealy(g2)
try:
stratcomp = spot.mealy_product(strat1, strat2)
except RuntimeError as e:
se = str(e)
tc.assertIn("Incompatible", se)
else:
report_missing_exception()

View file

@ -696,7 +696,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc5ec2bf930> >" "<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f05083f22a0> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -2714,7 +2714,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7fc5ec2bfc00> >" "<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7f05083a6900> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -3027,7 +3027,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc5dc8463f0> >" "<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f05082c7a20> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -3102,7 +3102,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc5ec2bf990> >" "<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f05083f2300> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -3179,7 +3179,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7fc5ec2bffc0> >" "<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7f05083f28d0> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -3306,7 +3306,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7fc5dc846f30> >" "<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7f05083a64b0> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -3327,8 +3327,13 @@
"It can happen that the complete specification of the controller can be separated into sub-specifications with DISJOINT output propositions, see Finkbeiner et al. Specification Decomposition for Reactive Synthesis.\n", "It can happen that the complete specification of the controller can be separated into sub-specifications with DISJOINT output propositions, see Finkbeiner et al. Specification Decomposition for Reactive Synthesis.\n",
"This results in multiple Mealy machines which have to be converted into one single AIG circuit.\n", "This results in multiple Mealy machines which have to be converted into one single AIG circuit.\n",
"\n", "\n",
"This can be done using the function `mealy_machines_to_aig()`, which takes a vector of separated Mealy machines as argument.\n", "This can be done in two ways:\n",
"In order for this to work, all Mealy machines need to share the same `bdd_dict`. This can be ensured by passing a common options strucuture." "\n",
"1. Using the function `mealy_machines_to_aig()`, which takes a vector of separated mealy machines as argument.\n",
"2. Combine the mealy machines into one before passing it to `mealy_machine_to aig(). This currently only supports input complete machines of the same type (mealy/separated mealy/split mealy)\n",
"\n",
"Note that the method version is usually preferable as it is faster.\n",
"Also note that in order for this to work, all mealy machines need to share the same `bdd_dict`. This can be ensured by passing a common options strucuture."
] ]
}, },
{ {
@ -3623,7 +3628,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Circuit implementing both machines:\n" "Circuit implementing both machines from a vector of machines:\n"
] ]
}, },
{ {
@ -3733,7 +3738,185 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7fc5ec237ed0> >" "<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7f05083f2fc0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Combining the two machines into one.\n"
]
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.43.0 (0)\n",
" -->\n",
"<!-- Pages: 1 -->\n",
"<svg width=\"204pt\" height=\"126pt\"\n",
" viewBox=\"0.00 0.00 204.00 126.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1.0 1.0) rotate(0) translate(4 122)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-122 200,-122 200,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"98\" cy=\"-18\" rx=\"23.3\" ry=\"18\"/>\n",
"<text text-anchor=\"start\" x=\"88\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">0,0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M37.77,-18C39.45,-18 53.29,-18 67.17,-18\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"74.36,-18 67.36,-21.15 70.86,-18 67.36,-18 67.36,-18 67.36,-18 70.86,-18 67.36,-14.85 74.36,-18 74.36,-18\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M94.38,-36.15C93.83,-45.54 95.03,-54 98,-54 100.18,-54 101.41,-49.44 101.69,-43.3\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"101.62,-36.15 104.84,-43.12 101.65,-39.65 101.69,-43.15 101.69,-43.15 101.69,-43.15 101.65,-39.65 98.54,-43.18 101.62,-36.15 101.62,-36.15\"/>\n",
"<polygon fill=\"#e9f4fb\" stroke=\"transparent\" points=\"2,-55.5 2,-74.5 120,-74.5 120,-55.5 2,-55.5\"/>\n",
"<text text-anchor=\"start\" x=\"4\" y=\"-61.3\" font-family=\"Lato\" font-size=\"14.00\">(!i0 &amp; !i1) | (i0 &amp; i1)</text>\n",
"<text text-anchor=\"start\" x=\"124\" y=\"-61.3\" font-family=\"Lato\" font-size=\"14.00\">/</text>\n",
"<polygon fill=\"#ffe5f1\" stroke=\"transparent\" points=\"135,-55.5 135,-74.5 194,-74.5 194,-55.5 135,-55.5\"/>\n",
"<text text-anchor=\"start\" x=\"137\" y=\"-61.3\" font-family=\"Lato\" font-size=\"14.00\">!o0 &amp; o1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M92.2,-35.71C88.68,-54.65 90.62,-77 98,-77 104.46,-77 106.75,-59.89 104.86,-42.92\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"103.8,-35.71 107.93,-42.18 104.31,-39.17 104.82,-42.64 104.82,-42.64 104.82,-42.64 104.31,-39.17 101.7,-43.1 103.8,-35.71 103.8,-35.71\"/>\n",
"<polygon fill=\"#e9f4fb\" stroke=\"transparent\" points=\"2,-78.5 2,-97.5 120,-97.5 120,-78.5 2,-78.5\"/>\n",
"<text text-anchor=\"start\" x=\"4\" y=\"-84.3\" font-family=\"Lato\" font-size=\"14.00\">(!i0 &amp; i1) | (i0 &amp; !i1)</text>\n",
"<text text-anchor=\"start\" x=\"124\" y=\"-84.3\" font-family=\"Lato\" font-size=\"14.00\">/</text>\n",
"<polygon fill=\"#ffe5f1\" stroke=\"transparent\" points=\"135,-78.5 135,-97.5 194,-97.5 194,-78.5 135,-78.5\"/>\n",
"<text text-anchor=\"start\" x=\"137\" y=\"-84.3\" font-family=\"Lato\" font-size=\"14.00\">o0 &amp; !o1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f05082c7ba0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.43.0 (0)\n",
" -->\n",
"<!-- Pages: 1 -->\n",
"<svg width=\"202pt\" height=\"289pt\"\n",
" viewBox=\"0.00 0.00 202.39 289.50\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1.0 1.0) rotate(0) translate(4 285.5)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-285.5 198.39,-285.5 198.39,4 -4,4\"/>\n",
"<!-- 6 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>6</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"70.2\" cy=\"-100\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"70.2\" y=\"-96.3\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 10 -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>10</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"97.2\" cy=\"-176.75\" rx=\"23\" ry=\"23\"/>\n",
"<text text-anchor=\"middle\" x=\"97.2\" y=\"-173.05\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;10 -->\n",
"<g id=\"edge7\" class=\"edge\">\n",
"<title>6&#45;&gt;10</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M76.05,-117.22C79.24,-126.05 83.28,-137.22 86.97,-147.44\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"88.34\" cy=\"-151.24\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>8</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"124.2\" cy=\"-100\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"124.2\" y=\"-96.3\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;10 -->\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>8&#45;&gt;10</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M118.34,-117.22C115.15,-126.05 111.11,-137.22 107.42,-147.44\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"106.05\" cy=\"-151.24\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<!-- o0 -->\n",
"<g id=\"node4\" class=\"node\">\n",
"<title>o0</title>\n",
"<polygon fill=\"#ffe5f1\" stroke=\"black\" points=\"44.2,-235.5 88.59,-270 -0.2,-270 44.2,-235.5\"/>\n",
"<text text-anchor=\"middle\" x=\"44.2\" y=\"-254.8\" font-family=\"Times,serif\" font-size=\"14.00\">o0</text>\n",
"</g>\n",
"<!-- 10&#45;&gt;o0 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>10&#45;&gt;o0:s</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M77.46,-188.75C64.51,-197.36 49.25,-210.62 45.22,-227.13\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"44.68\" cy=\"-231.53\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<!-- o1 -->\n",
"<g id=\"node5\" class=\"node\">\n",
"<title>o1</title>\n",
"<polygon fill=\"#ffe5f1\" stroke=\"black\" points=\"150.2,-235.5 194.59,-270 105.8,-270 150.2,-235.5\"/>\n",
"<text text-anchor=\"middle\" x=\"150.2\" y=\"-254.8\" font-family=\"Times,serif\" font-size=\"14.00\">o1</text>\n",
"</g>\n",
"<!-- 10&#45;&gt;o1 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>10&#45;&gt;o1:s</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M116.93,-188.75C129.41,-197.04 144.03,-209.66 148.69,-225.35\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"145.27,-226.12 150.2,-235.5 152.19,-225.09 145.27,-226.12\"/>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node6\" class=\"node\">\n",
"<title>2</title>\n",
"<polygon fill=\"#e9f4fb\" stroke=\"black\" points=\"49.2,-46 10.2,-11.5 88.19,-11.5 49.2,-46\"/>\n",
"<text text-anchor=\"middle\" x=\"49.2\" y=\"-19.3\" font-family=\"Times,serif\" font-size=\"14.00\">i0</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;6 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>2&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M54.17,-41.77C56.92,-51.58 60.37,-63.89 63.36,-74.59\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"64.46\" cy=\"-78.53\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<!-- 2&#45;&gt;8 -->\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>2&#45;&gt;8</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M60.91,-35.72C72.59,-47.4 90.74,-65.55 104.61,-79.42\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"102.27,-82.02 111.81,-86.62 107.22,-77.07 102.27,-82.02\"/>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>4</title>\n",
"<polygon fill=\"#e9f4fb\" stroke=\"black\" points=\"145.2,-46 106.2,-11.5 184.19,-11.5 145.2,-46\"/>\n",
"<text text-anchor=\"middle\" x=\"145.2\" y=\"-19.3\" font-family=\"Times,serif\" font-size=\"14.00\">i1</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;6 -->\n",
"<g id=\"edge4\" class=\"edge\">\n",
"<title>4&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M133.48,-35.72C121.8,-47.4 103.65,-65.55 89.78,-79.42\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"87.18,-77.07 82.58,-86.62 92.13,-82.02 87.18,-77.07\"/>\n",
"</g>\n",
"<!-- 4&#45;&gt;8 -->\n",
"<g id=\"edge6\" class=\"edge\">\n",
"<title>4&#45;&gt;8</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M140.22,-41.77C137.47,-51.58 134.03,-63.89 131.03,-74.59\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"129.93\" cy=\"-78.53\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7f05082cff00> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -3753,9 +3936,16 @@
"strat2 = spot.solved_game_to_separated_mealy(g2)\n", "strat2 = spot.solved_game_to_separated_mealy(g2)\n",
"print(\"Reduced strategies:\")\n", "print(\"Reduced strategies:\")\n",
"display_inline(strat1, strat2)\n", "display_inline(strat1, strat2)\n",
"print(\"Circuit implementing both machines:\")\n", "#Method 1\n",
"print(\"Circuit implementing both machines from a vector of machines:\")\n",
"aig = spot.mealy_machines_to_aig([strat1, strat2], \"isop\")\n", "aig = spot.mealy_machines_to_aig([strat1, strat2], \"isop\")\n",
"display(aig)" "display(aig)\n",
"#Method 2\n",
"strat_comb = spot.mealy_product(strat1, strat2)\n",
"print(\"Combining the two machines into one.\")\n",
"display(strat_comb)\n",
"aig_comb = spot.mealy_machine_to_aig(strat_comb, \"isop\")\n",
"display(aig_comb)"
] ]
}, },
{ {
@ -3906,7 +4096,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7fc5ec2bf390> >" "<spot.aig; proxy of <Swig Object of type 'spot::aig_ptr *' at 0x7f05082c7660> >"
] ]
}, },
"metadata": {}, "metadata": {},
@ -4030,7 +4220,7 @@
"</svg>\n" "</svg>\n"
], ],
"text/plain": [ "text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc5dc846690> >" "<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f05082c7690> >"
] ]
}, },
"execution_count": 16, "execution_count": 16,
@ -4419,7 +4609,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.2" "version": "3.8.10"
} }
}, },
"nbformat": 4, "nbformat": 4,