import sys | |
import os | |
import re | |
import subprocess | |
import _paths | |
def handle_options(): | |
"""Returns options values as map.""" | |
from xsap.utils.options import ( | |
MC_ENGINE_BDD, | |
MC_ENGINE_BMC, | |
MC_ENGINE_MSAT_BMC, | |
MC_ENGINE_IC3) | |
import argparse | |
parser = argparse.ArgumentParser(description="") | |
parser.add_argument("--engine", "-E", | |
dest="engine", | |
choices=[MC_ENGINE_BDD, MC_ENGINE_BMC, MC_ENGINE_MSAT_BMC, MC_ENGINE_IC3], | |
default=MC_ENGINE_IC3, | |
help="Use given engine (default: %(default)s)") | |
parser.add_argument("--bmc-length", "-k", | |
dest="bmc_len", | |
action="store", | |
type=int, | |
default=10, | |
help="Maximum path length for BMC") | |
parser.add_argument("--smv-file", "-m", | |
dest="smv", | |
action="store", | |
default=None, | |
help="SMV file") | |
parser.add_argument("--diagnosis-condition", "-c", | |
dest="diag_cond", | |
action="store", | |
default=None, | |
help="Diagnosis condition") | |
parser.add_argument("--alarm-pattern", "-a", | |
dest="alarm_pattern", | |
choices=['exact', 'bounded', 'finite'], | |
default=None, | |
help="Alarm pattern (default: %(default)s)") | |
parser.add_argument("--delay-bound", "-d", | |
dest="delay_bound", | |
action="store", | |
type=int, | |
default=None, | |
help="Alarm pattern delay bound") | |
parser.add_argument("--context-expression", "-x", | |
dest="ltl_context", | |
action="store", | |
default=None, | |
help="LTL context expression") | |
parser.add_argument("--observables-file", "-o", | |
dest="obs_file", | |
action="store", | |
default=None, | |
help="File specifying observable variables") | |
parser.add_argument("--asl-file", "-f", | |
dest="asl_file", | |
action="store", | |
default=None, | |
help="File containing the alarms specification") | |
parser.add_argument("--verbosity-level", "-v", | |
dest="verbose_level", | |
action="store", | |
type=int, | |
default=0, | |
help="Sets the output verbosity level") | |
args = parser.parse_args() | |
# check arguments | |
if args.smv is None or not os.path.exists(args.smv): | |
parser.error("The SMV model was not specified.") | |
if args.bmc_len < 0: | |
parser.error("Illegal BMC length.") | |
if args.obs_file is None or not os.path.exists(args.obs_file): | |
parser.error("The observables file was not specified.") | |
if args.asl_file is None: | |
if args.diag_cond is None: | |
parser.error("The diagnosis condition was not specified.") | |
if args.alarm_pattern is None: | |
parser.error("The alarm pattern was not chosen.") | |
if args.alarm_pattern in ['exact', 'bounded'] and args.delay_bound is None: | |
parser.error("For the chosen alarm pattern a delay bound needs to be specified.") | |
if args.alarm_pattern in ['finite'] and args.delay_bound is not None: | |
parser.error("A delay bound cannot be specified for finite-delay.") | |
if args.delay_bound is not None and int(args.delay_bound) < 0: | |
parser.error("Illegal delay bound.") | |
else: | |
if not os.path.exists(args.asl_file): | |
parser.error("The ASL file does not exist") | |
if args.diag_cond is not None: | |
parser.error("Cannot specify both a diagnosis condition and an ASL file") | |
return args | |
if __name__ == "__main__": | |
_paths.setup_path() | |
# setup logging | |
import xsap.utils.misc.log | |
xsap.utils.misc.log.init() | |
args = handle_options() | |
from xsap.utils.options import MC_ENGINE_MSAT_BMC | |
from xsap.utils.processes.xsap_process import XsapProcess | |
need_msat = XsapProcess.has_infinite_domain_vars(args.smv) or MC_ENGINE_MSAT_BMC == args.engine | |
xsap_process = XsapProcess(args.smv, fail_obs_alm_fname=None, | |
ord_fname=None, need_msat=need_msat, | |
args=["-v", "%d" % args.verbose_level], stdout=subprocess.PIPE, | |
stderr=subprocess.STDOUT, | |
dumpers=[]) | |
delay_bound = -1 if args.delay_bound is None else int(args.delay_bound) | |
results = xsap_process.check_diagnosability_ASL(args.diag_cond, | |
args.alarm_pattern, delay_bound, args.ltl_context, args.obs_file, | |
args.engine, args.bmc_len, args.asl_file) | |
xsap_process.kill_and_close_streams() | |
for i, (res, traceA, traceB) in enumerate(results): | |
if len(results) > 1: | |
print("Specification %d" % i) | |
if "Error" == res: | |
print "--------------------------------------------------" | |
print "Result: An error has occurred during the analysis." | |
print "--------------------------------------------------" | |
elif "Unknown" == res: | |
print "------------------------------------------------------" | |
print "Result: No counterexample found within analysis bound." | |
print "------------------------------------------------------" | |
elif "True" == res: | |
print "-------------------------------------------------------" | |
print "Result: The specification is diagnosable in the system." | |
print "-------------------------------------------------------" | |
elif "False" == res: | |
print "--------------------------------------------------------------------------------" | |
print "Result: The specification is not diagnosable in the system. A pair of traces has" | |
print "been generated that show non-diagnosability:" | |
print "Trace A:", traceA | |
print "Trace B:", traceB | |
print "--------------------------------------------------------------------------------" | |
else: | |
assert False, "BUG: unexpected result of diagnosability verification." |