Skip to content

Commit 52bb31e

Browse files
authored
Merge pull request #7 from lip6/master
merging with last update concerning smt solver onesafe
2 parents 53b77ef + 26e3bf2 commit 52bb31e

File tree

8 files changed

+283
-84
lines changed

8 files changed

+283
-84
lines changed

fr.lip6.move.gal.structural/src/android/util/SparseIntArray.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,17 @@ public SparseIntArray(List<Integer> marks) {
8585
}
8686
}
8787

88-
public List<Integer> toList (int size) {
88+
public SparseIntArray(int[] marks) {
89+
// compute and set correct capacity
90+
this ( (int) Arrays.stream(marks).filter(e -> e != 0).count());
91+
for (int i = 0, e = marks.length ; i < e ; i++) {
92+
int v = marks[i];
93+
if (v != 0) {
94+
append(i, v);
95+
}
96+
}
97+
}
98+
public List<Integer> toList (int size) {
8999
List<Integer> res = new ArrayList<Integer> (size);
90100
int j = 0;
91101
for (int i=0; i < size ; i++ ) {

fr.lip6.move.gal.structural/src/fr/lip6/move/gal/structural/RandomExplorer.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public int[] runGuidedReachabilityDetection (long nbSteps, SparseIntArray parikh
5858
for (; i < nbSteps ; i++) {
5959
long dur = System.currentTimeMillis() - time + 1;
6060
if (dur > 1000 * timeout) {
61-
System.out.println("Interrupted Parikh walk after "+ i + " steps, including "+nbresets+ " resets, run timeout after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
61+
System.out.println("Interrupted Parikh walk after "+ i + " steps, including "+nbresets+ " resets, run timeout after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
6262
return verdicts;
6363
}
6464
if (!max) {
@@ -122,7 +122,7 @@ public int[] runGuidedReachabilityDetection (long nbSteps, SparseIntArray parikh
122122
}
123123

124124
long dur = System.currentTimeMillis() - time + 1;
125-
System.out.println("Incomplete Parikh walk after "+ i + " steps, including "+nbresets+ " resets, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) + " could not realise parikh vector " + (DEBUG >=1 ? parikhori : "")+ (DEBUG >=1 ? (" reached state " + state):"") );
125+
System.out.println("Incomplete Parikh walk after "+ i + " steps, including "+nbresets+ " resets, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) + " could not realise parikh vector " + (DEBUG >=1 ? parikhori : "")+ (DEBUG >=1 ? (" reached state " + state):"") );
126126
return verdicts;
127127
}
128128

@@ -160,7 +160,7 @@ public int[] runProbabilisticReachabilityDetection (long nbSteps, List<Expressio
160160

161161
long dur = System.currentTimeMillis() - time + 1;
162162
if (dur > 1000 * timeout) {
163-
System.out.println("Interrupted probabilistic random walk after "+ i + " steps, run timeout after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
163+
System.out.println("Interrupted probabilistic random walk after "+ i + " steps, run timeout after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
164164
break;
165165
}
166166

@@ -225,20 +225,20 @@ public int[] runProbabilisticReachabilityDetection (long nbSteps, List<Expressio
225225
if (todo.isEmpty()) {
226226
wex.wasExhaustive = true;
227227
if (! exhaustive) {
228-
System.out.println("Probably explored full state space saw : "+ seen + " states, properties seen :" + Arrays.toString(verdicts) );
228+
System.out.println("Probably explored full state space saw : "+ seen + " states, properties seen :" + new SparseIntArray(verdicts) );
229229
} else {
230-
System.out.println("Explored full state space saw : "+ seen + " states, properties seen :" + Arrays.toString(verdicts) );
230+
System.out.println("Explored full state space saw : "+ seen + " states, properties seen :" + new SparseIntArray(verdicts) );
231231
}
232232
}
233233
long dur = System.currentTimeMillis() - time + 1;
234234
if (! exhaustive) {
235-
System.out.println("Probabilistic random walk after "+ i + " steps, saw "+seen+" distinct states, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) );
235+
System.out.println("Probabilistic random walk after "+ i + " steps, saw "+seen+" distinct states, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) );
236236
} else {
237-
System.out.println("Exhaustive walk after "+ i + " steps, saw "+seen+" distinct states, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) );
237+
System.out.println("Exhaustive walk after "+ i + " steps, saw "+seen+" distinct states, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) );
238238
}
239239
} catch (OutOfMemoryError e) {
240240
long dur = System.currentTimeMillis() - time + 1;
241-
System.out.println("Probabilistic random walk exhausted memory after "+ i + " steps, saw "+seen+" distinct states, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) );
241+
System.out.println("Probabilistic random walk exhausted memory after "+ i + " steps, saw "+seen+" distinct states, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) );
242242
}
243243
return verdicts;
244244
}
@@ -272,7 +272,7 @@ public int[] runRandomReachabilityDetection (long nbSteps, List<Expression> expr
272272
for (; i < nbSteps ; i++) {
273273
long dur = System.currentTimeMillis() - time + 1;
274274
if (dur > 1000 * timeout) {
275-
System.out.println("Interrupted "+(bestFirst>=0?"Best-First ":"")+"random walk after "+ i + " steps, including "+nbresets+ " resets, run timeout after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
275+
System.out.println("Interrupted "+(bestFirst>=0?"Best-First ":"")+"random walk after "+ i + " steps, including "+nbresets+ " resets, run timeout after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
276276
return verdicts;
277277
}
278278
if (!max) {
@@ -347,7 +347,7 @@ public int[] runRandomReachabilityDetection (long nbSteps, List<Expression> expr
347347
}
348348
}
349349
long dur = System.currentTimeMillis() - time + 1;
350-
System.out.println("Incomplete "+(bestFirst>=0?"Best-First ":"")+"random walk after "+ i + " steps, including "+nbresets+ " resets, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + Arrays.toString(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
350+
System.out.println("Incomplete "+(bestFirst>=0?"Best-First ":"")+"random walk after "+ i + " steps, including "+nbresets+ " resets, run finished after "+ dur +" ms. (steps per millisecond="+ (i/dur) +" )"+ " properties seen :" + new SparseIntArray(verdicts) +(DEBUG >=1 ? (" reached state " + state):"") );
351351

352352
return verdicts;
353353
}

fr.lip6.move.gal.structural/src/fr/lip6/move/gal/structural/SparsePetriNet.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ private Expression replacePredicates(Expression expr) {
186186
return expr;
187187
}
188188

189-
public void testInInitial () {
189+
public int testInInitial () {
190190
SparseIntArray spinit = new SparseIntArray(marks);
191191
int proved = 0;
192192
for (Property prop : getProperties()) {
@@ -206,6 +206,7 @@ public void testInInitial () {
206206
if (proved > 0) {
207207
Logger.getLogger("fr.lip6.move.gal").info("Initial state test concluded for "+proved+ " properties.");
208208
}
209+
return proved;
209210
}
210211

211212
private Expression simplifyConstants(Expression expr, int[] perm) {

pnmcc/fr.lip6.move.gal.application.pnmcc/src/fr/lip6/move/gal/application/Application.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,9 @@ public Object startNoEx(IApplicationContext context) throws Exception {
365365
ReachabilitySolver.checkInInitial(reader.getSPN(), doneProps);
366366
reader.getSPN().getProperties().removeIf(p -> doneProps.containsKey(p.getName()));
367367

368-
UpperBoundsSolver.checkInInitial(reader, doneProps);
368+
UpperBoundsSolver.checkInInitial(reader.getSPN(), doneProps);
369369

370-
UpperBoundsSolver.applyReductions(reader, doneProps, solverPath, isSafe, skelBounds);
370+
UpperBoundsSolver.applyReductions(reader.getSPN(), doneProps, solverPath, isSafe, skelBounds);
371371

372372
reader.getSPN().getProperties().removeIf(p -> doneProps.containsKey(p.getName()));
373373
// checkInInitial(reader.getSpec(), doneProps, isSafe);
@@ -384,8 +384,8 @@ public Object startNoEx(IApplicationContext context) throws Exception {
384384
System.out.println("Starting property specific reduction for " + p.getName());
385385
r2.getSPN().getProperties().clear();
386386
r2.getSPN().getProperties().add(p);
387-
UpperBoundsSolver.checkInInitial(r2, doneProps);
388-
UpperBoundsSolver.applyReductions(r2, doneProps, solverPath, isSafe, null);
387+
UpperBoundsSolver.checkInInitial(r2.getSPN(), doneProps);
388+
UpperBoundsSolver.applyReductions(r2.getSPN(), doneProps, solverPath, isSafe, null);
389389
System.out.println("Ending property specific reduction for " + p.getName() + " in "
390390
+ (System.currentTimeMillis() - time) + " ms.");
391391
}

pnmcc/fr.lip6.move.gal.application.pnmcc/src/fr/lip6/move/gal/application/GlobalPropertySolver.java

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package fr.lip6.move.gal.application;
22

3+
import java.util.ArrayList;
34
import java.util.Arrays;
45
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Set;
8+
import java.util.logging.Logger;
59
import java.util.Map.Entry;
610

11+
import android.util.SparseIntArray;
712
import fr.lip6.move.gal.mcc.properties.DoneProperties;
813
import fr.lip6.move.gal.structural.DeadlockFound;
914
import fr.lip6.move.gal.structural.HLPlace;
15+
import fr.lip6.move.gal.structural.InvariantCalculator;
1016
import fr.lip6.move.gal.structural.NoDeadlockExists;
1117
import fr.lip6.move.gal.structural.PetriNet;
1218
import fr.lip6.move.gal.structural.Property;
@@ -15,6 +21,8 @@
1521
import fr.lip6.move.gal.structural.SparsePetriNet;
1622
import fr.lip6.move.gal.structural.expr.Expression;
1723
import fr.lip6.move.gal.structural.expr.Op;
24+
import fr.lip6.move.gal.structural.smt.DeadlockTester;
25+
import fr.lip6.move.gal.util.IntMatrixCol;
1826

1927
public class GlobalPropertySolver {
2028

@@ -146,17 +154,61 @@ public boolean solveProperty(String examination, MccTranslator reader) {
146154
if (reader.getHLPN() == null)
147155
buildProperties(examination, spn);
148156

149-
spn.simplifyLogic();
150-
spn.toPredicates();
151-
spn.testInInitial();
152-
spn.removeConstantPlaces();
153-
spn.removeRedundantTransitions(false);
154-
spn.removeConstantPlaces();
155-
spn.simplifyLogic();
156-
if (isSafe) {
157-
spn.assumeOneSafe();
157+
try {
158+
spn.simplifyLogic();
159+
spn.toPredicates();
160+
if (spn.testInInitial() > 0) {
161+
ReachabilitySolver.checkInInitial(spn, doneProps);
162+
}
163+
spn.removeConstantPlaces();
164+
spn.removeRedundantTransitions(false);
165+
spn.removeConstantPlaces();
166+
spn.simplifyLogic();
167+
if (isSafe) {
168+
spn.assumeOneSafe();
169+
}
170+
ReachabilitySolver.checkInInitial(spn, doneProps);
171+
} catch (GlobalPropertySolverException e) {
172+
return true;
158173
}
159-
174+
175+
if (ONE_SAFE.equals(examination) && reader.getHLPN() == null) {
176+
List<Expression> toCheck = new ArrayList<>(spn.getPlaceCount());
177+
List<Integer> maxStruct = new ArrayList<>(spn.getPlaceCount());
178+
List<Integer> maxSeen = new ArrayList<>(spn.getPlaceCount());
179+
for (int pid=0,e=spn.getPlaceCount() ; pid < e ; pid++) {
180+
toCheck.add(Expression.var(pid));
181+
maxStruct.add(-1);
182+
maxSeen.add(1);
183+
}
184+
// the invariants themselves
185+
Set<SparseIntArray> invar ;
186+
{
187+
// effect matrix
188+
IntMatrixCol sumMatrix = IntMatrixCol.sumProd(-1, spn.getFlowPT(), 1, spn.getFlowTP());
189+
invar = InvariantCalculator.computePInvariants(sumMatrix, spn.getPnames());
190+
}
191+
192+
long time = System.currentTimeMillis();
193+
UpperBoundsSolver.approximateStructuralBoundsUsingInvariants(spn, invar, toCheck, maxStruct);
194+
195+
int d=0;
196+
for (int pid=spn.getPlaceCount()-1 ; pid >= 0 ; pid--) {
197+
if (maxStruct.get(pid) == 1) {
198+
doneProps.put("place_"+pid, true, "STRUCTURAL INVARIANTS");
199+
maxStruct.remove(pid);
200+
maxSeen.remove(pid);
201+
toCheck.remove(pid);
202+
d++;
203+
}
204+
}
205+
Logger.getLogger("fr.lip6.move.gal").info("Rough structural analysis with invriants proved " + d + " places are one safe in " + (System.currentTimeMillis() - time) + " ms.");
206+
207+
DeadlockTester.testOneSafeWithSMT(toCheck, spn, invar, doneProps, solverPath, isSafe, 10);
208+
209+
spn.getProperties().removeIf(p->doneProps.containsKey(p.getName()));
210+
}
211+
160212
// vire les prop triviales, utile ?
161213
if (!spn.getProperties().isEmpty()) {
162214
try {
@@ -170,21 +222,21 @@ public boolean solveProperty(String examination, MccTranslator reader) {
170222
}
171223
}
172224

173-
spn.getProperties().removeIf(p -> ! doneProps.containsKey(p.getName()));
225+
spn.getProperties().removeIf(p -> doneProps.containsKey(p.getName()));
174226

175227
if (!spn.getProperties().isEmpty()) {
176228
System.out.println("Unable to solve all queries for examination "+examination + ". Remains :"+ spn.getProperties().size() + " assertions to prove.");
177229
return false;
178230
} else {
179231
System.out.println("Able to resolve query "+examination+ " after proving " + doneProps.size() + " properties.");
180-
}
181-
boolean success = isSuccess(doneProps, examination);
182-
if (success)
183-
System.out.println("FORMULA " + examination + " TRUE TECHNIQUES " + doneProps.computeTechniques());
184-
else
185-
System.out.println("FORMULA " + examination + " FALSE TECHNIQUES " + doneProps.computeTechniques());
232+
boolean success = isSuccess(doneProps, examination);
233+
if (success)
234+
System.out.println("FORMULA " + examination + " TRUE TECHNIQUES " + doneProps.computeTechniques());
235+
else
236+
System.out.println("FORMULA " + examination + " FALSE TECHNIQUES " + doneProps.computeTechniques());
186237

187-
return true;
238+
return true;
239+
}
188240
}
189241

190242
private void buildProperties(String examination, PetriNet spn) {

pnmcc/fr.lip6.move.gal.application.pnmcc/src/fr/lip6/move/gal/application/LTLPropertySolver.java

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.Set;
88
import java.util.concurrent.TimeoutException;
99

10+
import android.util.SparseIntArray;
1011
import fr.lip6.ltl.tgba.AcceptedRunFoundException;
1112
import fr.lip6.ltl.tgba.EmptyProductException;
1213
import fr.lip6.ltl.tgba.LTLException;
@@ -19,6 +20,7 @@
1920
import fr.lip6.move.gal.structural.SparsePetriNet;
2021
import fr.lip6.move.gal.structural.StructuralReduction;
2122
import fr.lip6.move.gal.structural.StructuralReduction.ReductionType;
23+
import fr.lip6.move.gal.structural.expr.AtomicProp;
2224
import fr.lip6.move.gal.structural.expr.Expression;
2325
import fr.lip6.move.gal.structural.expr.Op;
2426
import fr.lip6.move.gal.structural.smt.DeadlockTester;
@@ -174,48 +176,74 @@ public void runStutteringLTLTest(MccTranslator reader, DoneProperties doneProps,
174176
private TGBA applyKnowledgeBasedReductions(ISparsePetriNet spn, TGBA tgba, boolean isSafe) {
175177

176178
// cheap knowledge
179+
List<Expression> knowledge = new ArrayList<>();
177180

181+
addConvergenceKnowledge(knowledge, spn, tgba, isSafe);
182+
183+
addInitialStateKnowledge(knowledge, spn, tgba);
184+
185+
System.out.println("Knowledge obtained : " + knowledge);
186+
187+
// try to reduce the tgba using this knowledge
188+
SpotRunner sr = new SpotRunner(spotPath, workDir, 10);
189+
190+
191+
for (Expression factoid : knowledge) {
192+
String ltl = sr.printLTLProperty(factoid);
193+
TGBA prod = sr.computeProduct(tgba, ltl);
194+
if (prod.getEdges().get(prod.getInitial()).size() == 0) {
195+
// this is just false !
196+
System.out.println("Property proved to be true thanks to knowledge :" + factoid);
197+
return prod;
198+
} else if (prod.getProperties().contains("stutter-invariant") && ! tgba.getProperties().contains("stutter-invariant")) {
199+
System.out.println("Adopting stutter invariant property thanks to knowledge :" + factoid);
200+
tgba = prod;
201+
} else if (prod.getAPs().size() < tgba.getAPs().size()) {
202+
System.out.println("Adopting property with smaller alphabet thanks to knowledge :" + factoid);
203+
tgba = prod;
204+
}
205+
}
206+
207+
return tgba;
208+
209+
}
210+
211+
private void addInitialStateKnowledge(List<Expression> knowledge, ISparsePetriNet spn, TGBA tgba) {
212+
SparseIntArray init = new SparseIntArray(spn.getMarks());
213+
for (AtomicProp ap : tgba.getAPs()) {
214+
if (ap.getExpression().eval(init) == 1) {
215+
knowledge.add(Expression.apRef(ap));
216+
} else {
217+
knowledge.add(Expression.not(Expression.apRef(ap)));
218+
}
219+
}
220+
}
221+
222+
private void addConvergenceKnowledge(List<Expression> knowledge, ISparsePetriNet spn, TGBA tgba, boolean isSafe) {
178223
// we are SCC free hence structurally we will meet a deadlock in all traces
179224
// hence we must be accepted in one of these states, and they are by definition stuttering
180225
boolean allPathsAreDead = testAFDead (spn);
181226

182227
if (allPathsAreDead) {
183228
System.out.println("Detected that all paths lead to deadlock. Applying this knowledge to assert that all AP eventually converge : F ( (Ga|G!a) & (Gb|G!b)...)");
184229

185-
boolean [] results = DeadlockTester.testAPInDeadlocksWithSMT(spn, tgba.getAPs(), solverPath, isSafe);
186-
187-
List<Expression> knowledge = new ArrayList<>();
230+
boolean [] results = DeadlockTester.testAPInDeadlocksWithSMT(spn, tgba.getAPs(), solverPath, isSafe);
188231

189232
// build expressions : G p | G !p
190233
// for each ap "p", but remove bad values eliminated through SMT
191234
for (int i=0,ie=tgba.getAPs().size() ; i < ie ; i++) {
192235
boolean posExist = results[i];
193236
boolean negExist = results[i+1];
194-
knowledge.add(Expression.op(Op.OR,
237+
knowledge.add(
238+
Expression.op(Op.F,
239+
Expression.op(Op.OR,
195240
posExist ? Expression.op(Op.G, Expression.apRef(tgba.getAPs().get(i)), null): Expression.constant(false),
196-
negExist ? Expression.op(Op.G, Expression.not(Expression.apRef(tgba.getAPs().get(i))),null): Expression.constant(false)));
241+
negExist ? Expression.op(Op.G, Expression.not(Expression.apRef(tgba.getAPs().get(i))),null): Expression.constant(false)),null));
197242
if (!posExist && ! negExist) {
198243
System.out.println("Strange error detected, AP can be neither true nor false in deadlock.");
199244
}
200245
}
201-
202-
System.out.println("Knowledge obtained : " + knowledge);
203-
204-
205-
// try to reduce the tgba using this knowledge
206-
SpotRunner sr = new SpotRunner(spotPath, workDir, 10);
207-
208-
for (Expression factoid : knowledge) {
209-
String ltl = sr.printLTLProperty(factoid);
210-
TGBA prod = sr.computeProduct(tgba, ltl);
211-
if (prod.getEdges().get(prod.getInitial()).size() == 0) {
212-
// this is just false !
213-
return prod;
214-
}
215-
}
216246
}
217-
return tgba;
218-
219247
}
220248

221249
private boolean testAFDead(ISparsePetriNet spn) {

0 commit comments

Comments
 (0)