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.

220 lines
8.5 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 build_model(symbolic_description, properties=None):
  20. """
  21. Build a model from a symbolic description.
  22. :param symbolic_description: Symbolic model description to translate into a model.
  23. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  24. :return: Model in sparse representation.
  25. :rtype: SparseDtmc or SparseMdp
  26. """
  27. if not symbolic_description.undefined_constants_are_graph_preserving:
  28. raise StormError("Program still contains undefined constants")
  29. if properties:
  30. formulae = [prop.raw_formula for prop in properties]
  31. intermediate = core._build_sparse_model_from_prism_program(symbolic_description, formulae)
  32. else:
  33. intermediate = core._build_sparse_model_from_prism_program(symbolic_description)
  34. assert not intermediate.supports_parameters
  35. if intermediate.model_type == ModelType.DTMC:
  36. return intermediate._as_dtmc()
  37. elif intermediate.model_type == ModelType.MDP:
  38. return intermediate._as_mdp()
  39. elif intermediate.model_type == ModelType.CTMC:
  40. return intermediate._as_ctmc()
  41. elif intermediate.model_type == ModelType.MA:
  42. return intermediate._as_ma()
  43. else:
  44. raise StormError("Not supported non-parametric model constructed")
  45. def build_parametric_model(symbolic_description, properties=None):
  46. """
  47. Build a parametric model from a symbolic description.
  48. :param symbolic_description: Symbolic model description to translate into a model.
  49. :param List[Property] properties: List of properties that should be preserved during the translation. If None, then all properties are preserved.
  50. :return: Parametric model in sparse representation.
  51. :rtype: SparseParametricDtmc or SparseParametricMdp
  52. """
  53. if not symbolic_description.undefined_constants_are_graph_preserving:
  54. raise StormError("Program still contains undefined constants")
  55. if properties:
  56. formulae = [prop.raw_formula for prop in properties]
  57. else:
  58. formulae = []
  59. intermediate = core._build_sparse_parametric_model_from_prism_program(symbolic_description, formulae)
  60. assert intermediate.supports_parameters
  61. if intermediate.model_type == ModelType.DTMC:
  62. return intermediate._as_pdtmc()
  63. elif intermediate.model_type == ModelType.MDP:
  64. return intermediate._as_pmdp()
  65. elif intermediate.model_type == ModelType.CTMC:
  66. return intermediate._as_pctmc()
  67. elif intermediate.model_type == ModelType.MA:
  68. return intermediate._as_pma()
  69. else:
  70. raise StormError("Not supported parametric model constructed")
  71. def build_model_from_drn(file):
  72. """
  73. Build a model from the explicit DRN representation.
  74. :param String file: DRN file containing the model.
  75. :return: Model in sparse representation.
  76. :rtype: SparseDtmc or SparseMdp or SparseCTMC or SparseMA
  77. """
  78. intermediate = core._build_sparse_model_from_drn(file)
  79. assert not intermediate.supports_parameters
  80. if intermediate.model_type == ModelType.DTMC:
  81. return intermediate._as_dtmc()
  82. elif intermediate.model_type == ModelType.MDP:
  83. return intermediate._as_mdp()
  84. elif intermediate.model_type == ModelType.CTMC:
  85. return intermediate._as_ctmc()
  86. elif intermediate.model_type == ModelType.MA:
  87. return intermediate._as_ma()
  88. else:
  89. raise StormError("Not supported non-parametric model constructed")
  90. def build_parametric_model_from_drn(file):
  91. """
  92. Build a parametric model from the explicit DRN representation.
  93. :param String file: DRN file containing the model.
  94. :return: Parametric model in sparse representation.
  95. :rtype: SparseParametricDtmc or SparseParametricMdp or SparseParametricCTMC or SparseParametricMA
  96. """
  97. intermediate = core._build_sparse_parametric_model_from_drn(file)
  98. assert intermediate.supports_parameters
  99. if intermediate.model_type == ModelType.DTMC:
  100. return intermediate._as_pdtmc()
  101. elif intermediate.model_type == ModelType.MDP:
  102. return intermediate._as_pmdp()
  103. elif intermediate.model_type == ModelType.CTMC:
  104. return intermediate._as_pctmc()
  105. elif intermediate.model_type == ModelType.MA:
  106. return intermediate._as_pma()
  107. else:
  108. raise StormError("Not supported parametric model constructed")
  109. def perform_bisimulation(model, properties, bisimulation_type):
  110. """
  111. Perform bisimulation on model.
  112. :param model: Model.
  113. :param properties: Properties to preserve during bisimulation.
  114. :param bisimulation_type: Type of bisimulation (weak or strong).
  115. :return: Model after bisimulation.
  116. """
  117. formulae = [prop.raw_formula for prop in properties]
  118. if model.supports_parameters:
  119. return core._perform_parametric_bisimulation(model, formulae, bisimulation_type)
  120. else:
  121. return core._perform_bisimulation(model, formulae, bisimulation_type)
  122. def model_checking(model, property, only_initial_states=False, extract_scheduler=False):
  123. """
  124. Perform model checking on model for property.
  125. :param model: Model.
  126. :param property: Property to check for.
  127. :param only_initial_states: If True, only results for initial states are computed, otherwise for all states.
  128. :param extract_scheduler: If True, try to extract a scheduler
  129. :return: Model checking result.
  130. :rtype: CheckResult
  131. """
  132. if isinstance(property, Property):
  133. formula = property.raw_formula
  134. else:
  135. formula = property
  136. if model.supports_parameters:
  137. task = core.ParametricCheckTask(formula, only_initial_states)
  138. task.set_produce_schedulers(extract_scheduler)
  139. return core._parametric_model_checking_sparse_engine(model, task)
  140. else:
  141. task = core.CheckTask(formula, only_initial_states)
  142. task.set_produce_schedulers(extract_scheduler)
  143. return core._model_checking_sparse_engine(model, task)
  144. def prob01min_states(model, eventually_formula):
  145. assert type(eventually_formula) == logic.EventuallyFormula
  146. labelform = eventually_formula.subformula
  147. labelprop = core.Property("label-prop", labelform)
  148. phiStates = BitVector(model.nr_states, True)
  149. psiStates = model_checking(model, labelprop).get_truth_values()
  150. return compute_prob01min_states(model, phiStates, psiStates)
  151. def prob01max_states(model, eventually_formula):
  152. assert type(eventually_formula) == logic.EventuallyFormula
  153. labelform = eventually_formula.subformula
  154. labelprop = core.Property("label-prop", labelform)
  155. phiStates = BitVector(model.nr_states, True)
  156. psiStates = model_checking(model, labelprop).get_truth_values()
  157. return compute_prob01min_states(model, phiStates, psiStates)
  158. def compute_prob01_states(model, phi_states, psi_states):
  159. """
  160. Compute prob01 states for properties of the form phi_states until psi_states
  161. :param SparseDTMC model:
  162. :param BitVector phi_states:
  163. :param BitVector psi_states: Target states
  164. """
  165. if model.model_type != ModelType.DTMC:
  166. raise StormError("Prob 01 is only defined for DTMCs -- model must be a DTMC")
  167. if model.supports_parameters:
  168. return core._compute_prob01states_rationalfunc(model, phi_states, psi_states)
  169. else:
  170. return core._compute_prob01states_double(model, phi_states, psi_states)
  171. def compute_prob01min_states(model, phi_states, psi_states):
  172. if model.model_type == ModelType.DTMC:
  173. return compute_prob01_states(model, phi_states, psi_states)
  174. if model.supports_parameters:
  175. return core._compute_prob01states_min_rationalfunc(model, phi_states, psi_states)
  176. else:
  177. return core._compute_prob01states_min_double(model, phi_states, psi_states)
  178. def compute_prob01max_states(model, phi_states, psi_states):
  179. if model.model_type == ModelType.DTMC:
  180. return compute_prob01_states(model, phi_states, psi_states)
  181. if model.supports_parameters:
  182. return core._compute_prob01states_max_rationalfunc(model, phi_states, psi_states)
  183. else:
  184. return core._compute_prob01states_max_double(model, phi_states, psi_states)