-
Notifications
You must be signed in to change notification settings - Fork 2
/
ltl_to_aiger.py
executable file
·92 lines (66 loc) · 3.47 KB
/
ltl_to_aiger.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python3
import argparse
import logging
from typing import Iterable
from LTL_to_atm import translator_via_ltl3ba, translator_via_spot
from automata.k_reduction import k_reduce
from helpers.main_helper import setup_logging
from interfaces.LTL_to_automaton import LTLToAutomaton
from interfaces.automaton import Automaton
from interfaces.expr import Signal
from module_generation.automaton_to_verilog import atm_to_verilog
from module_generation.verilog_to_aiger_via_yosys import verilog_to_aiger
from parsing.acacia_parser_helper import parse_acacia_and_build_expr
# FIXME: rename
from parsing.tlsf_parser import convert_tlsf_or_acacia_to_acacia
def convert_spec_to_aiger(inputs:Iterable[Signal], outputs:Iterable[Signal],
ucw_automaton:Automaton,
k:int,
bad_out_name:str) -> str:
k_atm = k_reduce(ucw_automaton, k)
logging.info("k-LA automaton has %i states" % len(k_atm.nodes))
module_name = 'automaton'
verilog = atm_to_verilog(k_atm, inputs, outputs, module_name, bad_out_name)
return verilog_to_aiger(verilog)
def main():
parser = argparse.ArgumentParser(description='Translate LTL spec (TLSF or Acacia format) into AIGER via k-Live automata.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('spec', metavar='spec', type=str,
help='input spec (in Wring or TLSF format)')
parser.add_argument('--k', '-k', default=8, required=False, type=int,
help='max number of visits to a bad state (within one SCC)')
gr = parser.add_mutually_exclusive_group()
gr.add_argument('--spot', action='store_true', default=True,
dest='spot',
help='use SPOT for translating LTL->BA')
gr.add_argument('--ltl3ba', action='store_false', default=False,
dest='spot',
help='use LTL3BA for translating LTL->BA')
parser.add_argument('--mealy', action='store_true', default=False,
dest='acacia_mealy',
help='(for Acacia only) force Mealy machines')
parser.add_argument('--noopt', action='store_true', default=False,
dest='noopt',
help='Do not strengthen the specification (using the separation into safety-liveness)')
parser.add_argument('--out', '-o', required=False, type=str,
help='output AIGER file')
parser.add_argument('-v', '--verbose', action='count', default=0)
args = parser.parse_args()
setup_logging(args.verbose)
print(args)
ltl_to_automaton = (translator_via_ltl3ba.LTLToAtmViaLTL3BA,
translator_via_spot.LTLToAtmViaSpot)[args.spot]() # type: LTLToAutomaton
ltl_text, part_text, is_moore = convert_tlsf_or_acacia_to_acacia(args.spec,
not args.acacia_mealy)
spec = parse_acacia_and_build_expr(ltl_text, part_text,
ltl_to_automaton,
0 if args.noopt else 2)
ucw_automaton = ltl_to_automaton.convert(spec.formula)
aiger_str = convert_spec_to_aiger(spec.inputs, spec.outputs, ucw_automaton, args.k, 'bad')
if args.out:
with open(args.out, 'w') as f:
f.write(aiger_str)
else:
print(aiger_str)
if __name__ == '__main__':
main()