-
Notifications
You must be signed in to change notification settings - Fork 1
/
compute_lyapunov.py
100 lines (76 loc) · 3.22 KB
/
compute_lyapunov.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
93
94
95
96
97
98
99
100
import sys
import argparse
import logging
from fractions import Fraction
from pysmt.shortcuts import Symbol, REAL, get_env
from sabbath.system import DynSystem
from sabbath.lyapunov.lyapunov import synth_lyapunov, validate_lyapunov
from sabbath.lzz.serialization import importInvar
def main():
# x1,x2,x3,x4 = sp.symbols('x1 x2 x3 x4')
# vars_list = [x1,x2,x3,x4]
# vector_field = {
# x1 : -x1 + x2**3 - 3*x3*x4,
# x2 : -x1 - x2**3,
# x3 : x1 * x4 - x3,
# x4 : x1 * x3 - x4**4
# }
# feasible, lyap = test_lyapunov(factory, vector_field, vars_list, 4)
# print(feasible, lyap)
parser = argparse.ArgumentParser()
parser.add_argument("problem",help="File containing the verification problem")
parser.add_argument("--synth_algorithm",
choices=["sos","smt","quantifier_elimination"],
default="sos",
help="Technique used to synthesise the Lyapunov function.")
parser.add_argument("--validate",
dest="validate", action='store_true',
help="Validate the lyapunov function")
# parser.add_argument("--smt-synth",
# choices=["z3","mathsat","cvc5"],
# default="z3",
# help="SMT solver to use for synthesis (still not implemented)")
# parser.add_argument("--smt-validation",
# choices=["z3","mathsat","cvc5"],
# default="z3",
# help="SMT solver to use for validation (still not implemented)")
args = parser.parse_args()
logging.basicConfig(level=logging.DEBUG)
env = get_env()
with open(args.problem, "r") as json_stream:
problem_list = importInvar(json_stream, env)
assert(len(problem_list) == 1)
for p in problem_list:
(problem_name, init, safe, sys, invariants, predicates) = p
break
(mathematica, smt) = {
"sos" : (False,False),
"smt" : (False,True),
"quantifier_elimination" : (True,False),
}[args.synth_algorithm]
# Pre-processing
assert (sys.is_linear)
rescaled_systems = sys.get_rescaled_by_equilibrium_point()
if len(rescaled_systems) != 1:
print("Found multiple equilibrium point")
for rescaled in rescaled_systems:
print("Start synthesis using ", args.synth_algorithm)
(res, lyapunov) = synth_lyapunov(rescaled, 2, mathematica, smt)
if (res is None):
print("Unknown!")
elif (res):
print("Found a Lyapunov function: ", lyapunov.serialize())
if (args.validate):
if (mathematica or smt):
print("Skipping validation (correct by construction)")
else:
print ("Validating the Lyapunov function...")
is_valid = validate_lyapunov(rescaled, lyapunov)
print("Is valid: ", is_valid)
else:
if (not (mathematica or smt)):
print("WARNING: The Lyapunov function was obtained with numeric (unsound) methods")
else:
print("Cannot find a Lyapunov function")
if __name__ == "__main__":
main()