22
33import logging
44import sys
5+ import time
56from dataclasses import dataclass
67from enum import Enum
78
9+ import click
10+
811from .__about__ import __date__ , __summary__ , __version__
912
1013log = logging .getLogger ('backend' )
1316class Args (Enum ):
1417 BACKEND = "backend"
1518 BV = "bv"
19+ CONCRETIZATION = "concretization"
1620 CORES = "cores"
21+ CORES_FROM = "from"
22+ CORES_TO = "to"
1723 DEBUG = "debug"
1824 FAIR = "fair"
19- CORES_FROM = "from"
20- KEEP_FILES = "keep_files"
2125 INCLUDE = "include"
22- PROPERTY = "property"
23- CONCRETIZATION = "concretization"
26+ KEEP_FILES = "keep_files"
2427 NO_PROPERTIES = "no_properties"
28+ PROPERTY = "property"
29+ RND_SEED = "rnd_seed"
2530 SHOW = "show"
2631 SIMULATE = "simulate"
2732 STEPS = "steps"
2833 SYNC = "sync"
2934 TIMEOUT = "timeout"
3035 TRANSLATE_CEX = "translate_cex"
31- CORES_TO = "to"
3236 VALUES = "values"
3337 VERBOSE = "verbose"
3438
@@ -43,53 +47,37 @@ class Args(Enum):
4347
4448HELPMSG = {
4549 Args .BACKEND : "Backend to use in verification mode." ,
46-
4750 Args .BV : "Enable bitvector optimization where supported." ,
48-
4951 Args .CONCRETIZATION : "Type of concretization (only for simulation)." ,
50-
52+ Args .CORES_FROM : "Parallel analysis: partition start." ,
53+ Args .CORES_TO : "Parallel analysis: partition end." ,
5154 Args .CORES : "Number of CPU cores for parallel analysis." ,
52-
5355 Args .DEBUG : "Enable additional checks in the backend." ,
54-
5556 Args .FAIR : "Enforce fair interleaving of components." ,
56-
57- Args .CORES_FROM : "Parallel analysis: partition start." ,
58-
59- Args .KEEP_FILES : "Do not remove intermediate files." ,
60-
6157 Args .INCLUDE : (
6258 "Add custom code to generated program "
6359 "(may be specified multiple times)." ),
64-
65- Args .PROPERTY : "Property to consider, others will be ignored." ,
66-
60+ Args .KEEP_FILES : "Do not remove intermediate files." ,
6761 Args .NO_PROPERTIES : "Ignore all properties." ,
68-
62+ Args .PROPERTY : "Property to consider, others will be ignored." ,
63+ Args .RND_SEED : (
64+ "Seed for the random number generator."
65+ "If none is given, the current time will be used." ),
6966 Args .SHOW : "Print emulation program and exit." ,
70-
7167 Args .SIMULATE : (
7268 "Number of simulation traces to generate. "
7369 "If 0, run in verification mode." ),
74-
7570 Args .STEPS : (
7671 "Number of system evolutions. "
7772 "If 0, generate an unbounded system." ),
78-
7973 Args .SYNC : "Force synchronous stigmergy messages." ,
80-
8174 Args .TIMEOUT : (
8275 "Configure time limit (seconds). "
8376 "Set to 0 to disable timeout." ),
84-
8577 Args .TRANSLATE_CEX : (
8678 "Translate given counterexample to LAbS and exit."
8779 ),
88-
89- Args .CORES_TO : "Parallel analysis: partition end." ,
90-
9180 Args .VALUES : "assign values for parameterised specification (key=value)" ,
92-
9381 Args .VERBOSE : "Print additional messages from the backend."
9482}
9583
@@ -100,31 +88,51 @@ class Args(Enum):
10088 Args .CORES : 1 ,
10189 Args .DEBUG : False ,
10290 Args .FAIR : False ,
103- Args .CORES_FROM : None ,
10491 Args .INCLUDE : tuple (),
10592 Args .KEEP_FILES : False ,
106- Args .PROPERTY : None ,
10793 Args .NO_PROPERTIES : False ,
10894 Args .SHOW : False ,
10995 Args .SIMULATE : 0 ,
11096 Args .STEPS : 0 ,
11197 Args .SYNC : False ,
11298 Args .TIMEOUT : 0 ,
113- Args .TRANSLATE_CEX : None ,
114- Args .CORES_TO : None ,
11599 Args .VALUES : tuple (),
116100 Args .VERBOSE : False
117101}
118102
119103
104+ __existing = click .Path (exists = True )
105+ __nonnegative = click .IntRange (min = 0 )
106+
107+ TYPES = {
108+ Args .CONCRETIZATION : click .Choice (("src" , "sat" , "none" )),
109+ Args .CORES_FROM : __nonnegative ,
110+ Args .CORES_TO : __nonnegative ,
111+ Args .CORES : __nonnegative ,
112+ Args .INCLUDE : __existing ,
113+ Args .RND_SEED : click .IntRange (min = 1 ),
114+ Args .SIMULATE : __nonnegative ,
115+ Args .STEPS : __nonnegative ,
116+ Args .TIMEOUT : __nonnegative ,
117+ Args .TRANSLATE_CEX : __existing
118+ }
119+
120+
120121def CLICK (name , ** kwargs ):
121- return {
122- "help" : HELPMSG [name ],
122+ result = {
123123 "show_default" : name in DEFAULTS ,
124- ** ({} if DEFAULTS [name ] is None else {"default" : DEFAULTS [name ]}),
125124 ** kwargs
126125 }
127126
127+ def maybe_add_from (some_dict , kwarg ):
128+ if name in some_dict :
129+ result [kwarg ] = some_dict [name ]
130+
131+ maybe_add_from (HELPMSG , "help" )
132+ maybe_add_from (DEFAULTS , "default" )
133+ maybe_add_from (TYPES , "type" )
134+ return result
135+
128136
129137class CliArgs (dict ):
130138 def __init__ (self , file , __dict ) -> None :
@@ -136,14 +144,18 @@ def __init__(self, file, __dict) -> None:
136144 self .externs [k ] = int (v )
137145
138146 def __getitem__ (self , key : Args ):
139- return self .get (key .value , DEFAULTS [ key ] )
147+ return self .get (key .value , DEFAULTS . get ( key ) )
140148
141149 def __setitem__ (self , key : Args , value ):
142150 if isinstance (key , Args ):
143151 self [key .value ] = value
144152 else :
145153 super ().__setitem__ (key , value )
146154
155+ def get_seed (self ) -> int :
156+ seed = self [Args .RND_SEED ]
157+ return time .time_ns () % (1 << 32 ) if seed is None else seed
158+
147159
148160class ExitStatus (Enum ):
149161 SUCCESS = 0
0 commit comments