Mercurial > hg > Members > kono > jpf-core
view src/examples/Crossing.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
line wrap: on
line source
/* * Copyright (C) 2014, United States Government, as represented by the * Administrator of the National Aeronautics and Space Administration. * All rights reserved. * * The Java Pathfinder core (jpf-core) platform is licensed under the * Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * This is the famous Bridge-crossing puzzle. The aim is to see what the minimum * amount of time is for 4 people to cross with flash-light (torch): 10.5.2.1. * The answer is 17 for the given configuration. * * Purpose of this example is to show how to use the 'Verify' API in test * applications (usually drivers) * * One can find this solution with JPF in BFS search mode - DFS will not * work since this is an infinite-state program (time keeps increasing). * * If one uses the ignoreIf(cond) call the branches that will lead to * solutions worst than the current will be cut-off and this will allow * DFS also to complete - and BFS to terminate faster. * * When setting the native flag in main one can also save information * from one run to the next using JPF's native peer methods - * see JPF_Crossing.java for the code of getTotal() and setTotal(int). */ import gov.nasa.jpf.vm.Verify; enum Side { LEFT, RIGHT } class Bridge { Side torchSide; Person[] onBridge = new Person[2]; int numOnBridge = 0; public Bridge (Side torchSide){ this.torchSide = torchSide; } void moveTorch(){ if (torchSide == Side.LEFT){ torchSide = Side.RIGHT; } else { torchSide = Side.LEFT; } } public int cross() { int time = 0; moveTorch(); if (numOnBridge == 1) { onBridge[0].side = torchSide; time = onBridge[0].timeToCross; //System.out.println("Person " + onBridge[0] + // " moved to " + Torch.side + // " in time " + time); } else { onBridge[0].side = torchSide; onBridge[1].side = torchSide; if (onBridge[0].timeToCross > onBridge[1].timeToCross) { time = onBridge[0].timeToCross; } else { time = onBridge[1].timeToCross; } //System.out.println("Person " + onBridge[0] + // " and Person " + onBridge[1] + // " moved to " + Torch.side + // " in time " + time); } return time; } public void clearBridge() { numOnBridge = 0; onBridge[0] = null; onBridge[1] = null; } boolean isFull(){ return numOnBridge == 2; } boolean arePersonsOnBridge(){ return numOnBridge > 0; } boolean isPersonOnBridge (Person p){ return (p == onBridge[0] || p == onBridge[1]); } void putPersonOnBridge (Person p){ onBridge[numOnBridge++] = p; } } class Person { String name; Side side; int timeToCross; public Person(String name, int timeToCross) { this.timeToCross = timeToCross; this.name = name; } public void tryToMove (Bridge bridge) { if (side == bridge.torchSide) { if (!Verify.getBoolean()) { if (! (bridge.isFull() || bridge.isPersonOnBridge(this))){ bridge.putPersonOnBridge(this); } } } } @Override public String toString(){ return name; } } public class Crossing { Bridge bridge; Person[] persons; int elapsedTime; Side initialSide; public Crossing (Person[] persons, Side initialSide){ this.persons = persons; for (Person p : persons){ p.side = initialSide; } this.bridge = new Bridge( initialSide); this.initialSide = initialSide; } boolean haveAllPersonsCrossed (){ for (Person p : persons){ if (p.side == initialSide){ return false; } } return true; } void solve (){ printPersons(); System.out.println(); printCrossingState(); //Verify.setCounter(0, Integer.MAX_VALUE); while (!haveAllPersonsCrossed()){ for (Person p : persons){ p.tryToMove(bridge); } if (bridge.arePersonsOnBridge()) { elapsedTime += bridge.cross(); //Verify.ignoreIf(elapsedTime >= Verify.getCounter(0)); //Verify.ignoreIf(elapsedTime > 17); //with this DFS will also find error bridge.clearBridge(); } printCrossingState(); } System.out.println("total time = " + elapsedTime); //Verify.setCounter(0, elapsedTime); // new minimum Verify.printPathOutput("done"); Verify.storeTraceAndTerminateIf(elapsedTime == 17, null, null); //assert (elapsedTime > 17); } String personsOnSide (Side side){ int n=0; StringBuilder sb = new StringBuilder(); for (Person p : persons){ if (p.side == side){ if (n++ > 0){ sb.append(','); } sb.append( p); } } return sb.toString(); } String torchSymbol (Side side){ if (bridge.torchSide == side){ return "*"; } else { return " "; } } void printPersons(){ for (Person p : persons){ System.out.printf("%10s needs %2d min to cross\n", p.name, p.timeToCross); } } void printCrossingState (){ System.out.printf("%20s %s====%s %-20s : elapsed time=%d\n", personsOnSide(Side.LEFT), torchSymbol(Side.LEFT), torchSymbol(Side.RIGHT), personsOnSide(Side.RIGHT), elapsedTime); } public static void main(String[] args) { Person[] persons = { new Person("Bill", 1), new Person("Xoe", 2), new Person("Sue", 5), new Person("Joe", 10) }; Crossing crossing = new Crossing( persons, Side.LEFT); crossing.solve(); } }