2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.listener;
20 import gov.nasa.jpf.Config;
21 import gov.nasa.jpf.JPF;
22 import gov.nasa.jpf.ListenerAdapter;
23 import gov.nasa.jpf.search.Search;
24 import gov.nasa.jpf.jvm.bytecode.*;
25 import gov.nasa.jpf.vm.*;
26 import gov.nasa.jpf.vm.bytecode.LocalVariableInstruction;
27 import gov.nasa.jpf.vm.bytecode.ReadInstruction;
28 import gov.nasa.jpf.vm.bytecode.StoreInstruction;
29 import gov.nasa.jpf.vm.bytecode.WriteInstruction;
30 import gov.nasa.jpf.vm.choice.IntIntervalGenerator;
32 import java.io.PrintWriter;
36 // TODO: Fix for Groovy's model-checking
37 // TODO: This is a listener created to detect device conflicts and global variable conflicts
39 * Simple listener tool to track remove unwanted ChoiceGenerators that are registered
40 * while an existing ChoiceGenerator is being explored. Multiple ChoiceGenerators of the same
41 * type could be registered spuriously during a while(true) loop.
43 public class StateReducer extends ListenerAdapter {
45 private boolean debugMode;
46 private final PrintWriter out;
47 private String detail;
50 private Transition transition;
52 // Holds values that have appeared during CG advances
53 private HashSet<Integer> cgChoiceSet;
54 private Integer choiceUpperBound;
55 private boolean isInitialized;
57 public StateReducer (Config config, JPF jpf) {
58 debugMode = config.getBoolean("debug_state_transition", false);
60 out = new PrintWriter(System.out, true);
68 cgChoiceSet = new HashSet<>();
70 isInitialized = false;
74 public void stateRestored(Search search) {
76 id = search.getStateId();
77 depth = search.getDepth();
78 transition = search.getTransition();
80 out.println("\n==> DEBUG: The state is restored to state with id: " + id + " -- Transition: " + transition +
81 " and depth: " + depth + "\n");
85 //--- the ones we are interested in
87 public void searchStarted(Search search) {
89 out.println("\n==> DEBUG: ----------------------------------- search started" + "\n");
94 public void choiceGeneratorSet (VM vm, ChoiceGenerator<?> newCG) {
95 // Initialize with necessary information from the CG
96 if (newCG instanceof IntIntervalGenerator) {
97 IntIntervalGenerator iigCG = (IntIntervalGenerator) newCG;
98 // Check if CG has been initialized, otherwise initialize it
100 Integer[] choices = iigCG.getChoices();
101 // Get the upper bound from the last element of the choices
102 choiceUpperBound = choices[choices.length - 1];
103 isInitialized = true;
111 public void choiceGeneratorAdvanced (VM vm, ChoiceGenerator<?> currentCG) {
112 // Check every choice generated and make sure that all the available choices
113 // are chosen first before repeating the same choice of value twice!
114 if (currentCG instanceof IntIntervalGenerator) {
115 IntIntervalGenerator iigCG = (IntIntervalGenerator) currentCG;
116 Integer nextChoice = iigCG.getNextChoice();
117 if (!cgChoiceSet.contains(nextChoice)) {
118 cgChoiceSet.add(nextChoice);
120 // Allow reinitialization after an upper bound is hit
121 // This means all available choices have been explored once during this iteration
122 if (cgChoiceSet.contains(choiceUpperBound)) {
123 isInitialized = false;
130 public void stateAdvanced(Search search) {
132 id = search.getStateId();
133 depth = search.getDepth();
134 transition = search.getTransition();
135 if (search.isNewState()) {
141 if (search.isEndState()) {
142 out.println("\n==> DEBUG: This is the last state!\n");
145 out.println("\n==> DEBUG: The state is forwarded to state with id: " + id + " with depth: " + depth +
146 " which is " + detail + " Transition: " + transition + "\n");
151 public void stateBacktracked(Search search) {
153 id = search.getStateId();
154 depth = search.getDepth();
155 transition = search.getTransition();
158 out.println("\n==> DEBUG: The state is backtracked to state with id: " + id + " -- Transition: " + transition +
159 " and depth: " + depth + "\n");
164 public void searchFinished(Search search) {
166 out.println("\n==> DEBUG: ----------------------------------- search finished" + "\n");