diff --git a/spot/twaalgos/mealy_machine.cc b/spot/twaalgos/mealy_machine.cc index 1126ad8e0..df9ad6017 100644 --- a/spot/twaalgos/mealy_machine.cc +++ b/spot/twaalgos/mealy_machine.cc @@ -36,7 +36,9 @@ #include #include #include +#include #include +#include #include @@ -869,7 +871,7 @@ namespace split_cstr_time, prob_init_build_time, sat_time, build_time, refine_time, total_time; long long n_classes, n_refinement, n_lit, n_clauses, - n_iteration, n_bisim_let, n_min_states, done; + n_iteration, n_letters_part, n_bisim_let, n_min_states, done; std::string task; const std::string instance; @@ -892,6 +894,7 @@ namespace , n_lit{-1} , n_clauses{-1} , n_iteration{-1} + , n_letters_part{-1} , n_bisim_let{-1} , n_min_states{-1} , done{-1} @@ -935,8 +938,8 @@ namespace << "player_incomp_time,incomp_time,split_all_let_time," << "split_min_let_time,split_cstr_time,prob_init_build_time," << "sat_time,build_time,refine_time,total_time,n_classes," - << "n_refinement,n_lit,n_clauses,n_iteration,n_bisim_let," - << "n_min_states,done\n"; + << "n_refinement,n_lit,n_clauses,n_iteration,n_letters_part," + << "n_bisim_let,n_min_states,done\n"; } assert(!task.empty()); @@ -965,6 +968,7 @@ namespace f(ss, n_lit); f(ss, n_clauses); f(ss, n_iteration); + f(ss, n_letters_part); f(ss, n_bisim_let); f(ss, n_min_states); f(ss, done, false); @@ -1280,8 +1284,8 @@ namespace } square_matrix - compute_incomp(const_twa_graph_ptr mm, const unsigned n_env, - satprob_info& si) + compute_incomp_impl_(const_twa_graph_ptr mm, const unsigned n_env, + satprob_info& si, bool is_partitioned) { const unsigned n_tot = mm->num_states(); @@ -1292,20 +1296,6 @@ namespace // Have two states already been checked for common pred square_matrix checked_pred(n_env, false); - // We also need a transposed_graph - auto mm_t = make_twa_graph(mm->get_dict()); - mm_t->copy_ap_of(mm); - mm_t->new_states(n_env); - - for (unsigned s = 0; s < n_env; ++s) - { - for (const auto& e_env : mm->out(s)) - { - unsigned dst_env = mm->out(e_env.dst).begin()->dst; - mm_t->new_edge(dst_env, s, e_env.cond); - } - } - // Utility function auto get_cond = [&mm](unsigned s)->const bdd& {return mm->out(s).begin()->cond; }; @@ -1367,15 +1357,28 @@ namespace #endif // direct incomp: Two env states can reach incompatible player states // under the same input + // The original graph mm is not sorted, and most of the + // sorting is not rentable + // However, bdd_have_common_assignment simply becomes equality auto direct_incomp = [&](unsigned s1, unsigned s2) { for (const auto& e1 : mm->out(s1)) for (const auto& e2 : mm->out(s2)) { + if (is_partitioned && (e1.cond != e2.cond)) + continue; if (!is_p_incomp(e1.dst - n_env, e2.dst - n_env)) continue; //Compatible -> no prob // Reachable under same letter? - if (bdd_have_common_assignment(e1.cond, e2.cond)) + if (is_partitioned) // -> Yes + { + trace << s1 << " and " << s2 << " directly incomp " + "due to successors " << e1.dst << " and " << e2.dst + << '\n'; + return true; + } + else if (!is_partitioned + && bdd_have_common_assignment(e1.cond, e2.cond)) { trace << s1 << " and " << s2 << " directly incomp " "due to successors " << e1.dst << " and " << e2.dst @@ -1388,7 +1391,27 @@ namespace // If two states can reach an incompatible state // under the same input, then they are incompatible as well - auto tag_predec = [&](unsigned s1, unsigned s2) + + // Version if the input is not partitioned + // We also need a transposed_graph + twa_graph_ptr mm_t = nullptr; + if (!is_partitioned) + { + mm_t = make_twa_graph(mm->get_dict()); + mm_t->copy_ap_of(mm); + mm_t->new_states(n_env); + + for (unsigned s = 0; s < n_env; ++s) + { + for (const auto& e_env : mm->out(s)) + { + unsigned dst_env = mm->out(e_env.dst).begin()->dst; + mm_t->new_edge(dst_env, s, e_env.cond); + } + } + } + + auto tag_predec_unpart = [&](unsigned s1, unsigned s2) { static std::vector> todo_; assert(todo_.empty()); @@ -1422,17 +1445,98 @@ namespace // Done tagging all pred }; + // Version of taging taking advantaged of partitioned conditions + struct S + { + }; + struct T + { + int id; + }; + std::unique_ptr> mm_t_part; + if (is_partitioned) + { + mm_t_part = std::make_unique>(n_env, mm->num_edges()); + mm_t_part->new_states(n_env); + + for (unsigned s = 0; s < n_env; ++s) + { + for (const auto& e_env : mm->out(s)) + { + unsigned dst_env = mm->out(e_env.dst).begin()->dst; + mm_t_part->new_edge(dst_env, s, e_env.cond.id()); + } + } + + // Now we need to sort the edge to ensure that + // the next algo works correctly + mm_t_part->sort_edges_srcfirst_([](const auto& e1, const auto& e2) + {return e1.id < e2.id; }); + mm_t_part->chain_edges_(); + } + + auto tag_predec_part = [&](unsigned s1, unsigned s2) + { + static std::vector> todo_; + assert(todo_.empty()); + + todo_.emplace_back(s1, s2); + + while (!todo_.empty()) + { + auto [i, j] = todo_.back(); + todo_.pop_back(); + if (checked_pred.get(i, j)) + continue; + // If predecs are already marked incomp + auto e_it_i = mm_t_part->out(i); + auto e_it_j = mm_t_part->out(j); + + auto e_it_i_e = e_it_i.end(); + auto e_it_j_e = e_it_j.end(); + + auto e_i = e_it_i.begin(); + auto e_j = e_it_j.begin(); + + // Joint iteration over both edge groups + while ((e_i != e_it_i_e) && (e_j != e_it_j_e)) + { + if (e_i->id < e_j->id) + ++e_i; + else if (e_j->id < e_i->id) + ++e_j; + else + { + assert(e_j->id == e_i->id); + trace << e_i->dst << " and " << e_j->dst << " tagged incomp" + " due to " << e_i->id << '\n'; + inc_env.set(e_i->dst, e_j->dst, true); + todo_.emplace_back(e_i->dst, e_j->dst); + ++e_i; + ++e_j; + } + } + checked_pred.set(i, j, true); + } + // Done tagging all pred + }; + for (unsigned s1 = 0; s1 < n_env; ++s1) for (unsigned s2 = s1 + 1; s2 < n_env; ++s2) { if (inc_env.get(s1, s2)) continue; // Already done + // Check if they are incompatible for some letter // We have to check all pairs of edges if (direct_incomp(s1, s2)) { inc_env.set(s1, s2, true); - tag_predec(s1, s2); + if (is_partitioned) + tag_predec_part(s1, s2); + else + tag_predec_unpart(s1, s2); + } } @@ -1442,9 +1546,38 @@ namespace #endif si.incomp_time = si.restart(); return inc_env; + } // incomp no partition + + square_matrix + compute_incomp(const_twa_graph_ptr mm, const unsigned n_env, + satprob_info& si, int max_letter_mult) + { + // Try to generate a graph with partitioned env transitions + auto mm2 = make_twa_graph(mm, twa::prop_set::all()); + set_state_players(mm2, get_state_players(mm)); + set_synthesis_outputs(mm2, get_synthesis_outputs(mm)); + + // todo get a good value for cutoff + auto relabel_maps + = partitioned_game_relabel_here(mm2, true, false, true, + false, -1u, max_letter_mult); + bool succ = !relabel_maps.env_map.empty(); + + si.n_letters_part = relabel_maps.env_map.size(); + +#ifdef TRACE + if (succ) + std::cout << "Relabeling succesfull with " << relabel_maps.env_map.size() + << " letters\n"; + else + std::cout << "Relabeling aborted\n"; +#endif + + return compute_incomp_impl_(succ ? const_twa_graph_ptr(mm2) : mm, + n_env, si, succ); } - struct part_sol_t + struct part_sol_t { std::vector psol; std::vector is_psol; @@ -1602,6 +1735,11 @@ namespace return std::make_pair(n_group, which_group); } + // Helper function + // Computes the set of all original letters implied by the leaves + // This avoids transposing the graph + + // Computes the letters of each group // Letters here means bdds such that for all valid // assignments of the bdd we go to the same dst from the same source @@ -1611,7 +1749,9 @@ namespace { //To avoid recalc std::set all_bdd; - std::set treated_bdd; + std::vector all_bdd_v; + std::unordered_map node2idx; + std::unordered_multimap>> sigma_map; @@ -1649,6 +1789,11 @@ namespace continue; else { + // Store bdds as vector for compatibility + all_bdd_v.clear(); // Note: sorted automatically by id + std::transform(all_bdd.begin(), all_bdd.end(), + std::back_inserter(all_bdd_v), + [](int i){return bdd_from_int(i); }); // Insert it already into the sigma_map trace << "Group " << groupidx << " generates a new alphabet\n"; sigma_map.emplace(std::piecewise_construct, @@ -1658,62 +1803,60 @@ namespace } } + // Result red.share_sigma_with.push_back(groupidx); red.all_letters.emplace_back(); auto& group_letters = red.all_letters.back(); - treated_bdd.clear(); + // Compute it + auto this_part = try_partition_me(all_bdd_v, -1u); + assert(this_part.relabel_succ); - for (unsigned s = 0; s < n_env; ++s) + // Transform it + // group_letters is pair + // There are as many new_letters as treated bdds in the partition + group_letters.clear(); + group_letters.reserve(this_part.treated.size()); + node2idx.clear(); + node2idx.reserve(this_part.treated.size()); + + for (const auto& [label, node] : this_part.treated) { - if (red.which_group[s] != groupidx) - continue; - for (const auto& e : mmw->out(s)) - { - bdd rcond = e.cond; - const int econd_id = rcond.id(); - trace << rcond << " - " << econd_id << std::endl; - if (treated_bdd.count(econd_id)) - { - trace << "Already treated" << std::endl; - continue; - } - treated_bdd.insert(econd_id); - - assert(rcond != bddfalse && "Deactivated edges are forbiden"); - // Check against all currently used "letters" - const size_t osize = group_letters.size(); - for (size_t i = 0; i < osize; ++i) - { - if (group_letters[i].first == rcond) - { - rcond = bddfalse; - group_letters[i].second.insert(econd_id); - break; - } - bdd inter = group_letters[i].first & rcond; - if (inter == bddfalse) - continue; // No intersection - if (group_letters[i].first == inter) - group_letters[i].second.insert(econd_id); - else - { - group_letters[i].first -= inter; - group_letters.emplace_back(inter, - group_letters[i].second); - group_letters.back().second.insert(econd_id); - } - - rcond -= inter; - // Early exit? - if (rcond == bddfalse) - break; - } - // Leftovers? - if (rcond != bddfalse) - group_letters.emplace_back(rcond, std::set{econd_id}); - } + node2idx[node] = group_letters.size(); + group_letters.emplace_back(std::piecewise_construct, + std::forward_as_tuple(label), + std::forward_as_tuple()); } + + // Go through the graph for each original letter + auto search_leaves + = [&ig = *this_part.ig, &group_letters, &node2idx] + (int orig_letter_id, unsigned s, auto&& search_leaves_) -> void + { + if (ig.state_storage(s).succ == 0) + { + // Leaf + unsigned idx = node2idx[s]; + auto& setidx = group_letters[idx].second; + setidx.emplace_hint(setidx.end(), orig_letter_id); + } + else + { + // Traverse + for (const auto& e : ig.out(s)) + search_leaves_(orig_letter_id, e.dst, search_leaves_); + } + }; + + const unsigned Norig = all_bdd_v.size(); + for (unsigned s = 0; s < Norig; ++s) + search_leaves(all_bdd_v[s].id(), s, search_leaves); + + // Verify that all letters imply at least one original letter + assert(std::all_of(group_letters.begin(), group_letters.end(), + [](const auto& l){return !l.second.empty(); })); + + #ifdef TRACE trace << "this group letters" << std::endl; auto sp = [&](const auto& c) @@ -3467,6 +3610,7 @@ namespace for (unsigned letter_idx = 0; letter_idx < n_ml; ++letter_idx) { const auto& ml_list = group_map[letter_idx]; + assert(ml_list.begin() != ml_list.end()); // Incompatibility is commutative // new / new constraints const auto it_end = ml_list.end(); @@ -3794,12 +3938,9 @@ namespace return minmach; } // while loop } // try_build_machine -} // namespace -namespace spot -{ - twa_graph_ptr minimize_mealy(const const_twa_graph_ptr& mm, - int premin) + twa_graph_ptr minimize_mealy_(const const_twa_graph_ptr& mm, + int premin, int max_letter_mult) { bdd outputs = ensure_mealy("minimize_mealy", mm); @@ -3866,8 +4007,9 @@ namespace spot si.reorg_time = si.restart(); // Compute incompatibility based on bdd - auto incompmat = compute_incomp(mmw, n_env, si); + auto incompmat = compute_incomp(mmw, n_env, si, max_letter_mult); #ifdef TRACE + std::cerr << "Final incomp mat\n"; incompmat.print(std::cerr); #endif @@ -3944,6 +4086,15 @@ namespace spot minmachine)); return minmachine; } +} // namespace + +namespace spot +{ + twa_graph_ptr minimize_mealy(const const_twa_graph_ptr& mm, + int premin) + { + return minimize_mealy_(mm, premin, 10); + } twa_graph_ptr minimize_mealy(const const_twa_graph_ptr& mm, @@ -3970,7 +4121,8 @@ namespace spot sat_dimacs_file = std::make_unique(dimacsfile); sat_instance_name = si.opt.get_str("satinstancename"); - auto res = minimize_mealy(mm, si.minimize_lvl-4); + auto res = minimize_mealy_(mm, si.minimize_lvl-4, + si.opt.get("max_letter_mult", 10)); sat_csv_file.reset(); sat_dimacs_file.reset(); return res; @@ -4161,7 +4313,7 @@ namespace spot reduce_mealy_here(m, minimize_lvl == 2); } else if (3 <= minimize_lvl) - m = minimize_mealy(m, minimize_lvl - 4); + m = minimize_mealy(m, si); // Convert to demanded output format bool is_split = m->get_named_prop("state-player"); diff --git a/spot/twaalgos/synthesis.cc b/spot/twaalgos/synthesis.cc index 88e22ff04..4e38efd5b 100644 --- a/spot/twaalgos/synthesis.cc +++ b/spot/twaalgos/synthesis.cc @@ -37,6 +37,7 @@ #include +#include // Helper function/structures for split_2step namespace{ @@ -1935,4 +1936,98 @@ namespace spot return res; } + namespace + { + const std::string in_mark_s("__AP_IN__"); + const std::string out_mark_s("__AP_OUT__"); + } + + game_relabeling_map + partitioned_game_relabel_here(twa_graph_ptr& arena, + bool relabel_env, + bool relabel_play, + bool split_env, + bool split_play, + unsigned max_letter, + unsigned max_letter_mult) + { + if (!arena) + throw std::runtime_error("arena is null."); + auto& arena_r = *arena; + + const auto& sp = get_state_players(arena); + bdd all_ap = arena->ap_vars(); + + if (std::find_if(arena->ap().cbegin(), arena->ap().cend(), + [](const auto& ap) + { + return ap.ap_name() == out_mark_s + || ap.ap_name() == in_mark_s; + }) != arena->ap().cend()) + throw std::runtime_error("partitioned_game_relabel_here(): " + "You can not use " + + in_mark_s + " or " + out_mark_s + + " as propositions if relabeling."); + + bdd out_mark = bdd_ithvar(arena_r.register_ap(out_mark_s)); + bdd in_mark = bdd_ithvar(arena_r.register_ap(in_mark_s)); + + bdd outs = get_synthesis_outputs(arena) & out_mark; + bdd ins = bdd_exist(all_ap, outs) & in_mark; + + for (auto& e : arena_r.edges()) + e.cond = e.cond & (sp[e.src] ? out_mark : in_mark); + + game_relabeling_map res; + + if (relabel_env) + res.env_map + = partitioned_relabel_here(arena, split_env, max_letter, + max_letter_mult, ins, "__nv_in"); + if (relabel_play) + res.player_map + = partitioned_relabel_here(arena, split_play, max_letter, + max_letter_mult, outs, "__nv_out"); + return res; + } + + void + relabel_game_here(twa_graph_ptr& arena, + game_relabeling_map& rel_maps) + { + if (!arena) + throw std::runtime_error("arena is null."); + auto& arena_r = *arena; + + // Check that it was partitioned_game_relabel_here + if (!((std::find_if(arena->ap().cbegin(), arena->ap().cend(), + [](const auto& ap) + { return ap.ap_name() == out_mark_s; }) + != arena->ap().cend()) + && (std::find_if(arena->ap().cbegin(), arena->ap().cend(), + [](const auto& ap) + { return ap.ap_name() == in_mark_s; })) + != arena->ap().cend())) + throw std::runtime_error("relabel_game_here(): " + + in_mark_s + " or " + out_mark_s + + " not registered with arena. " + "Not relabeled?"); + + if (!rel_maps.env_map.empty()) + relabel_here(arena, &rel_maps.env_map); + if (!rel_maps.player_map.empty()) + relabel_here(arena, &rel_maps.player_map); + + bdd dummy_ap = bdd_ithvar(arena_r.register_ap(in_mark_s)) + & bdd_ithvar(arena_r.register_ap(out_mark_s)); + + for (auto& e : arena_r.edges()) + e.cond = bdd_exist(e.cond, dummy_ap); + + arena_r.unregister_ap(arena_r.register_ap(in_mark_s)); + arena_r.unregister_ap(arena_r.register_ap(out_mark_s)); + + return; + } + } // spot diff --git a/spot/twaalgos/synthesis.hh b/spot/twaalgos/synthesis.hh index b1b7fdf1d..2d9c0600a 100644 --- a/spot/twaalgos/synthesis.hh +++ b/spot/twaalgos/synthesis.hh @@ -21,6 +21,7 @@ #include #include +#include #include namespace spot @@ -256,4 +257,39 @@ namespace spot SPOT_API bool solve_game(twa_graph_ptr arena, synthesis_info& gi); + struct SPOT_API game_relabeling_map + { + relabeling_map env_map; + relabeling_map player_map; + }; + + /// \ingroup synthesis + /// \brief Tries to relabel a SPLIT game \a arena using fresh propositions. + /// Can be applied to env or player depending on \a relabel_env + /// and \a relabel_play. The arguments \a split_env and \a split_play + /// determine whether or not env and player edges are to + /// be split into several transitions labelled by letters not conditions. + /// + /// \return pair of relabeling_map, first is for env, second is for player. + /// The maps are empty if no relabeling was performed + /// \note Can also be applied to split mealy machine. + /// \note partitioned_relabel_here can not be used directly if there are + /// T (true conditions) + SPOT_API game_relabeling_map + partitioned_game_relabel_here(twa_graph_ptr& arena, + bool relabel_env, + bool relabel_play, + bool split_env = false, + bool split_play = false, + unsigned max_letter = -1u, + unsigned max_letter_mult = -1u); + + /// \ingroup synthesis + /// \brief Undoes a relabeling done by partitioned_game_relabel_here. + /// A dedicated function is necessary in order to remove the + /// variables tagging env and player conditions + SPOT_API void + relabel_game_here(twa_graph_ptr& arena, + game_relabeling_map& rel_maps); + } diff --git a/tests/python/_mealy.ipynb b/tests/python/_mealy.ipynb index 9d7fe7d96..ebeeaacb7 100644 --- a/tests/python/_mealy.ipynb +++ b/tests/python/_mealy.ipynb @@ -129,7 +129,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc35aaa030> >" + " *' at 0x7f86481a2690> >" ] }, "execution_count": 4, @@ -209,7 +209,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc35aaa900> >" + " *' at 0x7f85f45cbb70> >" ] }, "execution_count": 6, @@ -283,7 +283,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc35aaa900> >" + " *' at 0x7f85f45cbb70> >" ] }, "execution_count": 8, @@ -387,7 +387,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc35ac20c0> >" + " *' at 0x7f861bfc8ae0> >" ] }, "execution_count": 9, @@ -532,7 +532,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc35ac2720> >" + " *' at 0x7f85f45efde0> >" ] }, "execution_count": 10, @@ -584,13 +584,13 @@ " split_cstr_time\n", " prob_init_build_time\n", " ...\n", - " refine_time\n", " total_time\n", " n_classes\n", " n_refinement\n", " n_lit\n", " n_clauses\n", " n_iteration\n", + " n_letters_part\n", " n_bisim_let\n", " n_min_states\n", " done\n", @@ -600,15 +600,15 @@ " \n", " 0\n", " presat\n", - " 25643.3\n", - " 1.112e-06\n", - " 4.588e-06\n", - " 9.888e-06\n", - " 4.549e-06\n", - " 1.5929e-05\n", - " 9.338e-06\n", - " 5.901e-06\n", - " 6.7276e-05\n", + " 3868.95\n", + " 3.282e-06\n", + " 1.4388e-05\n", + " 0.000129765\n", + " 1.3759e-05\n", + " 9.499e-06\n", + " 8.73e-06\n", + " 9.01e-06\n", + " 6.6209e-05\n", " ...\n", " NaN\n", " NaN\n", @@ -616,7 +616,7 @@ " NaN\n", " NaN\n", " NaN\n", - " NaN\n", + " 3\n", " 2\n", " NaN\n", " NaN\n", @@ -634,40 +634,40 @@ " NaN\n", " NaN\n", " ...\n", - " NaN\n", - " 0.000282709\n", + " 0.000743251\n", " 2\n", " 0\n", " 7\n", " 12\n", " 0\n", " NaN\n", + " NaN\n", " 4\n", " 1\n", " \n", " \n", "\n", - "

2 rows × 22 columns

\n", + "

2 rows × 23 columns

\n", "" ], "text/plain": [ " task premin_time reorg_time partsol_time player_incomp_time incomp_time \\\n", - "0 presat 25643.3 1.112e-06 4.588e-06 9.888e-06 4.549e-06 \n", + "0 presat 3868.95 3.282e-06 1.4388e-05 0.000129765 1.3759e-05 \n", "1 sat NaN NaN NaN NaN NaN \n", "\n", " split_all_let_time split_min_let_time split_cstr_time prob_init_build_time \\\n", - "0 1.5929e-05 9.338e-06 5.901e-06 6.7276e-05 \n", + "0 9.499e-06 8.73e-06 9.01e-06 6.6209e-05 \n", "1 NaN NaN NaN NaN \n", "\n", - " ... refine_time total_time n_classes n_refinement n_lit n_clauses \\\n", - "0 ... NaN NaN NaN NaN NaN NaN \n", - "1 ... NaN 0.000282709 2 0 7 12 \n", + " ... total_time n_classes n_refinement n_lit n_clauses n_iteration \\\n", + "0 ... NaN NaN NaN NaN NaN NaN \n", + "1 ... 0.000743251 2 0 7 12 0 \n", "\n", - " n_iteration n_bisim_let n_min_states done \n", - "0 NaN 2 NaN NaN \n", - "1 0 NaN 4 1 \n", + " n_letters_part n_bisim_let n_min_states done \n", + "0 3 2 NaN NaN \n", + "1 NaN NaN 4 1 \n", "\n", - "[2 rows x 22 columns]" + "[2 rows x 23 columns]" ] }, "metadata": {}, @@ -758,7 +758,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc88735f00> >" + " *' at 0x7f861bfc8630> >" ] }, "execution_count": 11, @@ -861,7 +861,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc6157fe40> >" + " *' at 0x7f861bf9fb40> >" ] }, "execution_count": 12, @@ -1000,7 +1000,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc6157f210> >" + " *' at 0x7f861bf9f210> >" ] }, "execution_count": 13, @@ -1051,13 +1051,13 @@ " split_cstr_time\n", " prob_init_build_time\n", " ...\n", - " refine_time\n", " total_time\n", " n_classes\n", " n_refinement\n", " n_lit\n", " n_clauses\n", " n_iteration\n", + " n_letters_part\n", " n_bisim_let\n", " n_min_states\n", " done\n", @@ -1067,15 +1067,15 @@ " \n", " 0\n", " presat\n", - " 25643.4\n", - " 1.683e-06\n", - " 5.611e-06\n", - " 2.66e-05\n", - " 1.2e-07\n", - " 3.647e-06\n", - " 8.365e-06\n", - " 3.747e-06\n", - " 2.5538e-05\n", + " 3869.08\n", + " 3.213e-06\n", + " 9.079e-06\n", + " 9.5752e-05\n", + " 5.168e-06\n", + " 5.727e-06\n", + " 7.543e-06\n", + " 1.5784e-05\n", + " 4.0507e-05\n", " ...\n", " NaN\n", " NaN\n", @@ -1083,7 +1083,7 @@ " NaN\n", " NaN\n", " NaN\n", - " NaN\n", + " 1\n", " 1\n", " NaN\n", " NaN\n", @@ -1102,7 +1102,6 @@ " NaN\n", " ...\n", " NaN\n", - " NaN\n", " 1\n", " 0\n", " 3\n", @@ -1111,6 +1110,7 @@ " NaN\n", " NaN\n", " NaN\n", + " NaN\n", " \n", " \n", " 2\n", @@ -1125,7 +1125,6 @@ " NaN\n", " NaN\n", " ...\n", - " 4.4884e-05\n", " NaN\n", " 1\n", " 1\n", @@ -1135,6 +1134,7 @@ " NaN\n", " NaN\n", " NaN\n", + " NaN\n", " \n", " \n", " 3\n", @@ -1149,48 +1149,48 @@ " NaN\n", " NaN\n", " ...\n", - " NaN\n", - " 0.000200344\n", + " 0.000399073\n", " 2\n", " 0\n", " 17\n", " 29\n", " 1\n", " NaN\n", + " NaN\n", " 4\n", " 1\n", " \n", " \n", "\n", - "

4 rows × 22 columns

\n", + "

4 rows × 23 columns

\n", "" ], "text/plain": [ " task premin_time reorg_time partsol_time player_incomp_time \\\n", - "0 presat 25643.4 1.683e-06 5.611e-06 2.66e-05 \n", + "0 presat 3869.08 3.213e-06 9.079e-06 9.5752e-05 \n", "1 sat NaN NaN NaN NaN \n", "2 refinement NaN NaN NaN NaN \n", "3 sat NaN NaN NaN NaN \n", "\n", " incomp_time split_all_let_time split_min_let_time split_cstr_time \\\n", - "0 1.2e-07 3.647e-06 8.365e-06 3.747e-06 \n", + "0 5.168e-06 5.727e-06 7.543e-06 1.5784e-05 \n", "1 NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN \n", "\n", - " prob_init_build_time ... refine_time total_time n_classes n_refinement \\\n", - "0 2.5538e-05 ... NaN NaN NaN NaN \n", - "1 NaN ... NaN NaN 1 0 \n", - "2 NaN ... 4.4884e-05 NaN 1 1 \n", - "3 NaN ... NaN 0.000200344 2 0 \n", + " prob_init_build_time ... total_time n_classes n_refinement n_lit \\\n", + "0 4.0507e-05 ... NaN NaN NaN NaN \n", + "1 NaN ... NaN 1 0 3 \n", + "2 NaN ... NaN 1 1 10 \n", + "3 NaN ... 0.000399073 2 0 17 \n", "\n", - " n_lit n_clauses n_iteration n_bisim_let n_min_states done \n", - "0 NaN NaN NaN 1 NaN NaN \n", - "1 3 6 0 NaN NaN NaN \n", - "2 10 16 NaN NaN NaN NaN \n", - "3 17 29 1 NaN 4 1 \n", + " n_clauses n_iteration n_letters_part n_bisim_let n_min_states done \n", + "0 NaN NaN 1 1 NaN NaN \n", + "1 6 0 NaN NaN NaN NaN \n", + "2 16 NaN NaN NaN NaN NaN \n", + "3 29 1 NaN NaN 4 1 \n", "\n", - "[4 rows x 22 columns]" + "[4 rows x 23 columns]" ] }, "metadata": {}, @@ -1200,6 +1200,7 @@ "name": "stdout", "output_type": "stream", "text": [ + "Number of variables\n", "0 NaN\n", "1 3\n", "2 10\n", @@ -1285,7 +1286,7 @@ "\n" ], "text/plain": [ - " *' at 0x7fcc35ac22a0> >" + " *' at 0x7f861bfcdc00> >" ] }, "execution_count": 14, @@ -1297,6 +1298,7 @@ "si = spot.synthesis_info()\n", "si.minimize_lvl = 3\n", "aut_ms, table = spot.minimize_mealy(aut_s, si, display_log=True, return_log=True)\n", + "print(\"Number of variables\")\n", "print(table[\"n_lit\"])\n", "aut_ms" ] @@ -1347,13 +1349,13 @@ " split_cstr_time\n", " prob_init_build_time\n", " ...\n", - " refine_time\n", " total_time\n", " n_classes\n", " n_refinement\n", " n_lit\n", " n_clauses\n", " n_iteration\n", + " n_letters_part\n", " n_bisim_let\n", " n_min_states\n", " done\n", @@ -1363,15 +1365,15 @@ " \n", " 0\n", " presat\n", - " 25643.5\n", - " 1.563e-06\n", - " 5.4e-06\n", - " 2.0519e-05\n", - " 1.3e-07\n", - " 3.968e-06\n", - " 9.698e-06\n", - " 7.624e-06\n", - " 3.211e-05\n", + " 3869.14\n", + " 2.863e-06\n", + " 9.08e-06\n", + " 6.0622e-05\n", + " 4.679e-06\n", + " 5.308e-06\n", + " 8.59e-06\n", + " 7.962e-06\n", + " 4.0159e-05\n", " ...\n", " NaN\n", " NaN\n", @@ -1379,7 +1381,7 @@ " NaN\n", " NaN\n", " NaN\n", - " NaN\n", + " 1\n", " 1\n", " NaN\n", " NaN\n", @@ -1398,7 +1400,6 @@ " NaN\n", " ...\n", " NaN\n", - " NaN\n", " 1\n", " 0\n", " 3\n", @@ -1407,6 +1408,7 @@ " NaN\n", " NaN\n", " NaN\n", + " NaN\n", " \n", " \n", " 2\n", @@ -1421,7 +1423,6 @@ " NaN\n", " NaN\n", " ...\n", - " 4.4633e-05\n", " NaN\n", " 1\n", " 1\n", @@ -1431,6 +1432,7 @@ " NaN\n", " NaN\n", " NaN\n", + " NaN\n", " \n", " \n", " 3\n", @@ -1445,48 +1447,48 @@ " NaN\n", " NaN\n", " ...\n", - " NaN\n", - " 0.000280675\n", + " 0.000416464\n", " 2\n", " 0\n", " 17\n", " 29\n", " 1\n", " NaN\n", + " NaN\n", " 4\n", " 1\n", " \n", " \n", "\n", - "

4 rows × 22 columns

\n", + "

4 rows × 23 columns

\n", "" ], "text/plain": [ " task premin_time reorg_time partsol_time player_incomp_time \\\n", - "0 presat 25643.5 1.563e-06 5.4e-06 2.0519e-05 \n", + "0 presat 3869.14 2.863e-06 9.08e-06 6.0622e-05 \n", "1 sat NaN NaN NaN NaN \n", "2 refinement NaN NaN NaN NaN \n", "3 sat NaN NaN NaN NaN \n", "\n", " incomp_time split_all_let_time split_min_let_time split_cstr_time \\\n", - "0 1.3e-07 3.968e-06 9.698e-06 7.624e-06 \n", + "0 4.679e-06 5.308e-06 8.59e-06 7.962e-06 \n", "1 NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN \n", "\n", - " prob_init_build_time ... refine_time total_time n_classes n_refinement \\\n", - "0 3.211e-05 ... NaN NaN NaN NaN \n", - "1 NaN ... NaN NaN 1 0 \n", - "2 NaN ... 4.4633e-05 NaN 1 1 \n", - "3 NaN ... NaN 0.000280675 2 0 \n", + " prob_init_build_time ... total_time n_classes n_refinement n_lit \\\n", + "0 4.0159e-05 ... NaN NaN NaN NaN \n", + "1 NaN ... NaN 1 0 3 \n", + "2 NaN ... NaN 1 1 10 \n", + "3 NaN ... 0.000416464 2 0 17 \n", "\n", - " n_lit n_clauses n_iteration n_bisim_let n_min_states done \n", - "0 NaN NaN NaN 1 NaN NaN \n", - "1 3 6 0 NaN NaN NaN \n", - "2 10 16 NaN NaN NaN NaN \n", - "3 17 29 1 NaN 4 1 \n", + " n_clauses n_iteration n_letters_part n_bisim_let n_min_states done \n", + "0 NaN NaN 1 1 NaN NaN \n", + "1 6 0 NaN NaN NaN NaN \n", + "2 16 NaN NaN NaN NaN NaN \n", + "3 29 1 NaN NaN 4 1 \n", "\n", - "[4 rows x 22 columns]" + "[4 rows x 23 columns]" ] }, "metadata": {}, @@ -1570,10 +1572,118 @@ " " ] }, + { + "cell_type": "markdown", + "id": "b10213b8", + "metadata": {}, + "source": [ + "# Testing partitioned relabeling" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "fd5ca506", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Conditions in orig machine: 8\n", + "Conditions in relabeled machine: 13\n" + ] + } + ], + "source": [ + "def get_mealy():\n", + " return spot.split_2step(spot.automaton(\"\"\"HOA: v1\n", + "States: 2\n", + "Start: 0\n", + "AP: 11 \"u0accel0accel\" \"u0accel0f1dcon23p81b\" \"u0accel0f1dcon231b\" \"u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b\" \"u0gear0gear\" \"u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b\" \"u0steer0f1dsteering0angle0trackpos1b\" \"u0steer0steer\" \"p0p0gt0rpm0f1dcon5523231b\" \"p0p0lt0rpm0f1dcon32323231b\" \"p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\"\n", + "acc-name: all\n", + "Acceptance: 0 t\n", + "properties: trans-labels explicit-labels state-acc deterministic\n", + "controllable-AP: 0 1 2 3 4 5 6 7\n", + "--BODY--\n", + "State: 0\n", + "[!0&!1&2&!3&4&!5&6&!7&!8&!9&!10] 0\n", + "[!0&1&!2&!3&4&!5&6&!7&!8&!9&10] 0\n", + "[!0&!1&2&!3&!4&5&6&!7&!8&9&!10] 0\n", + "[!0&1&!2&!3&!4&5&6&!7&!8&9&10] 0\n", + "[!0&!1&2&3&!4&!5&6&!7&8&!9&!10] 0\n", + "[!0&1&!2&3&!4&!5&6&!7&8&!9&10] 0\n", + "[!0&!1&2&!3&!4&5&!6&7&8&9 | !0&!1&2&!3&!4&5&6&!7&8&9 | !0&!1&2&!3&4&!5&!6&7&8&9 | !0&!1&2&!3&4&!5&6&!7&8&9 | !0&!1&2&3&!4&!5&!6&7&8&9 | !0&!1&2&3&!4&!5&6&!7&8&9 | !0&1&!2&!3&!4&5&!6&7&8&9 | !0&1&!2&!3&!4&5&6&!7&8&9 | !0&1&!2&!3&4&!5&!6&7&8&9 | !0&1&!2&!3&4&!5&6&!7&8&9 | !0&1&!2&3&!4&!5&!6&7&8&9 | !0&1&!2&3&!4&!5&6&!7&8&9 | 0&!1&!2&!3&!4&5&!6&7&8&9 | 0&!1&!2&!3&!4&5&6&!7&8&9 | 0&!1&!2&!3&4&!5&!6&7&8&9 | 0&!1&!2&!3&4&!5&6&!7&8&9 | 0&!1&!2&3&!4&!5&!6&7&8&9 | 0&!1&!2&3&!4&!5&6&!7&8&9] 1\n", + "State: 1\n", + "[!0&!1&2&!3&!4&5&!6&7 | !0&!1&2&!3&!4&5&6&!7 | !0&!1&2&!3&4&!5&!6&7 | !0&!1&2&!3&4&!5&6&!7 | !0&!1&2&3&!4&!5&!6&7 | !0&!1&2&3&!4&!5&6&!7 | !0&1&!2&!3&!4&5&!6&7 | !0&1&!2&!3&!4&5&6&!7 | !0&1&!2&!3&4&!5&!6&7 | !0&1&!2&!3&4&!5&6&!7 | !0&1&!2&3&!4&!5&!6&7 | !0&1&!2&3&!4&!5&6&!7 | 0&!1&!2&!3&!4&5&!6&7 | 0&!1&!2&!3&!4&5&6&!7 | 0&!1&!2&!3&4&!5&!6&7 | 0&!1&!2&!3&4&!5&6&!7 | 0&!1&!2&3&!4&!5&!6&7 | 0&!1&!2&3&!4&!5&6&!7] 1\n", + "--END--\"\"\"))\n", + "\n", + "def env_conditions(m):\n", + " sp = spot.get_state_players(m)\n", + " conds = []\n", + " for e in m.edges():\n", + " if sp[e.src]:\n", + " continue\n", + " if not e.cond in conds:\n", + " conds.append(e.cond)\n", + " return conds\n", + "print(\"Conditions in orig machine: \", len(env_conditions(get_mealy())))\n", + "ms = get_mealy()\n", + "# Relabel only env\n", + "spot.partitioned_game_relabel_here(ms, True, False, True, False)\n", + "print(\"Conditions in relabeled machine: \", len(env_conditions(ms)))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "ee29da67", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Partitioned env letters: 13\n" + ] + } + ], + "source": [ + "si = spot.synthesis_info()\n", + "si.minimize_lvl = 3\n", + "# Turn on relabeling\n", + "si.opt.set(\"max_letter_mult\", 100000)\n", + "\n", + "mm, log = spot.minimize_mealy(get_mealy(), si, return_log=True)\n", + "print(\"Partitioned env letters:\", log[\"n_letters_part\"][0])" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "0aec8019", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Partitioned env letters: 0\n" + ] + } + ], + "source": [ + "# Turn off relabeling\n", + "si.opt.set(\"max_letter_mult\", 0)\n", + "\n", + "mm, log = spot.minimize_mealy(get_mealy(), si, return_log=True)\n", + "print(\"Partitioned env letters:\", log[\"n_letters_part\"][0])" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "5c9fe115", + "id": "a92f4f43", "metadata": {}, "outputs": [], "source": [] diff --git a/tests/python/_partitioned_relabel.ipynb b/tests/python/_partitioned_relabel.ipynb index a9c1c7af7..b7f1c4380 100644 --- a/tests/python/_partitioned_relabel.ipynb +++ b/tests/python/_partitioned_relabel.ipynb @@ -121,7 +121,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b0311a80> >" + " *' at 0x7f936415fbd0> >" ] }, "execution_count": 2, @@ -248,7 +248,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b0311a80> >" + " *' at 0x7f936415fbd0> >" ] }, "execution_count": 3, @@ -353,7 +353,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b0311a80> >" + " *' at 0x7f936415fbd0> >" ] }, "execution_count": 4, @@ -457,7 +457,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b02c0d50> >" + " *' at 0x7f936415bf30> >" ] }, "metadata": {}, @@ -611,7 +611,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b02c0d50> >" + " *' at 0x7f936415bf30> >" ] }, "execution_count": 5, @@ -769,7 +769,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b02c0d50> >" + " *' at 0x7f936415bf30> >" ] }, "execution_count": 6, @@ -886,7 +886,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b02c90f0> >" + " *' at 0x7f936c3c6090> >" ] }, "metadata": {}, @@ -1015,7 +1015,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b02c90f0> >" + " *' at 0x7f936c3c6090> >" ] }, "execution_count": 7, @@ -1184,7 +1184,7 @@ "\n" ], "text/plain": [ - " *' at 0x7f65b02c90f0> >" + " *' at 0x7f936c3c6090> >" ] }, "execution_count": 8, @@ -1198,6 +1198,1135 @@ "print(aut.to_str(\"hoa\"))\n", "aut" ] + }, + { + "cell_type": "markdown", + "id": "ef77c2ee", + "metadata": {}, + "source": [ + "# Concerning games and Mealy machines\n", + "\n", + "Games and split mealy machines have both: defined outputs and states that either belong to player or env.\n", + "Relabeling is done separately for env and player transitions (over inputs and outputs respectively).\n", + "\n", + "The problem is that T (bddtrue) is ambiguous, as it may be over the inputs or outputs.\n", + "\n", + "We therefore introduce a dedicated function for this matter." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "296a93d3", + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b / !u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b / !u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b / !u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b / !u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b / !u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b / !u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b / (label too long)\n", + "\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "1 / (label too long)\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " *' at 0x7f936415f510> >" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "HOA: v1\n", + "States: 9\n", + "Start: 0\n", + "AP: 11 \"u0accel0accel\" \"u0accel0f1dcon23p81b\" \"u0accel0f1dcon231b\" \"u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b\" \"u0gear0gear\" \"u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b\" \"u0steer0f1dsteering0angle0trackpos1b\" \"u0steer0steer\" \"p0p0gt0rpm0f1dcon5523231b\" \"p0p0lt0rpm0f1dcon32323231b\" \"p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\"\n", + "acc-name: all\n", + "Acceptance: 0 t\n", + "properties: trans-labels explicit-labels state-acc deterministic\n", + "spot-state-player: 0 0 1 1 1 1 1 1 1\n", + "controllable-AP: 0 1 2 3 4 5 6 7\n", + "--BODY--\n", + "State: 0\n", + "[!8&!9&!10] 2\n", + "[!8&!9&10] 3\n", + "[!8&9&!10] 4\n", + "[!8&9&10] 5\n", + "[8&!9&!10] 6\n", + "[8&!9&10] 7\n", + "[8&9] 8\n", + "State: 1\n", + "[t] 8\n", + "State: 2\n", + "[!0&!1&2&!3&4&!5&6&!7] 0\n", + "State: 3\n", + "[!0&1&!2&!3&4&!5&6&!7] 0\n", + "State: 4\n", + "[!0&!1&2&!3&!4&5&6&!7] 0\n", + "State: 5\n", + "[!0&1&!2&!3&!4&5&6&!7] 0\n", + "State: 6\n", + "[!0&!1&2&3&!4&!5&6&!7] 0\n", + "State: 7\n", + "[!0&1&!2&3&!4&!5&6&!7] 0\n", + "State: 8\n", + "[!0&!1&2&!3&!4&5&!6&7 | !0&!1&2&!3&!4&5&6&!7 | !0&!1&2&!3&4&!5&!6&7 | !0&!1&2&!3&4&!5&6&!7 | !0&!1&2&3&!4&!5&!6&7 | !0&!1&2&3&!4&!5&6&!7 | !0&1&!2&!3&!4&5&!6&7 | !0&1&!2&!3&!4&5&6&!7 | !0&1&!2&!3&4&!5&!6&7 | !0&1&!2&!3&4&!5&6&!7 | !0&1&!2&3&!4&!5&!6&7 | !0&1&!2&3&!4&!5&6&!7 | 0&!1&!2&!3&!4&5&!6&7 | 0&!1&!2&!3&!4&5&6&!7 | 0&!1&!2&!3&4&!5&!6&7 | 0&!1&!2&!3&4&!5&6&!7 | 0&!1&!2&3&!4&!5&!6&7 | 0&!1&!2&3&!4&!5&6&!7] 1\n", + "--END--\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "t\n", + "[all]\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "0->3\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "0->5\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "0->6\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "0->7\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "0->8\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b\n", + "\n", + "\n", + "\n", + "2->0\n", + "\n", + "\n", + "!u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "3->0\n", + "\n", + "\n", + "!u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "4->0\n", + "\n", + "\n", + "!u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "5->0\n", + "\n", + "\n", + "!u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "6->0\n", + "\n", + "\n", + "!u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "7->0\n", + "\n", + "\n", + "!u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "8->1\n", + "\n", + "\n", + "(label too long)\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " *' at 0x7f936415f990> >" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "HOA: v1\n", + "States: 9\n", + "Start: 0\n", + "AP: 21 \"u0accel0accel\" \"u0accel0f1dcon23p81b\" \"u0accel0f1dcon231b\" \"u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b\" \"u0gear0gear\" \"u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b\" \"u0steer0f1dsteering0angle0trackpos1b\" \"u0steer0steer\" \"p0p0gt0rpm0f1dcon5523231b\" \"p0p0lt0rpm0f1dcon32323231b\" \"p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\" \"__AP_OUT__\" \"__AP_IN__\" \"__nv_in0\" \"__nv_in1\" \"__nv_in2\" \"__nv_in3\" \"__nv_out0\" \"__nv_out1\" \"__nv_out2\" \"__nv_out3\"\n", + "acc-name: all\n", + "Acceptance: 0 t\n", + "properties: trans-labels explicit-labels state-acc deterministic\n", + "spot-state-player: 0 0 1 1 1 1 1 1 1\n", + "controllable-AP: 0 1 2 3 4 5 6 7\n", + "--BODY--\n", + "State: 0\n", + "[!13&!14&!15&!16] 2\n", + "[13&!14&!15&!16] 3\n", + "[!13&14&!15&!16] 4\n", + "[13&14&!15&!16] 5\n", + "[!13&!14&15&!16] 6\n", + "[13&!14&15&!16] 7\n", + "[!13&14&15&!16] 8\n", + "[13&14&15&!16] 2\n", + "[!13&!14&!15&16] 3\n", + "[13&!14&!15&16] 4\n", + "[!13&14&!15&16] 5\n", + "[13&14&!15&16] 6\n", + "[!13&!14&15&16] 7\n", + "State: 1\n", + "[13&14&15&!16] 8\n", + "[!13&!14&!15&16] 8\n", + "[13&!14&!15&16] 8\n", + "[!13&14&!15&16] 8\n", + "[13&14&!15&16] 8\n", + "[!13&!14&15&16] 8\n", + "[!13&14&15&!16] 8\n", + "State: 2\n", + "[!17&!18&!19&!20 | !17&18&19&!20] 0\n", + "State: 3\n", + "[17&!18&!19&!20 | 17&18&19&!20] 0\n", + "State: 4\n", + "[!17&!18&!19&20 | !17&18&!19&!20] 0\n", + "State: 5\n", + "[17&!18&!19&20 | 17&18&!19&!20] 0\n", + "State: 6\n", + "[!17&!18&19&!20 | !17&18&!19&20] 0\n", + "State: 7\n", + "[17&!18&19&!20 | 17&18&!19&20] 0\n", + "State: 8\n", + "[!17&!18&20 | 18&19&!20 | !19&20] 1\n", + "--END--\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "t\n", + "[all]\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "!__nv_in0 & !__nv_in1 & !__nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "__nv_in0 & __nv_in1 & __nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "0->3\n", + "\n", + "\n", + "__nv_in0 & !__nv_in1 & !__nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "0->3\n", + "\n", + "\n", + "!__nv_in0 & !__nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "!__nv_in0 & __nv_in1 & !__nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "__nv_in0 & !__nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "0->5\n", + "\n", + "\n", + "__nv_in0 & __nv_in1 & !__nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "0->5\n", + "\n", + "\n", + "!__nv_in0 & __nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "0->6\n", + "\n", + "\n", + "!__nv_in0 & !__nv_in1 & __nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "0->6\n", + "\n", + "\n", + "__nv_in0 & __nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "0->7\n", + "\n", + "\n", + "__nv_in0 & !__nv_in1 & __nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "0->7\n", + "\n", + "\n", + "!__nv_in0 & !__nv_in1 & __nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "0->8\n", + "\n", + "\n", + "!__nv_in0 & __nv_in1 & __nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "2->0\n", + "\n", + "\n", + "(!__nv_out0 & !__nv_out1 & !__nv_out2 & !__nv_out3) | (!__nv_out0 & __nv_out1 & __nv_out2 & !__nv_out3)\n", + "\n", + "\n", + "\n", + "3->0\n", + "\n", + "\n", + "(__nv_out0 & !__nv_out1 & !__nv_out2 & !__nv_out3) | (__nv_out0 & __nv_out1 & __nv_out2 & !__nv_out3)\n", + "\n", + "\n", + "\n", + "4->0\n", + "\n", + "\n", + "(!__nv_out0 & __nv_out1 & !__nv_out2 & !__nv_out3) | (!__nv_out0 & !__nv_out1 & !__nv_out2 & __nv_out3)\n", + "\n", + "\n", + "\n", + "5->0\n", + "\n", + "\n", + "(__nv_out0 & __nv_out1 & !__nv_out2 & !__nv_out3) | (__nv_out0 & !__nv_out1 & !__nv_out2 & __nv_out3)\n", + "\n", + "\n", + "\n", + "6->0\n", + "\n", + "\n", + "(!__nv_out0 & !__nv_out1 & __nv_out2 & !__nv_out3) | (!__nv_out0 & __nv_out1 & !__nv_out2 & __nv_out3)\n", + "\n", + "\n", + "\n", + "7->0\n", + "\n", + "\n", + "(__nv_out0 & !__nv_out1 & __nv_out2 & !__nv_out3) | (__nv_out0 & __nv_out1 & !__nv_out2 & __nv_out3)\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "8->1\n", + "\n", + "\n", + "(!__nv_out0 & !__nv_out1 & __nv_out3) | (__nv_out1 & __nv_out2 & !__nv_out3) | (!__nv_out2 & __nv_out3)\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "__nv_in0 & __nv_in1 & __nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!__nv_in0 & !__nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "__nv_in0 & !__nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!__nv_in0 & __nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "__nv_in0 & __nv_in1 & !__nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!__nv_in0 & !__nv_in1 & __nv_in2 & __nv_in3\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!__nv_in0 & __nv_in1 & __nv_in2 & !__nv_in3\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " *' at 0x7f936415f990> >" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Strategy torquesimple_acd as mealy machine\n", + "\n", + "aut = spot.automaton(\"\"\"HOA: v1\n", + "States: 2\n", + "Start: 0\n", + "AP: 11 \"u0accel0accel\" \"u0accel0f1dcon23p81b\" \"u0accel0f1dcon231b\" \"u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b\" \"u0gear0gear\" \"u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b\" \"u0steer0f1dsteering0angle0trackpos1b\" \"u0steer0steer\" \"p0p0gt0rpm0f1dcon5523231b\" \"p0p0lt0rpm0f1dcon32323231b\" \"p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\"\n", + "acc-name: all\n", + "Acceptance: 0 t\n", + "properties: trans-labels explicit-labels state-acc deterministic\n", + "controllable-AP: 0 1 2 3 4 5 6 7\n", + "--BODY--\n", + "State: 0\n", + "[!0&!1&2&!3&4&!5&6&!7&!8&!9&!10] 0\n", + "[!0&1&!2&!3&4&!5&6&!7&!8&!9&10] 0\n", + "[!0&!1&2&!3&!4&5&6&!7&!8&9&!10] 0\n", + "[!0&1&!2&!3&!4&5&6&!7&!8&9&10] 0\n", + "[!0&!1&2&3&!4&!5&6&!7&8&!9&!10] 0\n", + "[!0&1&!2&3&!4&!5&6&!7&8&!9&10] 0\n", + "[!0&!1&2&!3&!4&5&!6&7&8&9 | !0&!1&2&!3&!4&5&6&!7&8&9 | !0&!1&2&!3&4&!5&!6&7&8&9 | !0&!1&2&!3&4&!5&6&!7&8&9 | !0&!1&2&3&!4&!5&!6&7&8&9 | !0&!1&2&3&!4&!5&6&!7&8&9 | !0&1&!2&!3&!4&5&!6&7&8&9 | !0&1&!2&!3&!4&5&6&!7&8&9 | !0&1&!2&!3&4&!5&!6&7&8&9 | !0&1&!2&!3&4&!5&6&!7&8&9 | !0&1&!2&3&!4&!5&!6&7&8&9 | !0&1&!2&3&!4&!5&6&!7&8&9 | 0&!1&!2&!3&!4&5&!6&7&8&9 | 0&!1&!2&!3&!4&5&6&!7&8&9 | 0&!1&!2&!3&4&!5&!6&7&8&9 | 0&!1&!2&!3&4&!5&6&!7&8&9 | 0&!1&!2&3&!4&!5&!6&7&8&9 | 0&!1&!2&3&!4&!5&6&!7&8&9] 1\n", + "State: 1\n", + "[!0&!1&2&!3&!4&5&!6&7 | !0&!1&2&!3&!4&5&6&!7 | !0&!1&2&!3&4&!5&!6&7 | !0&!1&2&!3&4&!5&6&!7 | !0&!1&2&3&!4&!5&!6&7 | !0&!1&2&3&!4&!5&6&!7 | !0&1&!2&!3&!4&5&!6&7 | !0&1&!2&!3&!4&5&6&!7 | !0&1&!2&!3&4&!5&!6&7 | !0&1&!2&!3&4&!5&6&!7 | !0&1&!2&3&!4&!5&!6&7 | !0&1&!2&3&!4&!5&6&!7 | 0&!1&!2&!3&!4&5&!6&7 | 0&!1&!2&!3&!4&5&6&!7 | 0&!1&!2&!3&4&!5&!6&7 | 0&!1&!2&!3&4&!5&6&!7 | 0&!1&!2&3&!4&!5&!6&7 | 0&!1&!2&3&!4&!5&6&!7] 1\n", + "--END--\"\"\")\n", + "\n", + "display(aut)\n", + "\n", + "# Convert to split mealy machine\n", + "auts = spot.split_2step(aut)\n", + "print(auts.to_str(\"hoa\"))\n", + "display(auts)\n", + "\n", + "# Relabel both, inputs and outputs\n", + "# You can choose the split option and stopping criteria as before\n", + "rel_dicts = spot.partitioned_game_relabel_here(auts, True, True, True, False, 10000, 10000)\n", + "print(auts.to_str(\"hoa\"))\n", + "display(auts)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7ec02ff5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "HOA: v1\n", + "States: 9\n", + "Start: 0\n", + "AP: 11 \"u0accel0accel\" \"u0accel0f1dcon23p81b\" \"u0accel0f1dcon231b\" \"u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b\" \"u0gear0gear\" \"u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b\" \"u0steer0f1dsteering0angle0trackpos1b\" \"u0steer0steer\" \"p0p0gt0rpm0f1dcon5523231b\" \"p0p0lt0rpm0f1dcon32323231b\" \"p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\"\n", + "acc-name: all\n", + "Acceptance: 0 t\n", + "properties: trans-labels explicit-labels state-acc deterministic\n", + "spot-state-player: 0 0 1 1 1 1 1 1 1\n", + "controllable-AP: 0 1 2 3 4 5 6 7\n", + "--BODY--\n", + "State: 0\n", + "[f] 2\n", + "[f] 3\n", + "[f] 4\n", + "[f] 5\n", + "[f] 6\n", + "[f] 7\n", + "[8&9] 8\n", + "[!8&!9&!10] 2\n", + "[!8&!9&10] 3\n", + "[!8&9&!10] 4\n", + "[!8&9&10] 5\n", + "[8&!9&!10] 6\n", + "[8&!9&10] 7\n", + "State: 1\n", + "[!8&!9&!10] 8\n", + "[!8&!9&10] 8\n", + "[!8&9&!10] 8\n", + "[!8&9&10] 8\n", + "[8&!9&!10] 8\n", + "[8&!9&10] 8\n", + "[8&9] 8\n", + "State: 2\n", + "[!0&!1&2&!3&4&!5&6&!7] 0\n", + "State: 3\n", + "[!0&1&!2&!3&4&!5&6&!7] 0\n", + "State: 4\n", + "[!0&!1&2&!3&!4&5&6&!7] 0\n", + "State: 5\n", + "[!0&1&!2&!3&!4&5&6&!7] 0\n", + "State: 6\n", + "[!0&!1&2&3&!4&!5&6&!7] 0\n", + "State: 7\n", + "[!0&1&!2&3&!4&!5&6&!7] 0\n", + "State: 8\n", + "[!0&!1&2&!3&!4&5&!6&7 | !0&!1&2&!3&!4&5&6&!7 | !0&!1&2&!3&4&!5&!6&7 | !0&!1&2&!3&4&!5&6&!7 | !0&!1&2&3&!4&!5&!6&7 | !0&!1&2&3&!4&!5&6&!7 | !0&1&!2&!3&!4&5&!6&7 | !0&1&!2&!3&!4&5&6&!7 | !0&1&!2&!3&4&!5&!6&7 | !0&1&!2&!3&4&!5&6&!7 | !0&1&!2&3&!4&!5&!6&7 | !0&1&!2&3&!4&!5&6&!7 | 0&!1&!2&!3&!4&5&!6&7 | 0&!1&!2&!3&!4&5&6&!7 | 0&!1&!2&!3&4&!5&!6&7 | 0&!1&!2&!3&4&!5&6&!7 | 0&!1&!2&3&!4&!5&!6&7 | 0&!1&!2&3&!4&!5&6&!7] 1\n", + "--END--\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "t\n", + "[all]\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "0->3\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "0->3\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "0->5\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "0->5\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "0->6\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "0->6\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "0->7\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "0->7\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "8\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "0->8\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b\n", + "\n", + "\n", + "\n", + "2->0\n", + "\n", + "\n", + "!u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "3->0\n", + "\n", + "\n", + "!u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "4->0\n", + "\n", + "\n", + "!u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "5->0\n", + "\n", + "\n", + "!u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & !u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "6->0\n", + "\n", + "\n", + "!u0accel0accel & !u0accel0f1dcon23p81b & u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "7->0\n", + "\n", + "\n", + "!u0accel0accel & u0accel0f1dcon23p81b & !u0accel0f1dcon231b & !u0gear0f1dmax0f1dcon241b0f1dsub0gear0f1dcon241b1b1b & u0gear0f1dmin0f1dcon61b0f1dadd0gear0f1dcon241b1b1b & !u0gear0gear & u0steer0f1dsteering0angle0trackpos1b & !u0steer0steer\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "8->1\n", + "\n", + "\n", + "(label too long)\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "!p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & !p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & !p0p0lt0rpm0f1dcon32323231b & p0p0lt0speed0f1dsub0target2speed0f1dmultp0f1dabs0steer1b0f1dcon248881b1b1b\n", + "\n", + "\n", + "\n", + "1->8\n", + "\n", + "\n", + "p0p0gt0rpm0f1dcon5523231b & p0p0lt0rpm0f1dcon32323231b\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " *' at 0x7f936415f990> >" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Undo relabel\n", + "spot.relabel_game_here(auts, rel_dicts)\n", + "print(auts.to_str(\"hoa\"))\n", + "display(auts)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "48c2283b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "# Check if we do actually obtain the same automaton\n", + "\n", + "print(spot.are_equivalent(aut, spot.unsplit_2step(auts)))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "2b8d907e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n", + "True\n" + ] + } + ], + "source": [ + "# Test all options for equivalence\n", + "for relabel_env in [True, False]:\n", + " for relabel_player in [True, False]:\n", + " for split_env in [True, False]:\n", + " for split_player in [True, False]:\n", + " auts = spot.split_2step(aut)\n", + " rel_dicts = spot.partitioned_game_relabel_here(auts, relabel_env, relabel_player, split_env, split_player, 10000, 10000)\n", + " spot.relabel_game_here(auts, rel_dicts)\n", + " print(spot.are_equivalent(aut, spot.unsplit_2step(auts)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17a32a72", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tests/python/except.py b/tests/python/except.py index e531882dd..03076c01b 100644 --- a/tests/python/except.py +++ b/tests/python/except.py @@ -373,4 +373,22 @@ except RuntimeError as e: tc.assertIn("The given prefix for new variables", str(e)) else: - report_missing_exception() \ No newline at end of file + report_missing_exception() + +# Relabeling games must not use the +# globally reserved aps +aut = spot.make_twa_graph() +aut.new_states(2) +apin = buddy.bdd_ithvar(aut.register_ap("__AP_IN__")) +apout = buddy.bdd_ithvar(aut.register_ap("__AP_OUT__")) +aut.new_edge(0,1,apin & apout) +aut.new_edge(1,0,buddy.bdd_not(apin & apout)) +spot.set_state_players(aut, [False, True]) + +try: + spot.partitioned_game_relabel_here(aut, True, True) +except RuntimeError as e: + tc.assertIn("You can not use __AP_IN__ or __AP_OUT__", + str(e)) +else: + report_missing_exception()