From 3c5928d216025dc6d8a8e48e89e1cfa8c6c5f432 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Fri, 5 Nov 2021 12:15:40 +0100 Subject: [PATCH] tl: fix AST rendering of Star/FStar nodes * spot/tl/dot.cc: Show the min/max argument for Star/FStar nodes. * tests/python/formulas.ipynb: Adjust test. --- spot/tl/dot.cc | 22 +++- tests/python/formulas.ipynb | 253 +++++++++++++++++++----------------- 2 files changed, 155 insertions(+), 120 deletions(-) diff --git a/spot/tl/dot.cc b/spot/tl/dot.cc index a67de5fab..2bfbb43da 100644 --- a/spot/tl/dot.cc +++ b/spot/tl/dot.cc @@ -1,5 +1,5 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2009-2015, 2018-2019 Laboratoire de Recherche et +// Copyright (C) 2009-2015, 2018-2019, 2021 Laboratoire de Recherche et // Développement de l'Epita (LRDE). // Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 // (LIP6), département Systèmes Répartis Coopératifs (SRC), Université @@ -42,7 +42,7 @@ namespace spot { os_ << "digraph G {\n"; rec(f); - os_ << " subgraph atoms {\n rank=sink;\n" + os_ << " subgraph atoms {\n rank=sink\n" << sinks_->str() << " }\n}\n"; } @@ -61,9 +61,23 @@ namespace spot op o = f.kind(); std::string str = (o == op::ap) ? f.ap_name() : f.kindstr(); + if (o == op::Star || o == op::FStar) + { + unsigned min = f.min(); + unsigned max = f.max(); + if (min != 0 || max != formula::unbounded()) + { + str += "\n" + std::to_string(min); + if (max != min) + str += ".."; + if (max != formula::unbounded()) + str += std::to_string(max); + } + } + if (o == op::ap || f.is_constant()) - *sinks_ << " " << src << " [label=\"" - << str << "\", shape=box];\n"; + *sinks_ << " " << src + << " [label=\"" << str << "\", shape=box];\n"; else os_ << " " << src << " [label=\"" << str << "\"];\n"; diff --git a/tests/python/formulas.ipynb b/tests/python/formulas.ipynb index de64bbc09..95241be9d 100644 --- a/tests/python/formulas.ipynb +++ b/tests/python/formulas.ipynb @@ -57,10 +57,10 @@ { "data": { "text/latex": [ - "$\\{a \\mathbin{\\mathsf{;}} \\mathsf{first\\_match}(b^{\\star} \\mathbin{\\mathsf{;}} c^+ \\mathbin{\\mathsf{;}} d)\\}\\mathrel{\\Diamond\\kern-1.7pt\\raise.4pt\\hbox{$\\mathord{\\rightarrow}$}} (c \\land \\mathsf{G} \\mathsf{F} b)$" + "$\\{a \\mathbin{\\mathsf{;}} \\mathsf{first\\_match}(\\{b^{\\star} \\mathbin{\\mathsf{;}} c^+\\}^{\\mathsf{:}\\star3..5} \\mathbin{\\mathsf{;}} b)\\}\\mathrel{\\Diamond\\kern-1.7pt\\raise.4pt\\hbox{$\\mathord{\\rightarrow}$}} (c \\land \\mathsf{G} \\mathsf{F} b)$" ], "text/plain": [ - "spot.formula(\"{a;first_match(b[*];c[+];d)}<>-> (c & GFb)\")" + "spot.formula(\"{a;first_match({b[*];c[+]}[:*3..5];b)}<>-> (c & GFb)\")" ] }, "execution_count": 3, @@ -69,7 +69,7 @@ } ], "source": [ - "g = spot.formula('{a;first_match(b*;c[+];d)}<>->(GFb & c)'); g" + "g = spot.formula('{a;first_match((b*;c[+])[:*3..5];b)}<>->(GFb & c)'); g" ] }, { @@ -497,7 +497,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{a;first_match(b[*];c[+];d)}<>-> (c & GFb)\n" + "{a;first_match({b[*];c[+]}[:*3..5];b)}<>-> (c & GFb)\n" ] }, { @@ -509,42 +509,42 @@ "\n", "\n", - "\n", - "\n", + "\n", + "\n", "G\n", - "\n", + "\n", "\n", "\n", "0\n", - "\n", - "EConcat\n", + "\n", + "EConcat\n", "\n", "\n", "\n", "1\n", - "\n", - "Concat\n", + "\n", + "Concat\n", "\n", "\n", - "\n", + "\n", "0->1\n", - "\n", - "\n", - "L\n", + "\n", + "\n", + "L\n", "\n", - "\n", - "\n", - "10\n", - "\n", - "And\n", + "\n", + "\n", + "11\n", + "\n", + "And\n", "\n", - "\n", - "\n", - "0->10\n", - "\n", - "\n", - "R\n", + "\n", + "\n", + "0->11\n", + "\n", + "\n", + "R\n", "\n", "\n", "\n", @@ -555,133 +555,154 @@ "\n", "\n", "1->2\n", - "\n", - "\n", - "1\n", + "\n", + "\n", + "1\n", "\n", "\n", "\n", "3\n", - "\n", - "first_match\n", + "\n", + "first_match\n", "\n", "\n", - "\n", + "\n", "1->3\n", - "\n", - "\n", - "2\n", + "\n", + "\n", + "2\n", "\n", "\n", "\n", "4\n", - "\n", - "Concat\n", + "\n", + "Concat\n", "\n", "\n", - "\n", + "\n", "3->4\n", - "\n", - "\n", + "\n", + "\n", "\n", "\n", "\n", "5\n", - "\n", - "Star\n", + "\n", + "FStar\n", + "3..5\n", "\n", "\n", - "\n", + "\n", "4->5\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "7\n", - "\n", - "Star\n", - "\n", - "\n", - "\n", - "4->7\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "9\n", - "\n", - "d\n", - "\n", - "\n", - "\n", - "4->9\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "6\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "5->6\n", - "\n", - "\n", + "\n", + "\n", + "1\n", "\n", "\n", "\n", "8\n", - "\n", - "c\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "4->8\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "Concat\n", + "\n", + "\n", + "\n", + "5->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "Star\n", + "\n", + "\n", + "\n", + "6->7\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "9\n", + "\n", + "Star\n", + "1..\n", + "\n", + "\n", + "\n", + "6->9\n", + "\n", + "\n", + "2\n", "\n", "\n", - "\n", + "\n", "7->8\n", - "\n", - "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "10->8\n", - "\n", - "\n", + "\n", + "\n", + "10\n", + "\n", + "c\n", "\n", - "\n", - "\n", - "11\n", - "\n", - "G\n", + "\n", + "\n", + "9->10\n", + "\n", + "\n", "\n", - "\n", - "\n", - "10->11\n", - "\n", - "\n", + "\n", + "\n", + "11->10\n", + "\n", + "\n", "\n", "\n", "\n", "12\n", - "\n", - "F\n", + "\n", + "G\n", "\n", "\n", - "\n", + "\n", "11->12\n", - "\n", - "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "12->6\n", - "\n", - "\n", + "\n", + "\n", + "13\n", + "\n", + "F\n", + "\n", + "\n", + "\n", + "12->13\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "13->8\n", + "\n", + "\n", "\n", "\n", "\n" @@ -973,7 +994,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.9.2" } }, "nbformat": 4,