Renaming and clean up

"Strategy" was used for mealy machines and game strategies a like.
Introduced the notion of mealy machine in three different flavors:
mealy machine: twa_graph with synthesis-outputs
separated mealy machine: mealy machine and all transitions
have conditions of the form (bdd over inputs)&(bdd over outputs)
split mealy machine: mealy machine that alternates between
env and player states. Needs state-players

* bin/ltlsynt.cc: renaming
* python/spot/impl.i: Add vector for const_twa_graph_ptr
* spot/twaalgos/aiger.cc,
spot/twaalgos/aiger.hh: Adapting functions
* spot/twaalgos/mealy_machine.cc,
spot/twaalgos/mealy_machine.hh: Add test functions and
propagate properties correctly. Adjust for names
* spot/twaalgos/synthesis.cc,
spot/twaalgos/synthesis.hh: Removing unnecessary functions
and adapt to new names
* tests/python/aiger.py,
tests/python/_mealy.ipynb,
tests/python/mealy.py,
tests/python/synthesis.ipynb: Adjust
This commit is contained in:
philipp 2021-11-04 00:24:17 +01:00
parent 6ebe3d7447
commit 98ebbea17e
12 changed files with 3376 additions and 3038 deletions

View file

@ -3,7 +3,6 @@
{
"cell_type": "code",
"execution_count": 1,
"id": "99baf49c",
"metadata": {},
"outputs": [],
"source": [
@ -13,7 +12,6 @@
},
{
"cell_type": "markdown",
"id": "066489fd",
"metadata": {},
"source": [
"Test the Mealy printer."
@ -22,7 +20,6 @@
{
"cell_type": "code",
"execution_count": 2,
"id": "08d7d512",
"metadata": {},
"outputs": [],
"source": [
@ -32,7 +29,6 @@
{
"cell_type": "code",
"execution_count": 3,
"id": "4e5b66f4",
"metadata": {},
"outputs": [
{
@ -53,7 +49,6 @@
{
"cell_type": "code",
"execution_count": 4,
"id": "ce2ff962",
"metadata": {},
"outputs": [
{
@ -140,7 +135,7 @@
"</svg>\n"
],
"text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3d8c04f720> >"
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f300caabba0> >"
]
},
"execution_count": 4,
@ -155,17 +150,15 @@
{
"cell_type": "code",
"execution_count": 5,
"id": "3bcbeef2",
"metadata": {},
"outputs": [],
"source": [
"x = spot.apply_strategy(g, True, False)"
"x = spot.solved_game_to_separated_mealy(g)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "47d298f0",
"metadata": {},
"outputs": [
{
@ -220,7 +213,7 @@
"</svg>\n"
],
"text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3d8c04f630> >"
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f300c179300> >"
]
},
"execution_count": 6,
@ -235,7 +228,6 @@
{
"cell_type": "code",
"execution_count": 7,
"id": "f0d098ac",
"metadata": {},
"outputs": [],
"source": [
@ -245,7 +237,6 @@
{
"cell_type": "code",
"execution_count": 8,
"id": "adf92ac7",
"metadata": {},
"outputs": [
{
@ -294,7 +285,7 @@
"</svg>\n"
],
"text/plain": [
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3d8c04f630> >"
"<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f300c179300> >"
]
},
"execution_count": 8,
@ -305,96 +296,6 @@
"source": [
"x"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "6e8cd892",
"metadata": {},
"outputs": [
{
"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=\"247pt\" height=\"204pt\"\n",
" viewBox=\"0.00 0.00 247.00 204.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 200)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-200 243,-200 243,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"8\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"29\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#6a3d9a\">❸</text>\n",
"<text text-anchor=\"start\" x=\"45\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\">) | (Fin(</text>\n",
"<text text-anchor=\"start\" x=\"87\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff7f00\">❷</text>\n",
"<text text-anchor=\"start\" x=\"103\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\">) &amp; (Inf(</text>\n",
"<text text-anchor=\"start\" x=\"149\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"<text text-anchor=\"start\" x=\"165\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\">) | Fin(</text>\n",
"<text text-anchor=\"start\" x=\"203\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"219\" y=\"-181.8\" font-family=\"Lato\" font-size=\"14.00\">)))</text>\n",
"<text text-anchor=\"start\" x=\"64\" y=\"-167.8\" font-family=\"Lato\" font-size=\"14.00\">[parity max odd 4]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"123\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"123\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">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=\"M64.17,-18C66.01,-18 82.75,-18 97.75,-18\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"104.9,-18 97.9,-21.15 101.4,-18 97.9,-18 97.9,-18 97.9,-18 101.4,-18 97.9,-14.85 104.9,-18 104.9,-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=\"M119.4,-35.78C118.79,-45.31 119.99,-54 123,-54 125.21,-54 126.44,-49.32 126.7,-43.05\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"126.6,-35.78 129.85,-42.74 126.65,-39.28 126.7,-42.78 126.7,-42.78 126.7,-42.78 126.65,-39.28 123.55,-42.83 126.6,-35.78 126.6,-35.78\"/>\n",
"<polygon fill=\"#e9f4fb\" stroke=\"transparent\" points=\"72,-77 72,-96 115,-96 115,-77 72,-77\"/>\n",
"<text text-anchor=\"start\" x=\"74\" y=\"-82.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"<text text-anchor=\"start\" x=\"119\" y=\"-82.8\" font-family=\"Lato\" font-size=\"14.00\">/</text>\n",
"<polygon fill=\"#ffe5f1\" stroke=\"transparent\" points=\"130,-77 130,-96 174,-96 174,-77 130,-77\"/>\n",
"<text text-anchor=\"start\" x=\"132\" y=\"-82.8\" font-family=\"Lato\" font-size=\"14.00\">!b &amp; !d</text>\n",
"<text text-anchor=\"start\" x=\"115\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#6a3d9a\">❸</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=\"M117.81,-35.4C113.5,-60.54 115.23,-98 123,-98 130.08,-98 132.14,-66.97 129.21,-42.44\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"128.19,-35.4 132.31,-41.88 128.69,-38.86 129.19,-42.33 129.19,-42.33 129.19,-42.33 128.69,-38.86 126.07,-42.78 128.19,-35.4 128.19,-35.4\"/>\n",
"<polygon fill=\"#e9f4fb\" stroke=\"transparent\" points=\"86,-121 86,-140 115,-140 115,-121 86,-121\"/>\n",
"<text text-anchor=\"start\" x=\"88\" y=\"-126.8\" font-family=\"Lato\" font-size=\"14.00\">a | c</text>\n",
"<text text-anchor=\"start\" x=\"119\" y=\"-126.8\" font-family=\"Lato\" font-size=\"14.00\">/</text>\n",
"<polygon fill=\"#ffe5f1\" stroke=\"transparent\" points=\"130,-121 130,-140 161,-140 161,-121 130,-121\"/>\n",
"<text text-anchor=\"start\" x=\"132\" y=\"-126.8\" font-family=\"Lato\" font-size=\"14.00\">b | d</text>\n",
"<text text-anchor=\"start\" x=\"115.5\" y=\"-105.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#6a3d9a\">❸</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 0x7f3d76e561e0> >"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.apply_strategy(g, True, True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5948f923",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
@ -413,7 +314,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
"version": "3.8.10"
}
},
"nbformat": 4,

View file

@ -3339,9 +3339,10 @@ for strat_string, (ins_str, outs_str) in strats:
for ss in [""] + [f"+sub{ii}" for ii in range(3)]:
for ddx in ["", "+dc"]:# todo prob here
for uud in ["", "+ud"]:
aig = spot.strategy_to_aig(strat, m+ss+ddx+uud)
aig = spot.mealy_machine_to_aig(strat, m+ss+ddx+uud)
strat2_s = aig.as_automaton(True)
if not spot.is_mealy_specialization(strat_s, strat2_s):
if not spot.is_split_mealy_specialization(strat_s,
strat2_s):
print(f"Mode is {m+ss+ddx+uud}")
print(f"""Strat is \n{strat_s.to_str("hoa")}""")
print(f"""Aig as aut is \n{strat2_s.to_str("hoa")}""")
@ -3361,7 +3362,7 @@ for aout in outs_str:
outs &= buddy.bdd_ithvar(strat.register_ap(aout))
spot.set_synthesis_outputs(strat, outs)
aig = spot.strategy_to_aig(strat, "isop")
aig = spot.mealy_machine_to_aig(strat, "isop")
ins = [True, False, False, False, True, True, True, True, True, True]
exp_latches = [(False, False),

View file

@ -43,9 +43,10 @@ spot.set_synthesis_outputs(a, o1&o2)
b = spot.minimize_mealy(a)
assert(list(spot.get_state_players(b)).count(False) == 2)
assert(spot.is_mealy_specialization(a, b))
assert(spot.is_split_mealy_specialization(a, b))
test_auts = [("""HOA: v1
test_auts = [
("""HOA: v1
States: 22
Start: 0
AP: 6 "i0" "i1" "i2" "i3" "o0" "o1"
@ -360,13 +361,6 @@ for (mealy_str, nenv_min) in test_auts:
mealy = spot.automaton(mealy_str)
mealy.merge_edges()
mealy_min_ks = spot.minimize_mealy(mealy, -1, True)
mealy_min_us = spot.minimize_mealy(mealy, -1, False)
n_e = sum([s == 0 for s in spot.get_state_players(mealy_min_ks)])
assert(n_e == nenv_min)
assert(mealy_min_us.num_states() == nenv_min)
assert(spot.is_mealy_specialization(mealy, mealy_min_ks, True))
outs = buddy.bddtrue
ins = buddy.bddtrue
@ -378,8 +372,20 @@ for (mealy_str, nenv_min) in test_auts:
ins = ins & buddy.bdd_ithvar(mealy.register_ap(aap.ap_name()))
else:
assert("""Aps must start with either "i" or "o".""")
mealy_min_us_s = spot.split_2step(mealy_min_us, outs, False)
assert(spot.is_mealy_specialization(mealy, mealy_min_us_s, True))
spot.set_synthesis_outputs(mealy, outs)
mealy_min_ks = spot.minimize_mealy(mealy, -1)
n_e = sum([s == 0 for s in spot.get_state_players(mealy_min_ks)])
assert(n_e == nenv_min)
assert(spot.is_split_mealy_specialization(mealy, mealy_min_ks))
# Test un- and resplit
tmp = spot.unsplit_2step(mealy_min_ks)
mealy_min_rs = spot.split_2step(tmp, spot.get_synthesis_outputs(tmp), False)
assert(spot.is_split_mealy_specialization(mealy, mealy_min_rs, True))
assert(spot.are_equivalent(mealy_min_ks, mealy_min_rs))
# Testing bisimulation (with output assignment)
@ -498,13 +504,23 @@ State: 16
--END--""")
# Build an equivalent deterministic monitor
min_equiv = spot.minimize_mealy_fast(aut, False)
# ;
# ;
#
spot.set_synthesis_outputs(aut,
buddy.bdd_ithvar(
aut.register_ap("u02alarm29control02alarm29control"))\
& buddy.bdd_ithvar(
aut.register_ap("u02alarm29control0f1d2alarm29turn2on1b"))\
& buddy.bdd_ithvar(
aut.register_ap("u02alarm29control0f1d2alarm29turn2off1b")))
min_equiv = spot.reduce_mealy(aut, False)
assert min_equiv.num_states() == 6
assert spot.are_equivalent(min_equiv, aut)
# Build an automaton that recognizes a subset of the language of the original
# automaton
min_sub = spot.minimize_mealy_fast(aut, True)
min_sub = spot.reduce_mealy(aut, True)
assert min_sub.num_states() == 5
prod = spot.product(spot.complement(aut), min_sub)
assert spot.generic_emptiness_check(prod)
@ -531,6 +547,8 @@ State: 3
--END--
""")
spot.set_synthesis_outputs(aut, buddy.bdd_ithvar(aut.register_ap("b")))
exp = """HOA: v1
States: 1
Start: 0
@ -544,7 +562,7 @@ State: 0
--END--"""
# An example that shows that we should not build a tree when we use inclusion.
res = spot.minimize_mealy_fast(aut, True)
res = spot.reduce_mealy(aut, True)
assert res.to_str() == exp
aut = spot.automaton("""
@ -569,6 +587,8 @@ State: 3
--END--
""")
spot.set_synthesis_outputs(aut, buddy.bdd_ithvar(aut.register_ap("b")))
exp = """HOA: v1
States: 2
Start: 0
@ -585,7 +605,7 @@ State: 1
[0&1] 1
--END--"""
res = spot.minimize_mealy_fast(aut, True)
res = spot.reduce_mealy(aut, True)
assert res.to_str() == exp

File diff suppressed because it is too large Load diff