Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

LTL.java

00001 package gov.nasa.arc.ase.jpf;
00002 
00003 //#ifdef BUCHI
00004 import gov.nasa.arc.ase.util.Debug;
00005 import java.util.Stack;
00006 
00007 public class LTL implements iSearch {
00008   public static final boolean FIRST_DFS     = true;
00009   public static final boolean SECOND_DFS    = false;
00010 
00011   public static final int OLD_OFF_STACK     = -1;
00012   public static final int NEW           = -2;
00013 
00014   private boolean done = false;
00015   private boolean failed = false;
00016   private boolean deadlock = false;
00017   private Path errorPath;
00018   private ErrorTrailInterface error;
00019 
00020   private Stack buchiStack;
00021   private Stack buchiSchStack;
00022   private Stack acptStack;
00023   private int buchiState;
00024   private Sch buchiSch;
00025   private SM buchi;
00026   private BuchiSet buchiSet;
00027   private Stack buchiSetStack;
00028 
00029   public LTL() {
00030     Debug.println(Debug.MESSAGE, "LTL Search");
00031     initBuchi();
00032   }  
00033   public int acptStack_peek() {
00034     if(acptStack.size() == 0) return -1;
00035 
00036     return ((Integer)acptStack.peek()).intValue();
00037   }  
00038   public void acptStack_pop(int index) {
00039     if(buchi.accepting[buchiState])
00040       acptStack.pop();
00041   }  
00042   public void acptStack_push(int index) {
00043     if(buchi.accepting[buchiState])
00044       acptStack.push(new Integer(index));
00045   }  
00046   public void buchi_backtrack() {
00047     buchi_pop();
00048     buchiSch_pop();
00049   }  
00050   public boolean buchi_forward() {
00051     buchi_push();
00052     boolean buchi_move = buchi_next();
00053     buchiSch_push();
00054 
00055     return buchi_move;
00056   }  
00057   public boolean buchi_next() {
00058     SM b = buchi;
00059     b.setSch(buchiSch);
00060 
00061     int nt = b.getTransitionCount(buchiState);
00062     int t = -1;
00063     boolean enabled = false;
00064     boolean first = buchiSch.getTransition() == 0 && buchiSch.getRandom() == 0;
00065 
00066     if(!first) {
00067       while(buchiSch.getTransition() < nt) {
00068     t = buchiSch.getTransition();
00069     if(b.getGuard(buchiState, t) != null) {
00070       if(b.isEnabled(buchiState, t)) {
00071         enabled = true;
00072         break;
00073       } else
00074         buchiSch.getNextTransition();
00075     } else
00076       buchiSch.getNextTransition();
00077       }
00078     } else {
00079       while(buchiSch.getTransition() < nt) {
00080     t = buchiSch.getTransition();
00081     if(b.getGuard(buchiState, t) != null) {
00082       if(b.isEnabled(buchiState, t)) {
00083         enabled = true;
00084         break;
00085       } else
00086         buchiSch.getNextTransition();
00087     } else {
00088       enabled = true;
00089       break;
00090     }
00091       }
00092     }
00093 
00094     if(!enabled) {
00095       buchiSch.getNextTransition();
00096       return false;
00097     }
00098 
00099 //#ifdef DEBUG
00100 
00101 //#endif DEBUG
00102     int r = buchiSch.getRandom();
00103     buchiState = b.execute(buchiState, t);
00104     if(r == buchiSch.getRandom())
00105       buchiSch.getNextTransition();
00106 //#ifdef DEBUG
00107 
00108 //#endif DEBUG
00109 
00110     return true;
00111   }  
00112   public void buchi_pop() {
00113     buchiState = ((Integer)buchiStack.pop()).intValue();
00114   }  
00115   public void buchi_push() {
00116     buchiStack.push(new Integer(buchiState));
00117   }  
00118   public void buchi_undo() {
00119     int t = buchiSch.getTransition();
00120     int r = buchiSch.getRandom();
00121 
00122     buchi.backtrack(buchiState, r == 0 ? t-1 : t);
00123   }  
00124   public void buchiSch_pop() {
00125     buchiSch = (Sch)buchiSchStack.pop();
00126   }  
00127   public void buchiSch_push() {
00128     buchiSchStack.push(buchiSch.copy());
00129   }  
00130   private void buchiSet_get() {
00131     buchiSet = Engine.getJPF().vm.BuchiGet();
00132   }  
00133   private void buchiSet_pop() {
00134     buchiSet = (BuchiSet)buchiSetStack.pop();
00135   }  
00136   private void buchiSet_push() {
00137     buchiSetStack.push(buchiSet);
00138     buchiSet = null;
00139   }  
00140   private void error() {
00141     failed = true;
00142     if (Engine.options.bandera) {
00143       errorPath = Engine.getJPF().vm.getErrorTrail1();
00144     } else {
00145       error = Engine.getJPF().vm.getErrorTrail();        
00146     }
00147     done = !Engine.options.multiple_errors;
00148   }  
00149   public ErrorTrailInterface getError() {
00150     return error;
00151   }  
00152   public String getErrorMessage() {
00153     if(!failed) return "No Errors Found";
00154 
00155     if(deadlock) return "Deadlock found";
00156 
00157     return Engine.getJPF().vm.getErrorMessage();
00158   }  
00159   public Path getErrorPath() {
00160     return errorPath;
00161   }  
00162   public boolean hasFailed() {
00163     return failed;
00164   }  
00165   public void initBuchi() {
00166     buchi = SM.load(Engine.options.buchi);
00167 
00168     buchiStack = new Stack();
00169     buchiSchStack = new Stack();
00170     acptStack = new Stack();
00171     buchiSetStack = new Stack();
00172 
00173     buchiState = 0;
00174   }  
00175   private void off_stack(boolean first) {
00176     buchiSet.replace((first ? 0x80000000 : 0) | buchiState, OLD_OFF_STACK);
00177   }  
00178   public void search() {
00179 //#ifdef DEBUG
00180 
00181 //#endif DEBUG
00182     search(FIRST_DFS, 0);
00183 //#ifdef DEBUG
00184 
00185 //#endif DEBUG
00186   }  
00187   private boolean search(boolean first, int stack_start) {
00188     int index = stack_start;
00189     boolean up = false;
00190     iVirtualMachine vm = Engine.getJPF().vm;
00191     Status status = Engine.getJPF().status;
00192 
00193 Down:
00194     while(true) {
00195       vm.BuchiInitSch();
00196       while(true) {
00197     boolean buchiSet_get = false;
00198 
00199     if(!up) {
00200       int result = vm.BuchiForward();
00201 
00202       if(TransitionResult.isError(result)) {
00203         error();
00204         return true;
00205       }
00206 
00207       if(TransitionResult.isEnd(result)) {
00208 //#ifdef DEBUG
00209 
00210 //#endif DEBUG
00211         break;
00212       }
00213 
00214 //#ifdef DEBUG
00215 
00216 //#endif DEBUG
00217 
00218       buchiSch = new Sch();
00219       buchiSet_get = true;
00220     }
00221 
00222     while(true) {
00223       if(up) {
00224 
00225         Debug.println(Debug.MESSAGE, "Going up");
00226 
00227         up = false; index--;
00228         buchiSet_pop();
00229         off_stack(first);
00230         acptStack_pop(index);
00231         buchi_backtrack();
00232         buchi_undo();
00233         continue;
00234       }
00235 
00236       if(!buchi_forward()) {
00237 //#ifdef DEBUG
00238 
00239 //#endif DEBUG
00240         buchi_backtrack();
00241         break;
00242       }
00243 
00244 //#ifdef DEBUG
00245 
00246 //#endif DEBUG
00247 
00248       if(buchiSet_get) buchiSet_get();
00249       vm.BuchiSetState(buchiState);
00250       int currently = store(first, index);
00251 
00252       if(buchi.trivial[buchiState])
00253         if(buchi.accepting[buchiState]) {
00254           error();
00255           return true;
00256         } else {
00257           Debug.println(Debug.ERROR, "Reached a non-accepting trivial state");
00258           buchi_backtrack();
00259           buchi_undo();
00260           break;
00261         }
00262 
00263       if(currently == NEW) {
00264 //#ifdef DEBUG
00265 
00266 //#endif DEBUG
00267         status.states++;
00268         if(index != 0) status.transitions++;
00269         acptStack_push(index);
00270         index++;
00271         buchiSet_push();
00272         continue Down;
00273       } else {
00274 //#ifdef DEBUG
00275 
00276 //#endif DEBUG
00277         status.transitions++;
00278         if(currently != OLD_OFF_STACK) {
00279 //#ifdef DEBUG
00280 
00281 //#endif DEBUG
00282           if(currently <= acptStack_peek()) {
00283         error();
00284         Debug.println(Debug.ERROR, "Cycle detected");
00285         return true;
00286           }
00287         } else {
00288 //#ifdef DEBUG
00289 
00290 //#endif DEBUG
00291         }
00292       }
00293 
00294       buchi_backtrack();
00295       buchi_undo();
00296     }
00297 
00298     vm.BuchiBacktrack();
00299       }
00300 
00301       if(first && buchi.accepting[buchiState]) {
00302     if(!buchi.persistant[buchiState]) {
00303 //#ifdef DEBUG
00304 
00305 //#endif DEBUG
00306       vm.BuchiInitSch();
00307       boolean violation = search(SECOND_DFS, index);
00308 //#ifdef DEBUG
00309 
00310 //#endif DEBUG
00311       if(violation) return true;
00312     }
00313       }
00314 
00315       if(index == stack_start) break;
00316 
00317 
00318       Debug.println(Debug.MESSAGE, "Going up now");
00319 
00320       up = true;
00321     }
00322 
00323     return false;
00324   }  
00325   private int store(boolean first, int index) {
00326     int b = 0x80000000 | buchiState;
00327 
00328 //#ifdef DEBUG
00329 
00330 
00331 //#endif DEBUG
00332 
00333     if(!first) {
00334       int d = buchiSet.get(b);
00335       if(d > OLD_OFF_STACK) {
00336 //#ifdef DEBUG
00337 
00338 //#endif DEBUG
00339     return d;
00340       }
00341       b &= 0x7FFFFFFF;
00342     }
00343 
00344     int d = buchiSet.get(b);
00345     if(d >= OLD_OFF_STACK) {
00346 //#ifdef DEBUG
00347 
00348 //#endif DEBUG
00349       return d;
00350     }
00351 
00352     buchiSet.add(b, index);
00353 
00354     return NEW;
00355   }  
00356 }

Generated at Thu Feb 7 06:50:10 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001