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.

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