You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
16 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. import sys
  2. if sys.version_info[0] == 2:
  3. raise ImportError('Python 2.x is not supported for stormpy.')
  4. from . import core
  5. from .core import *
  6. from . import storage
  7. from .storage import *
  8. from ._config import *
  9. from .logic import *
  10. from .exceptions import *
  11. from pycarl import Variable # needed for building parametric models
  12. __version__ = "unknown"
  13. try:
  14. from _version import __version__
  15. except ImportError:
  16. # We're running in a tree that doesn't have a _version.py, so we don't know what our version is.
  17. pass
  18. core._set_up("")
  19. def _convert_sparse_model(model, parametric=False):
  20. """
  21. Convert (parametric) model in sparse representation into model corresponding to exact model type.
  22. :param model: Sparse model.
  23. :param parametric: Flag indicating if the model is parametric.
  24. :return: Model corresponding to exact model type.
  25. """
  26. if parametric:
  27. assert model.supports_parameters
  28. if model.model_type == ModelType.DTMC:
  29. return model._as_sparse_pdtmc()
  30. elif model.model_type == ModelType.MDP:
  31. return model._as_sparse_pmdp()
  32. elif model.model_type == ModelType.CTMC:
  33. return model._as_sparse_pctmc()
  34. elif model.model_type == ModelType.MA:
  35. return model._as_sparse_pma()
  36. else:
  37. raise StormError("Not supported parametric model constructed")
  38. else:
  39. assert not model.supports_parameters
  40. if model.model_type == ModelType.DTMC:
  41. return model._as_sparse_dtmc()
  42. elif model.model_type == ModelType.MDP:
  43. return model._as_sparse_mdp()
  44. elif model.model_type == ModelType.CTMC:
  45. return model._as_sparse_ctmc()
  46. elif model.model_type == ModelType.MA:
  47. return model._as_sparse_ma()
  48. else:
  49. raise StormError("Not supported non-parametric model constructed")
  50. def _convert_symbolic_model(model, parametric=False):
  51. """
  52. Convert (parametric) model in symbolic representation into model corresponding to exact model type.
  53. :param model: Symbolic model.
  54. :param parametric: Flag indicating if the model is parametric.
  55. :return: Model corresponding to exact model type.
  56. """
  57. if parametric:
  58. assert model.supports_parameters
  59. if model.model_type == ModelType.DTMC:
  60. return model._as_symbolic_pdtmc()
  61. elif model.model_type == ModelType.MDP:
  62. return model._as_symbolic_pmdp()
  63. elif model.model_type == ModelType.CTMC:
  64. return model._as_symbolic_pctmc()
  65. elif model.model_type == ModelType.MA:
  66. return model._as_symbolic_pma()
  67. else:
  68. raise StormError("Not supported parametric model constructed")
  69. else:
  70. assert not model.supports_parameters
  71. if model.model_type == ModelType.DTMC:
  72. return model._as_symbolic_dtmc()
  73. elif model.model_type == ModelType.MDP:
  74. return model._as_symbolic_mdp()
  75. elif model.model_type == ModelType.CTMC:
  76. return model._as_symbolic_ctmc()
  77. elif model.model_type == ModelType.MA:
  78. return model._as_symbolic_ma()
  79. else:
  80. raise StormError("Not supported non-parametric model constructed")
  81. def build_model(symbolic_description, properties=None):
  82. """
  83. Build a model in sparse representation from a symbolic description.
  84. :param symbolic_description: Symbolic model description to translate into a model.
  85. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  86. :return: Model in sparse representation.
  87. """
  88. return build_sparse_model(symbolic_description, properties=properties)
  89. def build_parametric_model(symbolic_description, properties=None):
  90. """
  91. Build a parametric model in sparse representation from a symbolic description.
  92. :param symbolic_description: Symbolic model description to translate into a model.
  93. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  94. :return: Parametric model in sparse representation.
  95. """
  96. return build_sparse_parametric_model(symbolic_description, properties=properties)
  97. def build_sparse_model(symbolic_description, properties=None):
  98. """
  99. Build a model in sparse representation from a symbolic description.
  100. :param symbolic_description: Symbolic model description to translate into a model.
  101. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  102. :return: Model in sparse representation.
  103. """
  104. if not symbolic_description.undefined_constants_are_graph_preserving:
  105. raise StormError("Program still contains undefined constants")
  106. if properties:
  107. formulae = [prop.raw_formula for prop in properties]
  108. intermediate = core._build_sparse_model_from_symbolic_description(symbolic_description, formulae)
  109. else:
  110. intermediate = core._build_sparse_model_from_symbolic_description(symbolic_description)
  111. return _convert_sparse_model(intermediate, parametric=False)
  112. def build_sparse_parametric_model(symbolic_description, properties=None):
  113. """
  114. Build a parametric model in sparse representation from a symbolic description.
  115. :param symbolic_description: Symbolic model description to translate into a model.
  116. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  117. :return: Parametric model in sparse representation.
  118. """
  119. if not symbolic_description.undefined_constants_are_graph_preserving:
  120. raise StormError("Program still contains undefined constants")
  121. if properties:
  122. formulae = [prop.raw_formula for prop in properties]
  123. intermediate = core._build_sparse_parametric_model_from_symbolic_description(symbolic_description, formulae)
  124. else:
  125. intermediate = core._build_sparse_parametric_model_from_symbolic_description(symbolic_description)
  126. return _convert_sparse_model(intermediate, parametric=True)
  127. def build_symbolic_model(symbolic_description, properties=None):
  128. """
  129. Build a model in symbolic representation from a symbolic description.
  130. :param symbolic_description: Symbolic model description to translate into a model.
  131. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  132. :return: Model in symbolic representation.
  133. """
  134. if not symbolic_description.undefined_constants_are_graph_preserving:
  135. raise StormError("Program still contains undefined constants")
  136. if properties:
  137. formulae = [prop.raw_formula for prop in properties]
  138. intermediate = core._build_symbolic_model_from_symbolic_description(symbolic_description, formulae)
  139. else:
  140. intermediate = core._build_symbolic_model_from_symbolic_description(symbolic_description)
  141. return _convert_symbolic_model(intermediate, parametric=False)
  142. def build_symbolic_parametric_model(symbolic_description, properties=None):
  143. """
  144. Build a parametric model in symbolic representation from a symbolic description.
  145. :param symbolic_description: Symbolic model description to translate into a model.
  146. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  147. :return: Parametric model in symbolic representation.
  148. """
  149. if not symbolic_description.undefined_constants_are_graph_preserving:
  150. raise StormError("Program still contains undefined constants")
  151. if properties:
  152. formulae = [prop.raw_formula for prop in properties]
  153. intermediate = core._build_symbolic_parametric_model_from_symbolic_description(symbolic_description, formulae)
  154. else:
  155. intermediate = core._build_symbolic_parametric_model_from_symbolic_description(symbolic_description)
  156. return _convert_symbolic_model(intermediate, parametric=True)
  157. def build_model_from_drn(file):
  158. """
  159. Build a model in sparse representation from the explicit DRN representation.
  160. :param String file: DRN file containing the model.
  161. :return: Model in sparse representation.
  162. """
  163. intermediate = core._build_sparse_model_from_drn(file)
  164. return _convert_sparse_model(intermediate, parametric=False)
  165. def build_parametric_model_from_drn(file):
  166. """
  167. Build a parametric model in sparse representation from the explicit DRN representation.
  168. :param String file: DRN file containing the model.
  169. :return: Parametric model in sparse representation.
  170. """
  171. intermediate = core._build_sparse_parametric_model_from_drn(file)
  172. return _convert_sparse_model(intermediate, parametric=True)
  173. def perform_bisimulation(model, properties, bisimulation_type):
  174. """
  175. Perform bisimulation on model.
  176. :param model: Model.
  177. :param properties: Properties to preserve during bisimulation.
  178. :param bisimulation_type: Type of bisimulation (weak or strong).
  179. :return: Model after bisimulation.
  180. """
  181. return perform_sparse_bisimulation(model, properties, bisimulation_type)
  182. def perform_sparse_bisimulation(model, properties, bisimulation_type):
  183. """
  184. Perform bisimulation on model in sparse representation.
  185. :param model: Model.
  186. :param properties: Properties to preserve during bisimulation.
  187. :param bisimulation_type: Type of bisimulation (weak or strong).
  188. :return: Model after bisimulation.
  189. """
  190. formulae = [prop.raw_formula for prop in properties]
  191. if model.supports_parameters:
  192. return core._perform_parametric_bisimulation(model, formulae, bisimulation_type)
  193. else:
  194. return core._perform_bisimulation(model, formulae, bisimulation_type)
  195. def perform_symbolic_bisimulation(model, properties):
  196. """
  197. Perform bisimulation on model in symbolic representation.
  198. :param model: Model.
  199. :param properties: Properties to preserve during bisimulation.
  200. :return: Model after bisimulation.
  201. """
  202. formulae = [prop.raw_formula for prop in properties]
  203. bisimulation_type = BisimulationType.STRONG
  204. if model.supports_parameters:
  205. return core._perform_symbolic_parametric_bisimulation(model, formulae, bisimulation_type)
  206. else:
  207. return core._perform_symbolic_bisimulation(model, formulae, bisimulation_type)
  208. def model_checking(model, property, only_initial_states=False, extract_scheduler=False):
  209. """
  210. Perform model checking on model for property.
  211. :param model: Model.
  212. :param property: Property to check for.
  213. :param only_initial_states: If True, only results for initial states are computed, otherwise for all states.
  214. :param extract_scheduler: If True, try to extract a scheduler
  215. :return: Model checking result.
  216. :rtype: CheckResult
  217. """
  218. return check_model_sparse(model, property, only_initial_states=only_initial_states,
  219. extract_scheduler=extract_scheduler)
  220. def check_model_sparse(model, property, only_initial_states=False, extract_scheduler=False):
  221. """
  222. Perform model checking on model for property.
  223. :param model: Model.
  224. :param property: Property to check for.
  225. :param only_initial_states: If True, only results for initial states are computed, otherwise for all states.
  226. :param extract_scheduler: If True, try to extract a scheduler
  227. :return: Model checking result.
  228. :rtype: CheckResult
  229. """
  230. if isinstance(property, Property):
  231. formula = property.raw_formula
  232. else:
  233. formula = property
  234. if model.supports_parameters:
  235. task = core.ParametricCheckTask(formula, only_initial_states)
  236. task.set_produce_schedulers(extract_scheduler)
  237. return core._parametric_model_checking_sparse_engine(model, task)
  238. else:
  239. task = core.CheckTask(formula, only_initial_states)
  240. task.set_produce_schedulers(extract_scheduler)
  241. return core._model_checking_sparse_engine(model, task)
  242. def check_model_dd(model, property, only_initial_states=False):
  243. """
  244. Perform model checking using dd engine.
  245. :param model: Model.
  246. :param property: Property to check for.
  247. :param only_initial_states: If True, only results for initial states are computed, otherwise for all states.
  248. :return: Model checking result.
  249. :rtype: CheckResult
  250. """
  251. if isinstance(property, Property):
  252. formula = property.raw_formula
  253. else:
  254. formula = property
  255. if model.supports_parameters:
  256. task = core.ParametricCheckTask(formula, only_initial_states)
  257. return core._parametric_model_checking_dd_engine(model, task)
  258. else:
  259. task = core.CheckTask(formula, only_initial_states)
  260. return core._model_checking_dd_engine(model, task)
  261. def check_model_hybrid(model, property, only_initial_states=False):
  262. """
  263. Perform model checking using hybrid engine.
  264. :param model: Model.
  265. :param property: Property to check for.
  266. :param only_initial_states: If True, only results for initial states are computed, otherwise for all states.
  267. :return: Model checking result.
  268. :rtype: CheckResult
  269. """
  270. if isinstance(property, Property):
  271. formula = property.raw_formula
  272. else:
  273. formula = property
  274. if model.supports_parameters:
  275. task = core.ParametricCheckTask(formula, only_initial_states)
  276. return core._parametric_model_checking_hybrid_engine(model, task)
  277. else:
  278. task = core.CheckTask(formula, only_initial_states)
  279. return core._model_checking_hybrid_engine(model, task)
  280. def transform_to_sparse_model(model):
  281. """
  282. Transform model in symbolic representation into model in sparse representation.
  283. :param model: Symbolic model.
  284. :return: Sparse model.
  285. """
  286. if model.supports_parameters:
  287. return core._transform_to_sparse_parametric_model(model)
  288. else:
  289. return core._transform_to_sparse_model(model)
  290. def prob01min_states(model, eventually_formula):
  291. assert type(eventually_formula) == logic.EventuallyFormula
  292. labelform = eventually_formula.subformula
  293. labelprop = core.Property("label-prop", labelform)
  294. phiStates = BitVector(model.nr_states, True)
  295. psiStates = model_checking(model, labelprop).get_truth_values()
  296. return compute_prob01min_states(model, phiStates, psiStates)
  297. def prob01max_states(model, eventually_formula):
  298. assert type(eventually_formula) == logic.EventuallyFormula
  299. labelform = eventually_formula.subformula
  300. labelprop = core.Property("label-prop", labelform)
  301. phiStates = BitVector(model.nr_states, True)
  302. psiStates = model_checking(model, labelprop).get_truth_values()
  303. return compute_prob01min_states(model, phiStates, psiStates)
  304. def compute_prob01_states(model, phi_states, psi_states):
  305. """
  306. Compute prob01 states for properties of the form phi_states until psi_states
  307. :param SparseDTMC model:
  308. :param BitVector phi_states:
  309. :param BitVector psi_states: Target states
  310. """
  311. if model.model_type != ModelType.DTMC:
  312. raise StormError("Prob 01 is only defined for DTMCs -- model must be a DTMC")
  313. if model.supports_parameters:
  314. return core._compute_prob01states_rationalfunc(model, phi_states, psi_states)
  315. else:
  316. return core._compute_prob01states_double(model, phi_states, psi_states)
  317. def compute_prob01min_states(model, phi_states, psi_states):
  318. if model.model_type == ModelType.DTMC:
  319. return compute_prob01_states(model, phi_states, psi_states)
  320. if model.supports_parameters:
  321. return core._compute_prob01states_min_rationalfunc(model, phi_states, psi_states)
  322. else:
  323. return core._compute_prob01states_min_double(model, phi_states, psi_states)
  324. def compute_prob01max_states(model, phi_states, psi_states):
  325. if model.model_type == ModelType.DTMC:
  326. return compute_prob01_states(model, phi_states, psi_states)
  327. if model.supports_parameters:
  328. return core._compute_prob01states_max_rationalfunc(model, phi_states, psi_states)
  329. else:
  330. return core._compute_prob01states_max_double(model, phi_states, psi_states)