org: syntax-highlight the HOA outputs
* elisp/hoa-mode.el, elisp/Makefile.am, elisp/README: New files. * debian/copyright, configure.ac, README, Makefile.am: Adjust. * doc/org/init.el.in: Adjust to load hoa-mode.el. * doc/org/spot.css: Add entries for HOA mode. * doc/org/hoa.org, doc/org/ltldo.org, doc/org/oaut.org, doc/org/tut20.org, doc/org/tut21.org, doc/org/tut22.org, doc/org/tut30.org: Make the HOA outputs as HOA.
This commit is contained in:
parent
d46da963d5
commit
5aba246ff0
16 changed files with 449 additions and 132 deletions
|
|
@ -21,14 +21,14 @@
|
|||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if NEVER
|
||||
# For Automake a conditional directory
|
||||
# For Automake a, conditional directory
|
||||
# is conditionally built, but unconditionally distributed.
|
||||
# So using NEVER here ensures that `make all' will not
|
||||
# recurse in bench/, but `make dist' will.
|
||||
NEVER_BENCH = bench
|
||||
NEVER_SUBDIRS = bench elisp
|
||||
endif
|
||||
|
||||
SUBDIRS = buddy lib src wrap ltdl iface doc $(NEVER_BENCH)
|
||||
SUBDIRS = buddy lib src wrap ltdl iface doc $(NEVER_SUBDIRS)
|
||||
|
||||
UTF8 = utf8/doc/ReleaseNotes utf8/doc/utf8cpp.html utf8/utf8.h \
|
||||
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h
|
||||
|
|
|
|||
1
README
1
README
|
|
@ -180,6 +180,7 @@ buddy/ A customized version of BuDDy 2.3 (a BDD library).
|
|||
ltdl/ Libtool's portable dlopen() wrapper library.
|
||||
lib/ Gnulib's portability modules.
|
||||
utf8/ Nemanja Trifunovic's utf-8 routines.
|
||||
elisp/ Related emacs modes, used for building the documentation.
|
||||
|
||||
Build-system stuff
|
||||
------------------
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ AC_CONFIG_FILES([
|
|||
doc/tl/Makefile
|
||||
doc/org/.dir-locals.el
|
||||
doc/org/init.el
|
||||
elisp/Makefile
|
||||
iface/ltsmin/defs
|
||||
iface/ltsmin/Makefile
|
||||
iface/Makefile
|
||||
|
|
|
|||
19
debian/copyright
vendored
19
debian/copyright
vendored
|
|
@ -125,6 +125,25 @@ Copyright: (unknown) D A Gwyn
|
|||
License: public-domain
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
Files: elisp/hoa-mode.el
|
||||
Copyright: 2015 Alexandre Duret-Lutz
|
||||
License: GPL-3+
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2015 Laboratoire de Recherche et Développement de l'Epita (LRDE)
|
||||
License: GPL-3+
|
||||
|
|
|
|||
108
doc/org/hoa.org
108
doc/org/hoa.org
|
|
@ -139,12 +139,12 @@ EOF
|
|||
|
||||
#+RESULTS:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports results
|
||||
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
|
||||
sed -n '/--BODY/,/--END/p' stvstracc.hoa | grep -v -- --
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
/* state-based acceptance */
|
||||
State: 0 {0 1}
|
||||
[0&!1] 0
|
||||
|
|
@ -158,16 +158,16 @@ State: 1 {0}
|
|||
State: 2
|
||||
[!0] 1 {0}
|
||||
[0] 2 {1}
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
will always be stored as a TωA with this transition structure:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports results
|
||||
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
|
||||
autfilt -Ht stvstracc.hoa | sed -n '/--BODY/,/--END/p' | grep -v -- --
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
State: 0
|
||||
[0&!1] 0 {0 1}
|
||||
[0&1] 1 {0 1}
|
||||
|
|
@ -178,7 +178,7 @@ State: 1
|
|||
State: 2
|
||||
[!0] 1 {0}
|
||||
[0] 2 {1}
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC sh :results silent :exports results
|
||||
rm -f stvstracc.hoa
|
||||
|
|
@ -201,8 +201,8 @@ For instance in the following automaton, the outgoing transitions of
|
|||
each states belong to the same sets:
|
||||
|
||||
#+NAME: state-based-example
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
cat >sba.hoa <<EOF
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
cat >sba.hoa <<EOF_HOA
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
|
|
@ -220,14 +220,14 @@ State: 2
|
|||
[!0] 1 {0 1}
|
||||
[0] 2 {0 1}
|
||||
--END--
|
||||
EOF
|
||||
EOF_HOA
|
||||
autfilt -H sba.hoa
|
||||
#+END_SRC
|
||||
|
||||
so the HOA output of =autfilt= automatically uses state-based acceptance:
|
||||
|
||||
#+RESULTS: state-based-example
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
|
|
@ -247,7 +247,7 @@ State: 2 {0 1}
|
|||
[!0] 1
|
||||
[0] 2
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
The rational for this automatic switch to state-based acceptance is as follows:
|
||||
- Tools that support transition-based acceptance can easily see
|
||||
|
|
@ -265,12 +265,12 @@ Nevertheless, should you really insist on having an output with
|
|||
transition-based acceptance, you can do so by passing the option =t=
|
||||
to the HOA printer:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
autfilt -Ht sba.hoa
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
|
|
@ -290,7 +290,7 @@ State: 2
|
|||
[!0] 1 {0 1}
|
||||
[0] 2 {0 1}
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC sh :results silent :exports results
|
||||
rm sba.hoa
|
||||
|
|
@ -302,12 +302,12 @@ format to prevents mixing the two: if you use =-Hm=, the decision of
|
|||
using state or transition-based acceptance will be made for each state
|
||||
separately. For instance:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -Hm 'GFa | Fb'
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "F(b | GFa)"
|
||||
States: 3
|
||||
|
|
@ -327,7 +327,7 @@ State: 2
|
|||
[1] 2 {0}
|
||||
[!1] 2
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
|
||||
So far we have discussed transforming state-based acceptance into
|
||||
|
|
@ -342,12 +342,12 @@ when necessary. Most tools have a =-S= option (or
|
|||
=--state-based-acceptance=) for this purpose. Compare the following
|
||||
output with the previous one.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -S -Hm 'GFa | Fb'
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "F(b | GFa)"
|
||||
States: 4
|
||||
|
|
@ -370,7 +370,7 @@ State: 3
|
|||
[1] 2
|
||||
[!1] 3
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
** Generic acceptance
|
||||
|
||||
|
|
@ -431,7 +431,7 @@ In the following example, you can see =autfilt= removing the duplicate
|
|||
Rabin pair, and reordering the remaining pair to fit the syntax
|
||||
corresponding to =Rabin 1=.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
autfilt -H <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
|
|
@ -454,7 +454,7 @@ EOF
|
|||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
|
|
@ -474,9 +474,7 @@ State: 2 {0 1}
|
|||
[!0] 1
|
||||
[0] 2
|
||||
--END--
|
||||
#+end_example
|
||||
|
||||
|
||||
#+END_SRC
|
||||
|
||||
Internally, the acceptance condition is stored as an array in reverse
|
||||
polish notation, and the primitives =Inf= and =Fin= are actually
|
||||
|
|
@ -500,12 +498,14 @@ When you look at an acceptance condition output by Spot, you can
|
|||
actually spot the terms that have been grouped together internally by
|
||||
looking at the spacing around operators =&= and =|=. For instance:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
randaut -A"Fin(0)|Fin(1)|Fin(2)&Fin(3)&Inf(4)&Inf(5)" -H 0 | grep Acceptance:
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
: Acceptance: 6 (Fin(0)|Fin(1)) | (Fin(2) & Fin(3) & (Inf(4)&Inf(5)))
|
||||
#+BEGIN_SRC hoa
|
||||
Acceptance: 6 (Fin(0)|Fin(1)) | (Fin(2) & Fin(3) & (Inf(4)&Inf(5)))
|
||||
#+END_SRC
|
||||
|
||||
Here =Fin(0)|Fin(1)= is actually a single internal term =Fin({0,1})=,
|
||||
and likewise for =Inf(4)&Inf(5)=.
|
||||
|
|
@ -611,7 +611,7 @@ They are currently two named properties related to the HOA format.
|
|||
You can see these properties being preserved when an automaton is read and then immediately output:
|
||||
|
||||
#+NAME: hello-world
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
cat >hw.hoa <<EOF
|
||||
HOA: v1
|
||||
name: "hello world!"
|
||||
|
|
@ -636,7 +636,7 @@ autfilt -H hw.hoa
|
|||
#+END_SRC
|
||||
|
||||
#+RESULTS: hello-world
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "hello world!"
|
||||
States: 3
|
||||
|
|
@ -657,7 +657,7 @@ State: 2 "so am I" {0 1}
|
|||
[!0] 1
|
||||
[0] 2
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
However if =autfilt= performs some transformation, and actually has to
|
||||
construct a new automaton, those properties will not be quarried over
|
||||
|
|
@ -670,32 +670,32 @@ the old states and the new ones.
|
|||
Here is for instance the result when =autfilt= is instructed to
|
||||
simplify the automaton:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
autfilt -H --small hw.hoa
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc deterministic
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&!1] 0
|
||||
[0&1] 1 {0}
|
||||
[!0] 2 {0}
|
||||
[0&1] 1
|
||||
[!0] 2
|
||||
State: 1
|
||||
[0&!1] 1
|
||||
[0&1] 2
|
||||
State: 2
|
||||
[!0] 1 {0}
|
||||
[0] 2 {0}
|
||||
State: 2 {0}
|
||||
[!0] 1
|
||||
[0] 2
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
|
||||
Note that if the name of the automaton is important to you, it can be
|
||||
|
|
@ -703,12 +703,12 @@ fixed via the =--name= option. For instance =--name=%M= will
|
|||
construct the new name by simply copying the one of the original
|
||||
automaton.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
autfilt -H --small hw.hoa --name=%M
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "hello world!"
|
||||
States: 3
|
||||
|
|
@ -716,20 +716,20 @@ Start: 0
|
|||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc deterministic
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&!1] 0
|
||||
[0&1] 1 {0}
|
||||
[!0] 2 {0}
|
||||
[0&1] 1
|
||||
[!0] 2
|
||||
State: 1
|
||||
[0&!1] 1
|
||||
[0&1] 2
|
||||
State: 2
|
||||
[!0] 1 {0}
|
||||
[0] 2 {0}
|
||||
State: 2 {0}
|
||||
[!0] 1
|
||||
[0] 2
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
The page about [[file:oaut.org][common output option for automata]] has a section showing
|
||||
how =--name= can be used to construct complex pipelines with automata that
|
||||
|
|
@ -748,12 +748,12 @@ in the HOA format, and then read those automata with =autfilt= to
|
|||
randomize the order of their transitions and states before printing
|
||||
them in HOA format.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
genltl --and-gf=1..3 | ltl2tgba -B -F- -H | autfilt --randomize -H
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "GFp1"
|
||||
States: 2
|
||||
|
|
@ -762,7 +762,7 @@ AP: 1 "p1"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
properties: deterministic stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
|
|
@ -779,7 +779,7 @@ AP: 2 "p1" "p2"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
properties: deterministic stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0&1] 2
|
||||
|
|
@ -801,7 +801,7 @@ AP: 3 "p1" "p2" "p3"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
properties: deterministic stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[!2] 0
|
||||
|
|
@ -821,7 +821,7 @@ State: 3
|
|||
[0] 1
|
||||
[!0] 3
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
|
||||
It should be noted that the HOA parser is less efficient when it reads
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
;; htmlize is not always in the load-path. On Debian it can be found here.
|
||||
(setq load-path (cons "/usr/share/emacs/site-lisp/emacs-goodies-el" load-path))
|
||||
(setq load-path (append '("@abs_top_srcdir@/elisp/" ; for hoa-mode.el
|
||||
;; htmlize is not always in the load-path.
|
||||
;; On Debian it can be found here.
|
||||
"/usr/share/emacs/site-lisp/emacs-goodies-el")
|
||||
load-path))
|
||||
(or (require 'org-publish nil t) ; Org 7
|
||||
(require 'ox-publish)) ; Org 8
|
||||
(require 'org-install)
|
||||
(require 'hoa-mode)
|
||||
|
||||
(print (concat "Org " (org-version)))
|
||||
(setq org-export-htmlize-output-type 'css)
|
||||
|
|
|
|||
|
|
@ -128,19 +128,20 @@ Here is another example, where we use Spin to produce two automata in
|
|||
the [[http://adl.github.io/hoaf/][HOA format]]. Spin has no support for HOA, but =ltldo= simply
|
||||
converts the never claim produced by =spin= into this format.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltldo -f a -f GFa 'spin -f %s>%O' -H
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 2
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
properties: trans-labels explicit-labels state-acc colored
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0] 1
|
||||
|
|
@ -161,7 +162,7 @@ State: 0
|
|||
State: 1 {0}
|
||||
[t] 0
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
Again, using the shorthands defined below, the previous command can be
|
||||
simplified to just this:
|
||||
|
|
@ -405,34 +406,35 @@ an LTL formula). In the following example, you can see that the
|
|||
automaton uses the atomic proposition =Error=, but its name contains a
|
||||
reference to =p0=.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltldo 'ltl3ba -H' -f '[]!Error' -H
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "BA for ([](!(p0)))"
|
||||
name: "BA for [](!(p0))"
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 1 "Error"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
properties: trans-labels explicit-labels state-acc colored
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0 "accept_init" {0}
|
||||
[!0] 0
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
If this is a problem, you can always force a new name with the
|
||||
=--name= option:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltldo 'ltl3ba -H' -f '[]!Error' -H --name='BA for %f'
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "BA for []!Error"
|
||||
States: 1
|
||||
|
|
@ -440,12 +442,13 @@ Start: 0
|
|||
AP: 1 "Error"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
properties: trans-labels explicit-labels state-acc colored
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0 "accept_init" {0}
|
||||
[!0] 0
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
* Controlling and measuring time
|
||||
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@ format can be found on a [[file:hoa.org][separate page]].)
|
|||
Here is an example where [[file:ltl2tgba.org][=ltl2tgba=]] is used to construct two automata:
|
||||
one for =a U b= and one for =(Ga -> Gb) W c=.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -H 'a U b' '(Ga -> Gb) W c'
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "a U b"
|
||||
States: 2
|
||||
|
|
@ -84,6 +84,7 @@ AP: 2 "a" "b"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
properties: stutter-invariant terminal
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 0
|
||||
|
|
@ -98,7 +99,7 @@ Start: 1
|
|||
AP: 3 "b" "a" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc
|
||||
properties: trans-labels explicit-labels trans-acc stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 0 {0}
|
||||
|
|
@ -118,7 +119,7 @@ State: 4
|
|||
[!1] 3
|
||||
[1] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
The above output contains two automata, named after the formulas they
|
||||
represent. Here is a picture of these two automata:
|
||||
|
|
@ -301,36 +302,37 @@ to use state-based acceptance whenever possible. Option =t= forces
|
|||
transition-based acceptance. For instance compare this output to the
|
||||
previous one:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -Ht 'a U b'
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "a U b"
|
||||
States: 2
|
||||
Start: 0
|
||||
Start: 1
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc deterministic
|
||||
properties: stutter-invariant terminal
|
||||
--BODY--
|
||||
State: 0
|
||||
[1] 1
|
||||
[0&!1] 0
|
||||
[t] 0 {0}
|
||||
State: 1
|
||||
[t] 1 {0}
|
||||
[1] 0
|
||||
[0&!1] 1
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
Option =m= uses mixed acceptance, i.e, some states might use
|
||||
state-based acceptance while other will not:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -Hm '(Ga -> Gb) W c'
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "(Gb | F!a) W c"
|
||||
States: 5
|
||||
|
|
@ -338,7 +340,7 @@ Start: 1
|
|||
AP: 3 "b" "a" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels
|
||||
properties: trans-labels explicit-labels stutter-invariant
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0] 0
|
||||
|
|
@ -358,7 +360,7 @@ State: 4
|
|||
[!1] 3
|
||||
[1] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
|
||||
It is also possible to output each automaton on a single line, in case
|
||||
|
|
@ -366,12 +368,14 @@ the result should be used with line-based tools or embedded into a CSV
|
|||
file... Here is an example using both transition-based acceptance,
|
||||
and single-line output:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -Htl 'a U b' '(Ga -> Gb) W c'
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
: HOA: v1 name: "a U b" States: 2 Start: 1 AP: 2 "a" "b" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels explicit-labels trans-acc deterministic --BODY-- State: 0 [t] 0 {0} State: 1 [1] 0 [0&!1] 1 --END--
|
||||
: HOA: v1 name: "(Gb | F!a) W c" States: 5 Start: 1 AP: 3 "b" "a" "c" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels explicit-labels trans-acc --BODY-- State: 0 [0] 0 {0} State: 1 [0&1&!2] 0 [!1&!2] 1 {0} [1&!2] 2 [2] 3 State: 2 [!1&!2] 1 {0} [1&!2] 2 [!1&2] 3 [1&2] 4 State: 3 [t] 3 {0} State: 4 [!1] 3 [1] 4 --END--
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1 name: "a U b" States: 2 Start: 1 AP: 2 "a" "b" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels explicit-labels trans-acc deterministic stutter-invariant terminal --BODY-- State: 0 [t] 0 {0} State: 1 [1] 0 [0&!1] 1 --END--
|
||||
HOA: v1 name: "(Gb | F!a) W c" States: 5 Start: 1 AP: 3 "b" "a" "c" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels explicit-labels trans-acc stutter-invariant --BODY-- State: 0 [0] 0 {0} State: 1 [0&1&!2] 0 [!1&!2] 1 {0} [1&!2] 2 [2] 3 State: 2 [!1&!2] 1 {0} [1&!2] 2 [!1&2] 3 [1&2] 4 State: 3 [t] 3 {0} State: 4 [!1] 3 [1] 4 --END--
|
||||
#+END_SRC
|
||||
|
||||
* LBTT output
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ body a{color:#008181}
|
|||
div#postamble{visibility:hidden}
|
||||
.outline-2 h2{border-bottom-style:solid;border-color:#ffe35e}
|
||||
pre.src{padding-top:8px;border-left-style:solid;border-color:#00adad;overflow:auto}
|
||||
pre.src-hoa{padding-top:8px;border-left-style:solid;border-color:#d70079;overflow:auto}
|
||||
pre.example{border-left-style:solid;border-color:#d70079}
|
||||
pre.src:before{border:none;border-bottom-style:solid;border-color:#00adad}
|
||||
pre.src:before{border:none;border-bottom-style:solid;border-color:#00adad;top:0px;}
|
||||
pre.src-hoa:before{content:'HOA';border:none;border-bottom-style:solid;border-color:#d70079;overflow:auto}
|
||||
img{max-width:100%}
|
||||
@media screen{
|
||||
#table-of-contents{position:fixed;right:0em;top:0em;max-width:50%;max-height:80%;overflow:auto;z-index:10}
|
||||
|
|
@ -34,7 +36,14 @@ img{max-width:100%}
|
|||
.org-builtin{font-weight:bold}
|
||||
.org-preprocessor{font-weight:bold}
|
||||
.org-string{font-weight:bold;color:#00adad}
|
||||
.src-hoa .org-string{font-weight:bold;color:#d70079}
|
||||
.org-function-name{font-weight:bold;color:#d70079}
|
||||
.org-type{font-weight:bold;color:#00adad}
|
||||
.org-comment-delimiter{font-weight:bold;color:#a13672}
|
||||
.org-comment{font-style:italic;color:#a13672}
|
||||
.org-hoa-keyword{font-weight:bold}
|
||||
.org-hoa-builtin{font-weight:bold}
|
||||
.org-hoa-acceptance-set{font-weight:bold}
|
||||
.org-hoa-header-uppercase{font-weight:bold;color:#00adad}
|
||||
.org-hoa-header-lowercase{color:#00adad}
|
||||
.org-hoa-ap-number{color:#d70079}
|
||||
|
|
|
|||
|
|
@ -52,12 +52,12 @@ This is very simple: [[file:autfilt.org][=autfilt=]] can read automata in any of
|
|||
supported formats, so all we have to do is to request the HOA output
|
||||
with =-H=:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
autfilt -H tut20.never
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 0
|
||||
|
|
@ -81,7 +81,7 @@ State: 4
|
|||
[1] 3
|
||||
[t] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
* Python
|
||||
|
||||
|
|
@ -89,13 +89,13 @@ Another one-liner. The =spot.automaton()= function reads a single
|
|||
automaton, and each automaton has a =to_str()= method that can print
|
||||
in =hoa=, =lbtt=, =spin= (for never claim) or =dot=.
|
||||
|
||||
#+BEGIN_SRC python :results output :exports both
|
||||
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
|
||||
import spot
|
||||
print(spot.automaton('tut20.never').to_str('hoa'))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 0
|
||||
|
|
@ -119,7 +119,7 @@ State: 4
|
|||
[1] 3
|
||||
[t] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
* C++
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ you), and =aut= is the actual automaton. The parser usually tries to
|
|||
recover from errors, so =aut= may not be null even if =errors= is
|
||||
non-empty.
|
||||
|
||||
#+BEGIN_SRC C++ :results verbatim :exports both
|
||||
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "parseaut/public.hh"
|
||||
|
|
@ -159,7 +159,7 @@ non-empty.
|
|||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 0
|
||||
|
|
@ -183,7 +183,7 @@ State: 4
|
|||
[1] 3
|
||||
[t] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
In automata, transitions guards are represented by BDDs. The role of
|
||||
=bdd_dict= object is to keep track of the correspondence between BDD
|
||||
|
|
@ -221,14 +221,14 @@ an =automaton_stream_parser= and calls its =parse()= method once.
|
|||
In Python, you can easily iterate over a file containing multiple
|
||||
automata by doing:
|
||||
|
||||
#+BEGIN_SRC python :results output :exports code
|
||||
#+BEGIN_SRC python :results output :exports code :wrap SRC hoa
|
||||
import spot
|
||||
for aut in spot.automata('tut20.never'):
|
||||
print(aut.to_str('hoa'))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 0
|
||||
|
|
@ -252,7 +252,7 @@ State: 4
|
|||
[1] 3
|
||||
[t] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
In fact =spot.automaton()= is just a wrapper around =spot.automata()=
|
||||
to return only the first automaton.
|
||||
|
|
|
|||
|
|
@ -10,12 +10,11 @@ commands aren't up to the task either.
|
|||
|
||||
First let's create an example automaton in HOA format.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
ltl2tgba -U -H 'Fa | G(Fb&Fc)' | tee tut21.hoa
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
name: "Fa | G(Fb & Fc)"
|
||||
States: 4
|
||||
|
|
@ -41,7 +40,7 @@ State: 3
|
|||
[!0&1&!2] 3 {0}
|
||||
[!0&!1&!2] 3
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
We now write some C++ to load this automaton [[file:tut20.org][as we did before]], and in
|
||||
=custom_print()= we print it out in a custom way by explicitly
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
This example demonstrates how to create an automaton in C++, and then print it.
|
||||
|
||||
#+BEGIN_SRC C++ :results verbatim :exports both
|
||||
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
|
||||
#include <iostream>
|
||||
#include "twaalgos/hoa.hh"
|
||||
#include "twa/twagraph.hh"
|
||||
|
|
@ -47,7 +47,7 @@ This example demonstrates how to create an automaton in C++, and then print it.
|
|||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
|
|
@ -64,4 +64,4 @@ State: 1
|
|||
State: 2
|
||||
[0 | 1] 1 {0 1}
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ autfilt tut30.hoa --dot=.a
|
|||
#+begin_example
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
label=<(Fin(<font color="#5DA5DA">â¿</font>) & Inf(<font color="#F17CB0">â¶</font>)) | (Fin(<font color="#FAA43A">â·</font>) & Inf(<font color="#B276B2">â¸</font>)) | (Fin(<font color="#60BD68">â¹</font>) & Inf(<font color="#F15854">âº</font>))>
|
||||
label=<(Fin(<font color="#5DA5DA">⓿</font>) & Inf(<font color="#F17CB0">❶</font>)) | (Fin(<font color="#FAA43A">❷</font>) & Inf(<font color="#B276B2">❸</font>)) | (Fin(<font color="#60BD68">❹</font>) & Inf(<font color="#F15854">❺</font>))>
|
||||
labelloc="t"
|
||||
node [shape="circle"]
|
||||
fontname="Lato"
|
||||
|
|
@ -29,25 +29,25 @@ digraph G {
|
|||
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 6
|
||||
0 [label=<0<br/><font color="#FAA43A">â·</font><font color="#F15854">âº</font>>]
|
||||
0 [label=<0<br/><font color="#FAA43A">❷</font><font color="#F15854">❺</font>>]
|
||||
0 -> 2 [label=<!p1>]
|
||||
0 -> 4 [label=<p1>]
|
||||
1 [label=<1<br/><font color="#FAA43A">â·</font><font color="#F15854">âº</font>>]
|
||||
1 [label=<1<br/><font color="#FAA43A">❷</font><font color="#F15854">❺</font>>]
|
||||
1 -> 4 [label=<!p1>]
|
||||
1 -> 3 [label=<p1>]
|
||||
2 [label=<2<br/><font color="#B276B2">â¸</font><font color="#60BD68">â¹</font>>]
|
||||
2 [label=<2<br/><font color="#B276B2">❸</font><font color="#60BD68">❹</font>>]
|
||||
2 -> 0 [label=<!p1>]
|
||||
2 -> 4 [label=<p1>]
|
||||
3 [label=<3<br/><font color="#B276B2">â¸</font><font color="#60BD68">â¹</font>>]
|
||||
3 [label=<3<br/><font color="#B276B2">❸</font><font color="#60BD68">❹</font>>]
|
||||
3 -> 4 [label=<!p1>]
|
||||
3 -> 1 [label=<p1>]
|
||||
4 [label=<4<br/><font color="#F17CB0">â¶</font><font color="#FAA43A">â·</font><font color="#60BD68">â¹</font>>]
|
||||
4 [label=<4<br/><font color="#F17CB0">❶</font><font color="#FAA43A">❷</font><font color="#60BD68">❹</font>>]
|
||||
4 -> 4 [label=<!p1>]
|
||||
4 -> 4 [label=<p1>]
|
||||
5 [label=<5<br/><font color="#FAA43A">â·</font><font color="#60BD68">â¹</font>>]
|
||||
5 [label=<5<br/><font color="#FAA43A">❷</font><font color="#60BD68">❹</font>>]
|
||||
5 -> 2 [label=<!p1>]
|
||||
5 -> 3 [label=<p1>]
|
||||
6 [label=<6<br/><font color="#FAA43A">â·</font><font color="#60BD68">â¹</font>>]
|
||||
6 [label=<6<br/><font color="#FAA43A">❷</font><font color="#60BD68">❹</font>>]
|
||||
6 -> 5 [label=<!p1>]
|
||||
6 -> 5 [label=<p1>]
|
||||
}
|
||||
|
|
@ -76,12 +76,11 @@ changed to Büchi, but simplification routines (useless SCCs removal,
|
|||
simulation-based reductions, acceptance sets simplifications,
|
||||
WDBA-minimization, ...) will also be applied.
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
|
||||
autfilt -B -D -H tut30.hoa
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 1
|
||||
|
|
@ -89,7 +88,7 @@ AP: 1 "p1"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic inherently-weak
|
||||
properties: deterministic weak
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 0
|
||||
|
|
@ -105,7 +104,7 @@ State: 4
|
|||
[!0] 0
|
||||
[0] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: tut30out
|
||||
#+BEGIN_SRC sh :results verbatim :exports none
|
||||
|
|
@ -156,14 +155,13 @@ the result further.
|
|||
|
||||
The Python version uses the =postprocess()= routine:
|
||||
|
||||
#+BEGIN_SRC python :results output :exports both
|
||||
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
|
||||
import spot
|
||||
aut = spot.automaton('tut30.hoa').postprocess('BA', 'deterministic')
|
||||
print(aut.to_str('hoa'))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 1
|
||||
|
|
@ -171,7 +169,7 @@ AP: 1 "p1"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic inherently-weak
|
||||
properties: deterministic weak
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 0
|
||||
|
|
@ -187,7 +185,7 @@ State: 4
|
|||
[!0] 0
|
||||
[0] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
The =postprocess()= function has an interface similar to
|
||||
[[file:tut10.org][the =translate()= function discussed previously]]:
|
||||
|
|
@ -231,7 +229,7 @@ The C++ version of this code is a bit more verbose, because the
|
|||
=postprocessor= object, configure it, and then call it for each
|
||||
automaton to process.
|
||||
|
||||
#+BEGIN_SRC C++ :results verbatim :exports both
|
||||
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
|
||||
#include <iostream>
|
||||
#include "parseaut/public.hh"
|
||||
#include "twaalgos/postproc.hh"
|
||||
|
|
@ -258,7 +256,7 @@ automaton to process.
|
|||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
#+BEGIN_SRC hoa
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 1
|
||||
|
|
@ -266,7 +264,7 @@ AP: 1 "p1"
|
|||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic inherently-weak
|
||||
properties: deterministic weak
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 0
|
||||
|
|
@ -282,7 +280,7 @@ State: 4
|
|||
[!0] 0
|
||||
[0] 4
|
||||
--END--
|
||||
#+end_example
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC sh :results silent :exports results
|
||||
rm -f tut30.hoa
|
||||
|
|
|
|||
27
elisp/Makefile.am
Normal file
27
elisp/Makefile.am
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
## l'Epita (LRDE).
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
EXTRA_DIST = hoa-mode.el
|
||||
|
||||
GIT = https://gitlab.lrde.epita.fr/spot/emacs-modes/raw/master/
|
||||
|
||||
.PHONY: update-el
|
||||
update-el:
|
||||
wget $(GIT)/hoa-mode.el -O $(srcdir)/hoa-mode.el
|
||||
chmod a-w $(srcdir)/hoa-mode.el
|
||||
3
elisp/README
Normal file
3
elisp/README
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
hoa-mode.el is used when building the documentation for syntax
|
||||
highlighting the HOA files displayed in the examples. But you may
|
||||
also want to use it for editing and displaying HOA files.
|
||||
249
elisp/hoa-mode.el
Normal file
249
elisp/hoa-mode.el
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
;;; hoa-mode.el --- Major mode for the Hanoi Omega Automata format
|
||||
|
||||
;; Copyright (C) 2015 Alexandre Duret-Lutz
|
||||
|
||||
;; Author: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
;; Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
;; URL: https://gitlab.lrde.epita.fr/spot/emacs-modes
|
||||
;; Keywords: major-mode, automata, convenience
|
||||
;; Created: 2015-11-13
|
||||
|
||||
;;; License:
|
||||
|
||||
;; This package is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; This package is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Major mode for editing files in the Hanoi Omega Automata format.
|
||||
;; (See URL `http://adl.github.io/hoaf/' for that format.) This
|
||||
;; provides rules for syntax highlighting, some navigation functions,
|
||||
;; and a convenient way to display the automata in Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'auto-mode-alist '("\\.hoa\\'" . hoa-mode))
|
||||
|
||||
;;;###autoload
|
||||
(add-to-list 'magic-mode-alist '("\\<HOA:\\s-*v" . hoa-mode))
|
||||
|
||||
(defgroup hoa-mode nil
|
||||
"Major mode for editing Hanoi Omega Automata files."
|
||||
:group 'data)
|
||||
|
||||
(defgroup hoa-mode-faces nil
|
||||
"Faces used by `hoa-mode'."
|
||||
:group 'hoa-mode
|
||||
:group 'faces)
|
||||
|
||||
(defface hoa-header-uppercase-face
|
||||
'((t :inherit font-lock-type-face :weight bold))
|
||||
"Face for headers with an uppercase initial."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-header-lowercase-face
|
||||
'((t :inherit font-lock-type-face :weight normal))
|
||||
"Face for headers with a lowercase initial."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-keyword-face
|
||||
'((t :inherit font-lock-keyword-face))
|
||||
"Face used for --BODY--, --END--, and --ABORT--."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-builtin-face
|
||||
'((t :inherit font-lock-builtin-face))
|
||||
"Face used for Inf, Fin, t, and f."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-acceptance-set-face
|
||||
'((t :inherit font-lock-constant-face :weight bold))
|
||||
"Face used for acceptance sets."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-alias-face
|
||||
'((t :inherit font-lock-variable-name-face))
|
||||
"Face used for aliases."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defface hoa-ap-number-face
|
||||
'((t :inherit font-lock-constant-face))
|
||||
"Face used for numbers that denote atomic propositions."
|
||||
:group 'hoa-mode-faces)
|
||||
|
||||
(defconst hoa-alias-regex
|
||||
"@[a-zA-Z0-9_-]*\\_>"
|
||||
"Regex for matching aliases.")
|
||||
|
||||
(defvar hoa-font-lock-keywords
|
||||
(list
|
||||
'("\\_<[A-Z][a-zA-Z0-9_-]*:" . 'hoa-header-uppercase-face)
|
||||
'("\\_<[a-z][a-zA-Z0-9_-]*:" . 'hoa-header-lowercase-face)
|
||||
`(,hoa-alias-regex . 'hoa-alias-face)
|
||||
'("\\_<--\\(BODY\\|END\\|ABORT\\)--" . 'hoa-keyword-face)
|
||||
'("\\_<\\(Inf\\|Fin\\|t\\|f\\)\\_>" . 'hoa-builtin-face)
|
||||
'("(\\s-*\\([0-9]+\\)\\s-*)" 1 'hoa-acceptance-set-face)
|
||||
'("{\\(\\([0-9]\\|\\s-\\)+\\)}" 1 'hoa-acceptance-set-face)
|
||||
;; numbers between brackets denote atomic propositions.
|
||||
'("\\["
|
||||
("\\_<[0-9]+\\_>"
|
||||
(save-excursion (search-forward "]" nil t))
|
||||
nil
|
||||
(0 'hoa-ap-number-face)))
|
||||
;; likewise for numbers following an Alias: definition
|
||||
`(,(concat "Alias:\\s-*" hoa-alias-regex)
|
||||
("\\_<[0-9]+\\_>"
|
||||
(save-excursion
|
||||
(re-search-forward
|
||||
(concat "\\(" hoa-alias-regex "\\|[0-9|&!]\\|\\s-\\)+") nil t))
|
||||
nil
|
||||
(0 'hoa-ap-number-face))))
|
||||
"Hilighting rules for `hoa-mode'.")
|
||||
|
||||
(defvar hoa-mode-syntax-table
|
||||
(let ((st (make-syntax-table)))
|
||||
(modify-syntax-entry ?< "." st)
|
||||
(modify-syntax-entry ?> "." st)
|
||||
(modify-syntax-entry ?| "." st)
|
||||
(modify-syntax-entry ?_ "_" st)
|
||||
(modify-syntax-entry ?- "_" st)
|
||||
(modify-syntax-entry ?$ "." st)
|
||||
(modify-syntax-entry ?& "." st)
|
||||
(modify-syntax-entry ?+ "." st)
|
||||
(modify-syntax-entry ?/ ". 14bn" st)
|
||||
(modify-syntax-entry ?* ". 23bn" st)
|
||||
st)
|
||||
"Syntax table for `hoa-mode'.")
|
||||
|
||||
(defun hoa-start-of-automaton ()
|
||||
"Move to the start of the automaton at point."
|
||||
(interactive)
|
||||
(search-backward "HOA:"))
|
||||
|
||||
(defun hoa-end-of-automaton ()
|
||||
"Move to the end of the automaton at point."
|
||||
(interactive)
|
||||
; if we are pointing inside something that looks like --END-- or
|
||||
; --ABORT--, back out a bit.
|
||||
(if (looking-at "[ENDABORT-]*-")
|
||||
(backward-word))
|
||||
(re-search-forward "--\\(END\\|ABORT\\)--\n?"))
|
||||
|
||||
(defun hoa-mark-automaton-at-point ()
|
||||
"Mark the automaton at point."
|
||||
(interactive)
|
||||
(hoa-end-of-automaton)
|
||||
(set-mark (point))
|
||||
(hoa-start-of-automaton))
|
||||
|
||||
(defcustom hoa-display-error-buffer "*hoa-dot-error*"
|
||||
"The name of the buffer to display errors from `hoa-display-command'."
|
||||
:group 'hoa-mode
|
||||
:type 'string)
|
||||
|
||||
(defcustom hoa-display-buffer "*hoa-display*"
|
||||
"The name of the buffer to display automata."
|
||||
:group 'hoa-mode
|
||||
:type 'string)
|
||||
|
||||
(defcustom hoa-display-command "autfilt --dot='barf(Lato)' | dot -Tpng"
|
||||
"Command used to display HOA files.
|
||||
|
||||
The command is expected to take the automaton in HOA format on
|
||||
its standard input, and output an image in PNG format on its
|
||||
standard output.
|
||||
|
||||
The default value uses the tools autfilt (part of the Spot
|
||||
package, see URL `https://spot.lrde.epita.fr/') and dot (part of
|
||||
the GraphViz package, see URL `http://www.graphviz.org/')."
|
||||
:group 'hoa-mode
|
||||
:type 'string)
|
||||
|
||||
(defun hoa-display-automaton-at-point ()
|
||||
"Display the automaton-at-point.
|
||||
|
||||
This uses the command in `hoa-display-command' to convert HOA
|
||||
into PNG, and then display the result in `hoa-display-buffer'.
|
||||
If the command terminates with an error, its standard error is
|
||||
put in `hoa-display-error-buffer' and shown."
|
||||
(interactive)
|
||||
(let ((b (save-excursion (if (not (looking-at "HOA:"))
|
||||
(hoa-start-of-automaton)
|
||||
(point))))
|
||||
(e (save-excursion (hoa-end-of-automaton) (point)))
|
||||
(dotbuf (generate-new-buffer "*hoa-dot-output*"))
|
||||
(errfile (make-temp-file
|
||||
(expand-file-name "hoadot" temporary-file-directory)))
|
||||
(coding-system-for-read 'no-conversion))
|
||||
(with-current-buffer dotbuf
|
||||
(set-buffer-multibyte nil))
|
||||
(let ((exit-status
|
||||
(call-process-region b e shell-file-name nil (list dotbuf errfile)
|
||||
nil shell-command-switch hoa-display-command)))
|
||||
(when (equal 0 exit-status)
|
||||
(let ((hoa-img (create-image (with-current-buffer dotbuf (buffer-string))
|
||||
'png t)))
|
||||
(with-current-buffer (get-buffer-create hoa-display-buffer)
|
||||
(erase-buffer)
|
||||
(insert-image hoa-img)
|
||||
(display-buffer (current-buffer)))))
|
||||
(when (file-exists-p errfile)
|
||||
(when (< 0 (nth 7 (file-attributes errfile)))
|
||||
(with-current-buffer (get-buffer-create hoa-display-error-buffer)
|
||||
(setq buffer-read-only nil)
|
||||
(erase-buffer)
|
||||
(format-insert-file errfile nil)
|
||||
(display-buffer (current-buffer))))
|
||||
(delete-file errfile))
|
||||
(kill-buffer dotbuf))))
|
||||
|
||||
(defvar hoa-mode-map
|
||||
(let ((map (make-keymap)))
|
||||
(define-key map "\M-e" 'hoa-end-of-automaton)
|
||||
(define-key map "\M-a" 'hoa-start-of-automaton)
|
||||
(define-key map "\C-\M-h" 'hoa-mark-automaton-at-point)
|
||||
(define-key map "\C-c\C-c" 'hoa-display-automaton-at-point)
|
||||
map)
|
||||
"Keymap for `hoa-mode'.")
|
||||
|
||||
(defcustom hoa-mode-hook nil
|
||||
"Hook run whenever `hoa-mode' is activated."
|
||||
:group 'hoa-mode
|
||||
:type 'hook)
|
||||
|
||||
;;;### autoload
|
||||
(defun hoa-mode ()
|
||||
"Major mode for editing files in the Hanoi Omega Automata format.
|
||||
|
||||
See URL `http://adl.github.io/hoaf/' for a definition of that format.
|
||||
|
||||
The following key bindings are installed in hoa-mode:
|
||||
|
||||
\\{hoa-mode-map}
|
||||
|
||||
By default the `hoa-display-automaton-at-point' function requires
|
||||
extra software (Spot and GraphViz), but can be configured to use
|
||||
other tools. See that function for details."
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
(set-syntax-table hoa-mode-syntax-table)
|
||||
(set (make-local-variable 'font-lock-defaults) '(hoa-font-lock-keywords))
|
||||
(use-local-map hoa-mode-map)
|
||||
(setq major-mode 'hoa-mode)
|
||||
(setq mode-name "HOA")
|
||||
(run-hooks 'hoa-mode-hook))
|
||||
|
||||
(provide 'hoa-mode)
|
||||
|
||||
;;; hoa-mode.el ends here
|
||||
Loading…
Add table
Add a link
Reference in a new issue