/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.frontend.typechecker.locationtypes.infer; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.sat4j.maxsat.WeightedMaxSatDecorator; import org.sat4j.maxsat.reader.WDimacsReader; import org.sat4j.pb.IPBSolver; import org.sat4j.pb.OptToPBSATAdapter; import org.sat4j.reader.ParseFormatException; import org.sat4j.specs.ContradictionException; import org.sat4j.specs.IProblem; import org.sat4j.specs.TimeoutException; import abs.frontend.analyser.SemanticConditionList; import abs.frontend.typechecker.locationtypes.LocationType; public class SatGenerator { final Set<Constraint> constraints; final Set<LocationTypeVariable> vars; boolean enableStats = false; private boolean enableDebug = false; final List<List<Integer>> output; final Environment e; public SatGenerator(Set<Constraint> constraints) { this.constraints = constraints; initializeConstraints(); e = new Environment(); output = new ArrayList<List<Integer>>(); vars = new HashSet<LocationTypeVariable>(); } private void initializeConstraints() { for (LocationType lt : LocationType.ALLVISTYPES) { LocationTypeVariable cltv = LocationTypeVariable.getFromLocationType(lt); constraints.add(Constraint.declConstraint(cltv)); constraints.add(Constraint.constConstraint(cltv, lt, Constraint.MUST_HAVE)); } } public Map<LocationTypeVariable, LocationType> generate(SemanticConditionList s) { Map<LocationTypeVariable, LocationType> res = generate(); if (res == null) { s.add(new LocationInferenceError()); } return res; } public Map<LocationTypeVariable, LocationType> generate() { long startNanos = System.nanoTime(); Map<LocationTypeVariable, LocationType> tvl = new HashMap<LocationTypeVariable, LocationType>(); for (Constraint c : constraints) { if (enableDebug) System.out.println(c); List<List<Integer>> gen = c.generateSat(e); output.addAll(gen); c.variables(vars); } long genNanos = System.nanoTime(); if (enableStats) { System.out.println("Constraint generation time: " + (genNanos - startNanos) / 1000000); } StringBuilder weights = new StringBuilder(); int countNiceConstraints = 0; for (LocationTypeVariable tv : vars) { if (tv.getNode() != null) { countNiceConstraints++; weights.append(Constraint.NICE_TO_HAVE); weights.append(" "); weights.append(e.get(tv, LocationType.NEAR)); weights.append(" "); weights.append(e.get(tv, LocationType.FAR)); weights.append(" "); for (LocationType lt : tv.parametricFarTypes()) { weights.append(e.get(tv, lt)); weights.append(" "); } weights.append("0\n"); } } StringBuilder sb = new StringBuilder(); int nbclauses = output.size() + countNiceConstraints; int nbvars = e.current; addInitLine(sb,nbclauses,nbvars); // update should_have int newShouldHave = countNiceConstraints * Constraint.NICE_TO_HAVE + 1; for (List<Integer> line : output) { if (line.get(0).equals(Constraint.SHOULD_HAVE)) { line.set(0, newShouldHave); } } //System.out.println("SHOULD_HAVE value: "+ newShouldHave); try{ for (List<Integer> line : output) { for (Integer i : line) { sb.append(i); sb.append(" "); } sb.append("0\n"); } } catch (Exception e) { System.out.println(sb.length()); throw e; } sb.append(weights); if (enableStats) { System.out.println("Number of variables: " + nbvars); System.out.println("Number of clauses: " + nbclauses); } //System.out.println(sb); IPBSolver solver = org.sat4j.maxsat.SolverFactory.newDefault();//instance().defaultSolver(); //IPBSolver solver = org.sat4j.pb.SolverFactory.newBoth(); //System.exit(0); WeightedMaxSatDecorator wmsd = new WeightedMaxSatDecorator(solver); WDimacsReader reader = new WDimacsReader(wmsd); //System.out.println(sb.toString()); try { InputStream is = new ByteArrayInputStream(sb.toString().getBytes("UTF-8")); IProblem problem = reader.parseInstance(is); long parseNanos = System.nanoTime(); if (enableStats) { System.out.println("Parsing time: " + (parseNanos - genNanos) / 1000000); } if (enableStats) { System.gc(); try { Thread.sleep(1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.gc(); } OptToPBSATAdapter opt = new OptToPBSATAdapter(wmsd); opt.setVerbose(false); //opt.setTimeoutMs(10000); //parseNanos = System.nanoTime(); //opt.setTimeout(arg0) parseNanos = System.nanoTime(); if (opt.isSatisfiable()) { int[] model = opt.model(); long solveNanos = System.nanoTime(); if (enableStats) { System.out.println("Solving time: " + (solveNanos-parseNanos) / 1000000); System.out.println("Total time: " + (solveNanos-startNanos) / 1000000); } //int[] model = problem.model(); //model = problem.findModel(); //System.out.println("Model generated"); //problem.printInfos(new PrintWriter(System.out), "INFO: "); //System.out.println(Arrays.toString(model)); for (int i : model) { if (i > 0 /*&& i <= nbvars*/) { TypedVar tv = e.vars().get(i-1); //System.out.println(tv.v + " : " + tv.t); tvl.put(tv.v, tv.t); } } if (enableDebug) System.out.println("Solution: " + tvl); if (enableStats) { int fars = 0; int sws = 0; int nears = 0; int paramfars = 0; for (Entry<LocationTypeVariable, LocationType> e : tvl.entrySet()) { if (e.getKey().getNode() != null) { LocationType t = e.getValue(); if (t.isFar()) fars++; if (t.isParametricFar()) paramfars++; if (t.isNear()) nears++; if (t.isSomewhere()) sws++; } } System.out.println("Fars: " + fars); System.out.println("Somewheres: " + sws); System.out.println("Nears: " + nears); System.out.println("Parametric Fars: " + paramfars); System.out.println("Total: " + (fars + sws + nears + paramfars)); } } else { return null; } return tvl; } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParseFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ContradictionException e) { // TODO Auto-generated catch block //e.printStackTrace(); } catch (TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private void addInitLine(StringBuilder sb, int nbclauses, int nbvars) { sb.append("p wcnf "); sb.append(nbvars); sb.append(" "); sb.append(nbclauses); sb.append(" "); sb.append(Constraint.MUST_HAVE); sb.append("\n"); } }