umaudemc 0.12.2__py3-none-any.whl → 0.13.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
umaudemc/__main__.py CHANGED
@@ -206,6 +206,11 @@ def build_parser():
206
206
  help='probability assignment method for adding them to the graph',
207
207
  metavar='METHOD'
208
208
  )
209
+ parser_graph.add_argument(
210
+ '-k', '--kleene-iteration',
211
+ help='write annotations on the transitions starting and terminating an iteration',
212
+ action='store_true'
213
+ )
209
214
  parser_graph.set_defaults(mode='graph')
210
215
 
211
216
  #
umaudemc/api.py CHANGED
@@ -297,7 +297,7 @@ class MaudeModel:
297
297
  wgraph = _wrappers.BoundedGraph(self.graph, depth) if depth > 0 else self.graph
298
298
 
299
299
  # Create and store the wrapped graph
300
- wgraph = _wrappers.wrapGraph(wgraph, purge, merge)
300
+ wgraph = _wrappers.wrap_graph(wgraph, purge, merge)
301
301
  self.wgraphs[(purge, merge, depth > 0)] = wgraph
302
302
 
303
303
  # In case both purge and merge are used, we keep the purged
umaudemc/backend/_spot.py CHANGED
@@ -8,7 +8,6 @@ import buddy
8
8
  import spot
9
9
 
10
10
  from ..formulae import collect_aprops
11
- from ..opsem import OpSemKleeneInstance, OpSemGraph
12
11
  from ..wrappers import create_graph
13
12
 
14
13
 
@@ -136,9 +135,10 @@ class KleeneModelBuilder(SpotModelBuilder):
136
135
  """Generator of ω-automata for strategy-controlled models with an iteration like the Kleene star"""
137
136
 
138
137
  def __init__(self, module, initial, strategy, aprops, bdd_dict, metamodule=None, opaques=()):
139
- self.instance = OpSemKleeneInstance.make_instance(module, metamodule)
138
+ from ..kleene import get_kleene_graph_mts
140
139
 
141
- super().__init__(self.instance.make_graph(initial, strategy, opaques), aprops, bdd_dict)
140
+ # opaque strategies are ignored with the new implementation
141
+ super().__init__(get_kleene_graph_mts(module, initial, strategy), aprops, bdd_dict)
142
142
 
143
143
  # Table of distinct iterations (from their context to the index of
144
144
  # its accepting condition)
@@ -166,7 +166,7 @@ class KleeneModelBuilder(SpotModelBuilder):
166
166
  state = pending.pop()
167
167
  state_spot = self.state_map[state]
168
168
 
169
- for next_state in self.graph.getNextStates(state):
169
+ for next_state, edge in self.graph.getTransitions(state):
170
170
  next_state_spot = self.state_map.get(next_state)
171
171
 
172
172
  if next_state_spot is None:
@@ -175,10 +175,10 @@ class KleeneModelBuilder(SpotModelBuilder):
175
175
  pending.append(next_state)
176
176
 
177
177
  # Check the iteration tags and set the accepting labels of the edges
178
- next_state_term = self.instance.get_cterm(self.graph.getStateTerm(next_state))
178
+ next_state_term = self.graph.getStateTerm(next_state)
179
179
  acc_set = []
180
180
 
181
- for tag, enter in self.instance.extract_tags(self.graph.getStateTerm(next_state)):
181
+ for tag, enter in edge.iterations:
182
182
  acc_index = self.iter_map.get(tag)
183
183
 
184
184
  if acc_index is None:
@@ -299,7 +299,6 @@ class SpotBackend:
299
299
  stats['counterexample'] = model_builder.extract_counterexample(run, model_automaton)
300
300
 
301
301
  if get_graph:
302
- stats['graph'] = model_builder.graph if not kleene_iteration \
303
- else OpSemGraph(model_builder.graph, model_builder.instance)
302
+ stats['graph'] = model_builder.graph
304
303
 
305
304
  return holds, stats
@@ -0,0 +1,21 @@
1
+ #
2
+ # Admissibility checking subcommand
3
+ #
4
+
5
+ import os
6
+
7
+ from ..common import parse_initial_data, usermsgs
8
+ # Meter las herramientas en backends y usar la misma estrategia que en otros contextos
9
+
10
+ def acheck(args):
11
+ """Admissibility check subcommand"""
12
+
13
+ # Parse the module data
14
+ data = parse_initial_data(args, only_module=True)
15
+
16
+ if data is None:
17
+ return 1
18
+
19
+ print(data.module)
20
+
21
+ return 0
umaudemc/command/graph.py CHANGED
@@ -11,7 +11,7 @@ from shutil import which
11
11
  from ..common import maude, usermsgs, default_model_settings, parse_initial_data, split_comma
12
12
  from ..formatter import get_formatters
13
13
  from ..grapher import DOTGrapher, PDOTGrapher, TikZGrapher
14
- from ..wrappers import wrapGraph
14
+ from ..wrappers import wrap_graph
15
15
 
16
16
 
17
17
  class ProcessStream:
@@ -96,6 +96,18 @@ def graph(args):
96
96
  args.merge_states,
97
97
  args.strategy)
98
98
 
99
+ # Check the Kleene iteration flag
100
+ kleene_graph = False
101
+
102
+ if args.kleene_iteration:
103
+ if not with_strategy:
104
+ usermsgs.print_warning('The --kleene-iteration flag should only be used with a strategy. Ignoring.')
105
+ elif args.passign:
106
+ usermsgs.print_warning('The --kleene-iteration flag cannot be used with probabilities. Ignoring.')
107
+ else:
108
+ kleene_graph = True
109
+
110
+
99
111
  # Select the appropriate rewriting graph
100
112
  # (probabilistic, strategy-controlled, or standard)
101
113
  if args.passign or oformat in ('prism', 'jani'):
@@ -106,13 +118,18 @@ def graph(args):
106
118
  purge_fails=args.purge_fails,
107
119
  merge_states=args.merge_states)
108
120
 
121
+ elif kleene_graph:
122
+ from ..kleene import get_kleene_graph
123
+ rwgraph = get_kleene_graph(initial_data)
124
+ rwgraph = wrap_graph(rwgraph, purge_fails, merge_states)
125
+
109
126
  elif not with_strategy:
110
127
  rwgraph = maude.RewriteGraph(initial_data.term)
111
128
 
112
129
  else:
113
130
  rwgraph = maude.StrategyRewriteGraph(initial_data.term, initial_data.strategy,
114
131
  initial_data.opaque, initial_data.full_matchrew)
115
- rwgraph = wrapGraph(rwgraph, purge_fails, merge_states)
132
+ rwgraph = wrap_graph(rwgraph, purge_fails, merge_states)
116
133
 
117
134
  # If something has failed when creating the graph
118
135
  if rwgraph is None:
@@ -129,8 +146,19 @@ def graph(args):
129
146
  else:
130
147
  aprops = []
131
148
 
149
+ # State and edge labels
132
150
  slabel, elabel = get_formatters(args.slabel, args.elabel, with_strategy, only_labels=True)
133
151
 
152
+ if kleene_graph:
153
+ # Extend the label with the iteration flags
154
+ original_elabel = elabel
155
+
156
+ def kleene_elabel(stmt):
157
+ iterations_txt = ''.join(f'{" +" if enter else " -"}{iid}' for iid, enter in stmt.iterations)
158
+ return f'{original_elabel(stmt)}{iterations_txt}'
159
+
160
+ elabel = kleene_elabel
161
+
134
162
  # Whether the graph should be seen as a CTMC and probabilities should not be normalized
135
163
  is_ctmc = args.passign and args.passign.startswith('ctmc-')
136
164
 
umaudemc/common.py CHANGED
@@ -14,30 +14,6 @@ from . import usermsgs
14
14
  # Warn about old versions of the maude package installed
15
15
  #
16
16
 
17
- if hasattr(maude, 'StateTransitionGraph'):
18
- usermsgs.print_warning('Version 0.3 of the maude package contains bugs related to model checking.\n'
19
- 'Please update.')
20
-
21
- # Anyhow, allow using it at their own risk, for which some adaptations are needed
22
- maude.RewriteGraph = maude.StateTransitionGraph
23
- maude.StrategyRewriteGraph = maude.StrategyTransitionGraph
24
-
25
- maude.Symbol.__call__ = lambda self, *args: self.makeTerm(args)
26
-
27
- if not hasattr(maude, 'Hook'):
28
- usermsgs.print_warning('Version 0.5 of the maude package adds some useful features for this program.\n'
29
- 'Please update.')
30
-
31
- maude.RewriteGraph.getNrRewrites = lambda: 0
32
- maude.StrategyRewriteGraph.getNrRewrites = lambda: 0
33
- maude.ModelCheckResult.nrBuchiStates = 0
34
- maude.downModule = lambda term: term.symbol().getModule().downModule(term)
35
- maude.Sort.__le__ = lambda self, other: self.leq(other)
36
- maude.Term.__eq__ = lambda self, other: self.equal(other)
37
-
38
- if not hasattr(maude.StrategyRewriteGraph, 'getNrRealStates'):
39
- maude.StrategyRewriteGraph.getNrRealStates = maude.StrategyRewriteGraph.getNrStates
40
-
41
17
  if not hasattr(maude.Term, 'getVarName'):
42
18
  usermsgs.print_warning('Version 1.0 of the maude package adds some useful features for this program.\n'
43
19
  'Please update.')
umaudemc/counterprint.py CHANGED
@@ -78,17 +78,21 @@ def print_counterexample(graph, counter, printer_triple):
78
78
  next_index = lead_in[i+1] if i+1 < len(lead_in) else cycle[0]
79
79
 
80
80
  if graph.strategyControlled:
81
+ trans = graph.getTransition(index, next_index)
82
+
81
83
  printer.next_step_strat(
82
84
  sformat(graph, index),
83
85
  graph.getStateStrategy(index),
84
- eformat(graph, index, next_index),
86
+ eformat(trans),
85
87
  sformat(graph, next_index),
86
88
  first_index=index,
87
89
  second_index=next_index)
88
90
  else:
91
+ rule = graph.getRule(index, next_index)
92
+
89
93
  printer.next_step(
90
94
  sformat(graph, index),
91
- eformat(graph, index, next_index),
95
+ eformat(rule),
92
96
  sformat(graph, next_index),
93
97
  first_index=index,
94
98
  second_index=next_index)
@@ -103,17 +107,21 @@ def print_counterexample(graph, counter, printer_triple):
103
107
  next_index = cycle[i+1] if i+1 < len(cycle) else cycle[0]
104
108
 
105
109
  if graph.strategyControlled:
110
+ trans = graph.getTransition(index, next_index)
111
+
106
112
  printer.next_step_strat(
107
113
  sformat(graph, index),
108
114
  graph.getStateStrategy(index),
109
- eformat(graph, index, next_index),
115
+ eformat(trans),
110
116
  sformat(graph, next_index),
111
117
  first_index=index,
112
118
  second_index=next_index)
113
119
  else:
120
+ rule = graph.getRule(index, next_index)
121
+
114
122
  printer.next_step(
115
123
  sformat(graph, index),
116
- eformat(graph, index, next_index),
124
+ eformat(rule),
117
125
  sformat(graph, next_index),
118
126
  first_index=index,
119
127
  second_index=next_index)
umaudemc/data/smcview.js CHANGED
@@ -38,13 +38,11 @@ function browseDir(dir)
38
38
  }
39
39
  }
40
40
 
41
- var question = new FormData()
42
-
43
- question.append('question', 'ls')
44
- question.append('url', dir)
41
+ var question = {question: 'ls', url: dir}
45
42
 
46
43
  request.open('post', 'ask')
47
- request.send(question)
44
+ request.setRequestHeader('Content-Type', 'application/json')
45
+ request.send(JSON.stringify(question))
48
46
  }
49
47
 
50
48
  function openFile(file)
@@ -57,6 +55,23 @@ function openFile(file)
57
55
  loadSourceModules(file)
58
56
  }
59
57
 
58
+ function loadSourceNative()
59
+ {
60
+ const request = new XMLHttpRequest()
61
+
62
+ request.onreadystatechange = function()
63
+ {
64
+ if (this.readyState == XMLHttpRequest.DONE && this.status == 200)
65
+ {
66
+ console.log(this.responseText)
67
+ openFile(this.responseText)
68
+ }
69
+ }
70
+
71
+ request.open('get', 'umaudemc://open/')
72
+ request.send()
73
+ }
74
+
60
75
  function incompletePassign()
61
76
  {
62
77
  switch (document.getElementById('pmethod').value) {
@@ -193,11 +208,10 @@ function loadSourceModules(file)
193
208
  // Discard modules from previous files
194
209
  smodule.options.length = 0
195
210
 
196
- var question = new FormData()
197
- question.append('question', 'sourceinfo')
198
- question.append('url', file)
211
+ var question = {question: 'sourceinfo', url: file}
199
212
  request.open('post', 'ask')
200
- request.send(question)
213
+ request.setRequestHeader('Content-Type', 'application/json')
214
+ request.send(JSON.stringify(question))
201
215
  }
202
216
 
203
217
  function addPropToFormula(prop)
@@ -318,11 +332,11 @@ function loadModule()
318
332
 
319
333
  description.innerText = 'Please select a Maude file and a Maude module defining the system and properties specification.'
320
334
 
321
- var question = new FormData()
322
- question.append('question', 'modinfo')
323
- question.append('mod', currentModule)
335
+ var question = {question: 'modinfo', mod: currentModule}
336
+
324
337
  request.open('post', 'ask')
325
- request.send(question)
338
+ request.setRequestHeader('Content-Type', 'application/json')
339
+ request.send(JSON.stringify(question))
326
340
  }
327
341
 
328
342
  function modelcheck()
@@ -356,14 +370,14 @@ function modelcheck()
356
370
  }
357
371
  }
358
372
 
359
- var question = new FormData()
360
-
361
- question.append('question', 'modelcheck')
362
- question.append('mod', document.getElementById('module').value)
363
- question.append('initial', document.getElementById('initial').value)
364
- question.append('formula', document.getElementById('formula').value)
365
- question.append('strategy', document.getElementById('strategy').value)
366
- question.append('opaques', document.getElementById('opaques').value)
373
+ const question = {
374
+ question: 'modelcheck',
375
+ mod: document.getElementById('module').value,
376
+ initial: document.getElementById('initial').value,
377
+ formula: document.getElementById('formula').value,
378
+ strategy: document.getElementById('strategy').value,
379
+ opaques: document.getElementById('opaques').value
380
+ }
367
381
 
368
382
  // Quantitative model checking stuff
369
383
  if (document.getElementById('command').value == 'qt')
@@ -375,7 +389,8 @@ function modelcheck()
375
389
  }
376
390
 
377
391
  request.open('post', 'ask')
378
- request.send(question)
392
+ request.setRequestHeader('Content-Type', 'application/json')
393
+ request.send(JSON.stringify(question))
379
394
  }
380
395
 
381
396
  function escapeHTMLChars(text) {
@@ -460,17 +475,15 @@ function waitModelChecker(mcref) {
460
475
  // Disable input until model checking has finished
461
476
  disableInput(true)
462
477
 
463
- var question = new FormData()
478
+ const question = {question: 'wait', mcref: mcref}
464
479
 
465
- question.append('question', 'wait')
466
- question.append('mcref', mcref)
467
480
  request.open('post', 'ask')
468
- request.send(question)
481
+ request.setRequestHeader('Content-Type', 'application/json')
482
+ request.send(JSON.stringify(question))
469
483
  }
470
484
 
471
485
  function cancelChecking() {
472
486
  const request = new XMLHttpRequest()
473
- const question = new FormData()
474
487
 
475
488
  request.onreadystatechange = function()
476
489
  {
@@ -486,9 +499,9 @@ function cancelChecking() {
486
499
  }
487
500
  }
488
501
 
489
- question.append('question', 'cancel')
490
502
  request.open('post', 'ask')
491
- request.send(question)
503
+ request.setRequestHeader('Content-Type', 'application/json')
504
+ request.send('{"question": "cancel"}')
492
505
  }
493
506
 
494
507
  function closeResultDialog()
umaudemc/formatter.py CHANGED
@@ -89,23 +89,18 @@ def parse_state_format(sformat, strategy):
89
89
  tused > 0, sused > 0))
90
90
 
91
91
 
92
- def apply_edge_format(graph, origin, dest, eformat):
92
+ def apply_edge_format(stmt, eformat):
93
93
  """
94
94
  Edge label generator using a prebuilt format string.
95
95
 
96
- :param graph: Rewriting graph the transition belong to.
97
- :type graph: Maude rewriting graph.
98
- :param origin: Index of the origin state within the graph.
99
- :type origin: int
100
- :param dest: Index of the destination state within the graph.
101
- :type dest: int
96
+ :param stmt: Rule that caused the transition
97
+ :type stmt: Rule
102
98
  :param eformat: Prebuilt format string.
103
99
  :type eformat: str
104
100
  :returns: Formatted edge label.
105
101
  :rtype str
106
102
  """
107
103
 
108
- stmt = graph.getRule(origin, dest)
109
104
  label = stmt.getLabel()
110
105
  line = stmt.getLineNumber()
111
106
  opaque = ''
@@ -116,9 +111,8 @@ def apply_edge_format(graph, origin, dest, eformat):
116
111
  return eformat.format(stmt=stmt, label=label, line=line, opaque=opaque)
117
112
 
118
113
 
119
- def apply_edge_format_strat(graph, origin, dest, eformat):
114
+ def apply_edge_format_strat(trans, eformat):
120
115
  """Edge label generator for strategy-controlled using a prebuilt format string"""
121
- trans = graph.getTransition(origin, dest)
122
116
  opaque, label, stmt, line = '', '', '', ''
123
117
 
124
118
  if trans.getType() == maude.StrategyRewriteGraph.SOLUTION:
@@ -150,9 +144,9 @@ def parse_edge_format(eformat, strategy):
150
144
  eformat = re.sub(r'%(.\d+)?n', r'{line:\1}', eformat)
151
145
 
152
146
  if strategy:
153
- return lambda graph, origin, dest: apply_edge_format_strat(graph, origin, dest, eformat)
147
+ return lambda trans: apply_edge_format_strat(trans, eformat)
154
148
  else:
155
- return lambda graph, origin, dest: apply_edge_format(graph, origin, dest, eformat)
149
+ return lambda stmt: apply_edge_format(stmt, eformat)
156
150
 
157
151
 
158
152
  #
@@ -165,29 +159,30 @@ def print_term(graph, index):
165
159
  return graph.getStateTerm(index)
166
160
 
167
161
 
168
- def print_transition(graph, origin, dest):
162
+ def print_transition(stmt):
169
163
  """Default edge-label printing function"""
170
- return graph.getRule(origin, dest)
164
+ return stmt
171
165
 
172
166
 
173
- def print_transition_strat(graph, origin, dest):
167
+ def print_transition_strat(trans):
174
168
  """Default edge-label printing function with strategies"""
175
- trans = graph.getTransition(origin, dest)
176
- return {
177
- maude.StrategyRewriteGraph.RULE_APPLICATION : trans.getRule(),
178
- maude.StrategyRewriteGraph.OPAQUE_STRATEGY : trans.getStrategy(),
179
- maude.StrategyRewriteGraph.SOLUTION : ''
180
- }[trans.getType()]
169
+ ttype = trans.getType()
170
+
171
+ if ttype == maude.StrategyRewriteGraph.RULE_APPLICATION:
172
+ return trans.getRule()
173
+ elif ttype == maude.StrategyRewriteGraph.OPAQUE_STRATEGY:
174
+ return trans.getStrategy()
175
+ else:
176
+ return ''
181
177
 
182
178
 
183
- def print_transition_label(graph, origin, dest):
179
+ def print_transition_label(stmt):
184
180
  """Alternative edge-label printing function (only rule label)"""
185
- return graph.getRule(origin, dest).getLabel()
181
+ return stmt.getLabel()
186
182
 
187
183
 
188
- def print_transition_strat_label(graph, origin, dest):
184
+ def print_transition_strat_label(trans):
189
185
  """Alternative edge-label printing function with strategies (only rule/strategy label)"""
190
- trans = graph.getTransition(origin, dest)
191
186
  ttype = trans.getType()
192
187
 
193
188
  if ttype == maude.StrategyRewriteGraph.RULE_APPLICATION:
umaudemc/grapher.py CHANGED
@@ -43,8 +43,8 @@ class DOTGrapher:
43
43
  if bound == 0:
44
44
  return
45
45
 
46
- for next_state in graph.getNextStates(stateNr):
47
- elabel = self.elabel(graph, stateNr, next_state) if self.elabel else None
46
+ for next_state, edge in graph.getTransitions(stateNr):
47
+ elabel = self.elabel(edge) if self.elabel else None
48
48
  self.write_transition(stateNr, next_state, elabel)
49
49
 
50
50
  if next_state not in self.visited:
@@ -67,7 +67,8 @@ class PDOTGrapher(DOTGrapher):
67
67
  num, den = Fraction(p).limit_denominator().as_integer_ratio()
68
68
 
69
69
  # Standard labels are used too
70
- elabel = self.elabel(graph, start, end)
70
+ stmt = graph.getTransition(start, end) if graph.strategyControlled else graph.getRule(start, end)
71
+ elabel = self.elabel(stmt)
71
72
 
72
73
  return f'{num}/{den} {elabel}' if p != 1.0 else elabel
73
74
 
@@ -123,14 +124,14 @@ class TikZGrapher:
123
124
  if bound == 0:
124
125
  return
125
126
 
126
- for next_state in graph.getNextStates(stateNr):
127
+ for next_state, edge in graph.getTransitions(stateNr):
127
128
  print(f'\t{self.printState(graph, stateNr)}', file=self.outfile, end='')
128
129
  next_visited = next_state in self.visited
129
130
 
130
131
  if self.elabel is None:
131
132
  print(f' -> ', file=self.outfile, end='')
132
133
  else:
133
- label = str(self.elabel(graph, stateNr, next_state)).replace('"', '""')
134
+ label = str(self.elabel(edge)).replace('"', '""')
134
135
  print(f' ->["{label}"] ', file=self.outfile, end='')
135
136
 
136
137
  print(f'{self.printState(graph, next_state)};', file=self.outfile)