MODEL = """ ------------------------------------------------------------------------ -- Generated using Kripkomat ------------------------------------------------------------------------ MODULE {name} VAR state : {{ {states} }}; ASSIGN init(state) := {initial}; next(state) := case {transitions} esac; DEFINE {properties} """ TRAN = " state = {n} : {{{ms}}};" PROP = """ -- Property "{prop}" {alias} := {logic}; """ PROP_LOGIC = "state = {state}" LTL_FORM = """LTLSPEC {ltl}; """ A_UPPERCASE = ord('a') ALPHABET_SIZE = 26 def _decompose(number): """Generate digits from `number` in base alphabet, least significants bits first. Since A is 1 rather than 0 in base alphabet, we are dealing with `number - 1` at each iteration to be able to extract the proper digits. """ while number: number, remainder = divmod(number - 1, ALPHABET_SIZE) yield remainder def base_10_to_alphabet(number): """Convert a decimal number to its base alphabet representation""" return ''.join( chr(A_UPPERCASE + part) for part in _decompose(number) )[::-1] class ModelBuilder: def __init__(self, states, initial, transitions, properties, ltls=[], name="main"): self._name = name self._states = states self._initial = initial self._tran = transitions self._props = properties self._ltls = ltls self._propalias = {} for no,prop in enumerate(properties.keys()): self._propalias[prop] = base_10_to_alphabet(no + 1) def generate(self): # build model states_decl = ",".join(self._states) transitions = [] for n,ms in self._tran.items(): transition = TRAN.format(n=n, ms=",".join(ms)) transitions.append(transition) properties = [] for prop,states in self._props.items(): alias = self._propalias[prop] logic = " | ".join([PROP_LOGIC.format(state=x) for x in states]) prop_str = PROP.format(prop=prop, alias=alias, logic=logic) properties.append(prop_str) out = MODEL.format(name=self._name, states=states_decl, initial=self._initial, transitions="\n".join(transitions), properties="\n".join(properties)) # add LTL formulas for ltl in self._ltls: out += LTL_FORM.format(ltl=ltl) return out