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.

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