|
28 | 28 | import java.util.ArrayList; |
29 | 29 | import java.util.Arrays; |
30 | 30 | import java.util.HashMap; |
| 31 | +import java.util.HashSet; |
31 | 32 | import java.util.List; |
32 | 33 | import java.util.Map; |
33 | 34 | import java.util.Scanner; |
@@ -425,32 +426,57 @@ public void buildCtrExtension(String id, XVarInteger[] list, AbstractTuple[] tup |
425 | 426 | controlConstraint(found == positive); |
426 | 427 | } |
427 | 428 |
|
428 | | - private String reachedState(String startState, XVarInteger[] list, Transition[] transitions) { |
429 | | - Map<String, String> map = new HashMap<>(); |
430 | | - Stream.of(transitions).forEach(tr -> map.put(tr.start + ":" + tr.value, tr.end + "")); |
431 | | - String current = startState; |
432 | | - for (XVarInteger x : list) { |
433 | | - String next = map.get(current + ":" + solution.intValueOf(x)); |
434 | | - if (next == null) |
435 | | - return null; |
436 | | - else |
437 | | - current = next; |
438 | | - } |
439 | | - return current; |
440 | | - } |
| 429 | + private void collectStates(String current, int i, XVarInteger[] list, Map<String, List<String>> map, Set<String> reached, Set<String> seen) { |
| 430 | + String node = current + " " + i; // it is important to record the level |
| 431 | + if (seen.contains(node)) |
| 432 | + return; // because already explored |
| 433 | + seen.add(node); |
| 434 | + List<String> nexts = map.get(current + ":" + solution.intValueOf(list[i])); |
| 435 | + if (nexts != null) |
| 436 | + for (String next : nexts) |
| 437 | + if (i == list.length - 1) |
| 438 | + reached.add(next); |
| 439 | + else |
| 440 | + collectStates(next, i + 1, list, map, reached, seen); |
| 441 | + } |
| 442 | + |
| 443 | + private Set<String> reachedStates(String startState, XVarInteger[] list, Transition[] transitions) { |
| 444 | + Set<String> seen = new HashSet<>(), reached = new HashSet<>(); |
| 445 | + Map<String, List<String>> map = new HashMap<>(); |
| 446 | + for (Transition tr : transitions) |
| 447 | + map.computeIfAbsent(tr.start + ":" + tr.value, r -> new ArrayList<String>()).add(tr.end); |
| 448 | + collectStates(startState, 0, list, map, reached, seen); |
| 449 | + return reached; |
| 450 | + } |
| 451 | + |
| 452 | + // private List<String> reachedStates(String startState, XVarInteger[] list, Transition[] transitions) { |
| 453 | + // List<String> reached = new ArrayList<>(); |
| 454 | + // Map<String, String> map = new HashMap<>(); |
| 455 | + // Stream.of(transitions).forEach(tr -> map.put(tr.start + ":" + tr.value, tr.end + "")); |
| 456 | + // String current = startState; |
| 457 | + // for (XVarInteger x : list) { |
| 458 | + // String next = map.get(current + ":" + solution.intValueOf(x)); |
| 459 | + // System.out.println("tra " + x + " " + solution.intValueOf(x) + " " + next); |
| 460 | + // if (next == null) |
| 461 | + // return null; |
| 462 | + // else |
| 463 | + // current = next; |
| 464 | + // } |
| 465 | + // reached.add(current); |
| 466 | + // return reached; |
| 467 | + // } |
441 | 468 |
|
442 | 469 | @Override |
443 | 470 | public void buildCtrRegular(String id, XVarInteger[] list, Transition[] transitions, String startState, String[] finalStates) { |
444 | | - String state = reachedState(startState, list, transitions); |
445 | | - controlConstraint(state != null && Arrays.stream(finalStates).anyMatch(v -> v.equals(state))); |
| 471 | + Set<String> reached = reachedStates(startState, list, transitions); |
| 472 | + controlConstraint(reached.size() > 0 && Arrays.stream(finalStates).anyMatch(v -> reached.stream().anyMatch(state -> v.equals(state)))); |
446 | 473 | } |
447 | 474 |
|
448 | 475 | @Override |
449 | 476 | public void buildCtrMDD(String id, XVarInteger[] list, Transition[] transitions) { |
450 | | - String state = reachedState(transitions[0].start, list, transitions); // The first state of the first transition |
451 | | - // MUST be the |
452 | | - // starting state |
453 | | - controlConstraint(state != null); |
| 477 | + Set<String> reached = reachedStates(transitions[0].start, list, transitions); |
| 478 | + // The first state of the first transition MUST be the starting state |
| 479 | + controlConstraint(reached.size() > 0); |
454 | 480 | } |
455 | 481 |
|
456 | 482 | @Override |
|
0 commit comments