#! /bin/sh
# -*- coding: utf-8 -*-
# Copyright (C) 2017, 2019, 2020 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/>.

. ./defs || exit 1

set -e

cat >exp <<EOF
parity 19;
0 1 0 8,9 "INIT";
9 3 1 1,2;
2 1 0 12,13;
13 5 1 1,4;
4 1 0 8,15;
15 3 1 5,6;
6 1 0 8,15;
8 3 1 2;
5 1 0 16,17;
17 4 1 5,6;
16 4 1 2;
1 1 0 10,11;
11 4 1 5,7;
7 1 0 18,19;
19 3 1 5,7;
18 3 1 2,3;
3 1 0 10,14;
14 4 1 1,4;
10 4 1 2,3;
12 5 1 2,3;
parity 16;
0 1 0 1,2 "INIT";
2 1 1 3;
3 2 0 4,5;
5 1 1 6,7;
7 1 0 8,9;
9 1 1 10,11;
11 1 0 8,12;
12 1 1 10,11;
10 2 0 8,9;
8 3 1 3,13;
13 3 0 4,5;
4 1 1 3,13;
6 2 0 14,15;
15 2 1 3,13;
14 1 1 10,16;
16 1 0 14,15;
1 1 1 3,6;
parity 5;
1 1 0 4,5 "INIT";
5 5 1 0,1;
0 1 0 2,3;
3 3 1 0,0;
2 5 1 1;
4 4 1 1,1;
EOF

: > out
for algo in ds sd lar; do
    ltlsynt --ins=a --outs=b -f 'GFa <-> GFb' --algo=$algo --print-pg >>out
done
diff out exp

cat >exp <<EOF
REALIZABLE
aag 31 1 3 1 26
2
4 49
6 57
8 59
63
10 7 9
12 5 10
14 12 3
16 12 2
18 4 10
20 18 3
22 18 2
24 6 9
26 5 24
30 26 3
32 4 24
34 32 2
36 32 3
38 7 8
40 5 38
42 40 2
44 40 3
46 21 31
48 15 46
50 17 23
52 35 43
54 50 52
56 27 54
58 37 45
60 27 52
62 23 60
i0 a
o0 b
EOF
ltlsynt --ins=a --outs=b -f 'GFa <-> GFb' --aiger=ISOP >out
diff out exp

cat >exp <<EOF
REALIZABLE
aag 28 1 3 1 24
2
4 38
6 49
8 56
29
10 6 9
12 5 10
14 7 8
16 15 11
18 4 9
20 5 17
22 21 19
24 2 23
26 3 12
28 27 25
30 7 9
32 4 30
34 5 9
36 35 33
38 3 37
40 6 11
42 5 41
44 43 19
46 2 45
48 27 47
50 4 10
52 5 14
54 53 51
56 3 55
i0 a
o0 b
EOF
ltlsynt --ins=a --outs=b -f 'GFa <-> GFb' --aiger=ITE >out
diff out exp

cat >exp <<EOF
REALIZABLE
aag 16 1 2 2 13
2
4 29
6 33
31
31
8 5 7
10 8 3
12 8 2
14 4 7
16 14 3
18 14 2
20 5 6
22 20 2
24 20 3
26 17 25
28 11 26
30 19 23
32 13 30
i0 a
o0 b
o1 c
EOF
ltlsynt --ins=a --outs=b,c -f 'GFa <-> (GFb & GFc)' --aiger=Isop >out
diff out exp

cat >exp <<EOF
REALIZABLE
aag 10 1 2 2 7
2
4 18
6 20
14
14
8 4 7
10 5 6
12 11 9
14 2 13
16 4 9
18 3 17
20 2 17
i0 a
o0 b
o1 c
EOF
ltlsynt --ins=a --outs=b,c -f 'GFa <-> (GFb & GFc)' --aiger=ite >out
diff out exp

cat >exp <<EOF
translating formula done in X seconds
automaton has 3 states and 2 colors
split inputs and outputs done in X seconds
automaton has 9 states
determinization done
DPA has 12 states, 4 colors
simplification done
DPA has 11 states
determinization and simplification took X seconds
parity game solved in X seconds
EOF
ltlsynt --ins='a' --outs='b' -f 'GFa <-> GFb' --verbose --realizability 2> out
sed 's/ [0-9.e-]* seconds/ X seconds/g' out > outx
diff outx exp

cat >exp <<EOF
translating formula done in X seconds
automaton has 3 states and 4 colors
simplification done in X seconds
DPA has 3 states
split inputs and outputs done in X seconds
automaton has 8 states
parity game solved in X seconds
EOF
ltlsynt --ins=a --outs=b -f 'GFa <-> GFb' --verbose --algo=ps 2> out
sed 's/ [0-9.e-]* seconds/ X seconds/g' out > outx
diff outx exp

cat >exp <<EOF
translating formula done in X seconds
automaton has 16 states and 2 colors
LAR construction done in X seconds
DPA has 16 states, 4 colors
split inputs and outputs done in X seconds
automaton has 47 states
parity game solved in X seconds
EOF
ltlsynt --ins='a,b,c,d' --outs='e' -f '(Fa & Fb & Fc & Fd) <-> GFe' \
        --verbose --realizability --algo=lar 2> out
sed 's/ [0-9.e-]* seconds/ X seconds/g' out > outx
diff outx exp

for r in '' '--real'; do
    opts="$r --ins=a --outs=b -f"
    ltlsynt --algo=ds $opts 'GFa <-> GFb' --csv=FILE || :
    ltlsynt --algo=sd $opts 'FGa <-> GF(b&XXb)' --csv='>>FILE' || :
    ltlsynt --algo=ps $opts 'FGa <-> GF(b&XXb)' --csv='>>FILE' || :
    ltlsynt --algo=lar $opts 'FGc <-> GF(!b&XXb)' --csv='>>FILE' || :
    ltlsynt --algo=lar.old $opts 'FGa <-> GF(c&a)' --csv='>>FILE' || :
    test 6 = `wc -l < FILE`
    # Make sure all lines in FILE have the same number of comas
    sed 's/[^,]//g' < FILE |
        ( read first
          while read l; do
              test "x$first" = "x$l" || exit 1
          done)
done
for a in sd ds lar lar.old; do
    test 1 = `grep -c ",.$a.," FILE` || exit 1
done

ltlsynt --algo=lar $opts 'FGa <-> GF(c&a)' --print-pg --csv >out
grep parity out
grep 'FGa.*,"lar",' out
grep formula out


F0='(G ((((req) -> (X ((grant) && (X ((grant) && (X (grant))))))) && ((grant)
-> (X (! (grant))))) && ((cancel) -> (X ((! (grant)) U (go))))))'
IN0='cancel, go, req'
OUT0='grant'
EXP0='UNREALIZABLE'
F1='(G ((((req) -> (X ((grant) || (X ((grant) || (X (grant))))))) && ((grant)
-> (X (! (grant))))) && ((cancel) -> (X ((! (grant)) U (go))))))'
IN1='cancel, go, req'
OUT1='grant'
EXP1='UNREALIZABLE'
F2='((G ((cancel) -> (X (go)))) -> (G ((((req) -> (X ((grant) || (X ((grant) ||
(X (grant))))))) && ((grant) -> (X (! (grant))))) && ((cancel) -> (X ((!
(grant)) U (go)))))))'
IN2='cancel, go, req'
OUT2='grant'
EXP2='REALIZABLE'
F3='((G ((cancel) -> (X ((go) || (X (go)))))) -> (G ((((req) -> (X ((grant) ||
(X ((grant) || (X (grant))))))) && ((grant) -> (X (! (grant))))) && ((cancel)
-> (X ((! (grant)) U (go)))))))'
IN3='cancel, go, req'
OUT3='grant'
EXP3='REALIZABLE'
F4='((G ((cancel) -> (X ((go) || (X (go)))))) -> (G ((((req) -> (X (((grant) ||
(cancel)) || (X (((grant) || (cancel)) || (X ((grant) || (cancel)))))))) &&
((grant) -> (X (! (grant))))) && ((cancel) -> (X ((! (grant)) U (go)))))))'
IN4='cancel, go, req'
OUT4='grant'
EXP4='REALIZABLE'
F5='((G ((cancel) -> (X ((go) || (X ((go) || (X (go)))))))) -> (G ((((req) ->
(X (((grant) || (cancel)) || (X (((grant) || (cancel)) || (X ((grant) ||
(cancel)))))))) && ((grant) -> (X (! (grant))))) && ((cancel) -> (X ((!
(grant)) U (go)))))))'
IN5='cancel, go, req'
OUT5='grant'
EXP5='REALIZABLE'
F6='((G ((cancel) -> (X ((go) || (X (go)))))) -> (G ((((cancel) -> (X ((!
(grant)) U (go)))) && ((grant) -> (X (! (grant))))) && ((req) -> (((grant) ||
(cancel)) || (X (((grant) || (cancel)) || (X (((grant) || (cancel)) || (X
((grant) || (cancel))))))))))))'
IN6='cancel, go, req'
OUT6='grant'
EXP6='REALIZABLE'
F7='(! ((G ((req) -> (F (ack)))) && (G ((go) -> (F (grant))))))'
IN7='go, req'
OUT7='ack, grant'
EXP7='UNREALIZABLE'
F8='(((G ((((r1) -> (F (a1))) && ((r2) -> (F (a2)))) && (! ((a1) && (a2))))) &&
(((a1) U (r1)) || (G (a1)))) && (((a2) U (r2)) || (G (a2))))'
IN8='r1, r2'
OUT8='a1, a2'
EXP8='UNREALIZABLE'
F9='((((G (((((((r0) -> (F (a0))) && ((r1) -> (F (a1)))) && ((r2) -> (F (a2))))
&& (! ((a0) && (a1)))) && (! ((a0) && (a2)))) && (! ((a1) && (a2))))) && (((a0)
U (r0)) || (G (a0)))) && (((a1) U (r1)) || (G (a1)))) && (((a2) U (r2)) || (G
(a2))))'
IN9='r0, r1, r2'
OUT9='a0, a1, a2'
EXP9='UNREALIZABLE'
IN10='a, b, c'
OUT10='p0, p1, p2'
F10='G (p0 && ! p1 && ! p2 || (! p0 && p1 && ! p2) || (! p0 && ! p1 && p2)) &&
  (F (G a) || F (G b) || G (F c) <-> (G (F p0) || (G (F p1) && ! G (F p2))))'
EXP10='REALIZABLE'

for i in 0 1 7 8 9; do
  F=$(eval echo \$F$i)
  IN=$(eval echo \$IN$i)
  OUT=$(eval echo \$OUT$i)
  EXP=$(eval echo \$EXP$i)

  for algo in sd ds lar; do
    test $EXP = $(ltlsynt -f "$F" --ins="$IN" --outs="$OUT" --realizability \
    --algo=$algo)
  done
done

for i in 2 3 4 5 6 10; do
  F=$(eval echo \$F$i)
  IN=$(eval echo \$IN$i)
  OUT=$(eval echo \$OUT$i)
  EXP=$(eval echo \$EXP$i)

  ltl2tgba -f "!($F)" > negf_aut$i

  # test ltlsynt
  for algo in sd ds ps lar lar.old; do
    ltlsynt -f "$F" --ins="$IN" --outs="$OUT" --algo=$algo > out$i || true
    REAL=`head -1 out$i`
    test $REAL = $EXP
    tail -n +2 out$i > res$i
    # check that the L(strategy) is included in L(F)
    autfilt -q -v --intersect=negf_aut$i res$i
    # check that all environment actions are possible
    autfilt --remove-ap="$OUT" res$i | autfilt --dualize | autfilt --is-empty -q
  done
done

cat >exp <<EOF
REALIZABLE
HOA: v1
States: 3
Start: 0
AP: 1 "p0"
acc-name: all
Acceptance: 0 t
properties: trans-labels explicit-labels state-acc deterministic
--BODY--
State: 0
[t] 1
State: 1
[t] 2
State: 2
[!0] 2
--END--
EOF
ltlsynt --outs=p0 -x tls-impl=0 -f '!XXF(p0 & (p0 M Gp0))' > out
diff out exp

cat >exp <<EOF
REALIZABLE
HOA: v1
States: 1
Start: 0
AP: 1 "p0"
acc-name: all
Acceptance: 0 t
properties: trans-labels explicit-labels state-acc deterministic
--BODY--
State: 0
[!0] 0
--END--
EOF
ltlsynt --outs=p0 -x tls-impl=1 -f '!XXF(p0 & (p0 M Gp0))' > out
diff out exp

ltlsynt --outs=p0 -f '!XXF(p0 & (p0 M Gp0))' > out
diff out exp

f='Fp0 U XX((p0 & F!p1) | (!p0 & Gp1))'
ltlsynt --verbose --algo=ps --outs=p1 --ins=p0 -f "$f" 2>err
grep 'DPA has 14 states' err
ltlsynt --verbose -x wdba-minimize=1 --algo=ps --outs=p1 --ins=p0 -f "$f" 2>err
grep 'DPA has 12 states' err
