|
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