/******************************************************************************
* Copyright (c) 2009 - 2015 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
/**
*
*/
package com.ibm.wala.memsat;
import java.util.HashSet;
import java.util.Set;
import com.ibm.wala.memsat.concurrent.MemoryModel;
import com.ibm.wala.types.TypeReference;
import kodkod.engine.satlab.SATFactory;
/**
* Stores translation and analysis options for Miniatur.
*
* @specfield isContextSensitive: boolean // use context sensitive analysis to build call graphs? (default true)
* @specfield loopUnrollDepth: int // default 3
* @specfield openWorldScopeSize: int // the cardinality of each set of instances in the open world (default 4)
* @specfield numberOfIndexAtoms: int // number of atoms used for array indexing (default 10)
* @specfield recursionLimit: int // default 1
* @specfield primordialConcreteTypes: Set<TypeReference> // default int and String
* @specfield kodkodOptions: kodkod.engine.config.Options // options for the Kodkod engine (for defaults, see {@linkplain #Options()})
* @specfield memoryModel: MemoryModel // memory model used for analyzing concurrent programs (default is JMMAlt)
* @specfield assertsAreAssumptions: boolean // default is false
* @specified eclipseProjectName: String // the Eclipse project to analyze, if any. default is null.
* @author Emina Torlak
*/
public final class Options {
private boolean isContextSensitive,assertsAreAssumptions;
private int loopUnrollDepth, openWorldScopeSize, numberOfIndexAtoms, recursionLimit;
private TypeReference undefinedType;
private MemoryModel memoryModel;
private String eclipseProjectName;
private final Set<TypeReference> primordialConcreteTypes;
private final kodkod.engine.config.Options kodkodOptions;
/**
* Returns an Options instance initialized with default values.
* @effects
* this.isContextSensitive' = true and
* this.loopUnrollDepth' = 3 and
* this.openWorldScopeSize' = 4 and
* this.numberOfIndexAtoms' = 10 and
* this.recursionLimit' = 1 and
* this.primordialConcreteTypes' = {int, String} and
* this.kodkodOptions'.solver = SATFactory.MiniSAT and
* this.kodkodOptions'.bitwidth = 8 and
* this.memoryModel' = RelaxedModelFactory and
* this.assertsAreAssumptions = false
*/
public Options() {
this.isContextSensitive = true;
this.loopUnrollDepth = 3;
this.openWorldScopeSize = 4;
this.numberOfIndexAtoms = 10;
this.recursionLimit = 1;
this.primordialConcreteTypes = new HashSet<TypeReference>();
primordialConcreteTypes.add(TypeReference.JavaLangInteger);
primordialConcreteTypes.add(TypeReference.JavaLangString);
this.undefinedType = null;
this.kodkodOptions = new kodkod.engine.config.Options();
kodkodOptions.setBitwidth(8);
kodkodOptions.setSolver(SATFactory.MiniSat);
this.memoryModel = null;
this.assertsAreAssumptions = false;
this.eclipseProjectName = null;
}
/**
* Returns the value of isContextSensitive flag.
* @return this.isContextSensitive
*/
public boolean isContextSensitive() { return this.isContextSensitive; }
/**
* Sets the value of isContextSensitive flag.
* @return this.isContextSensitive' = isContextSensitive
*/
public void setContextSensitivity(boolean isContextSensitive) {
this.isContextSensitive = isContextSensitive;
}
/**
* @throws IllegalArgumentException - i !in [min..max]
*/
public void closedRangeCheck(int i, int min, int max) {
if (i < min || i > max)
throw new IllegalArgumentException(i + " must be in [" + min + ".." + max + "]");
}
/**
* Returns theloop unrolling depth.
* @return this.loopUnrollDepth
*/
public int loopUnrollDepth() { return loopUnrollDepth; }
/**
* Sets the loop unrolling depth.
* @return this.loopUnrollDepth' = depth
* @throws IllegalArgumentException - depth <= 0
*/
public void setloopUnrollDepth(int depth) {
closedRangeCheck(depth, 1, Integer.MAX_VALUE);
this.loopUnrollDepth = depth;
}
/**
* Return open world scope size. This number is the lower bound the cardinality of a
* set of instances in the open world, as determined by pointer analysis.
* For example, if a concrete class C has two sets of disjoint instances
* that reach into the open world, then each of those sets is guaranteed to
* be represented with at least this.openWorldScopeSize atoms.
* @return this.openWorldScopeSize
*/
public int openWorldScopeSize() { return openWorldScopeSize; }
/**
* Sets theopen world scope size.
* @return this.openWorldScopeSize' = size
* @throws IllegalArgumentException - size < 0
*/
public void setOpenWorldScopeSize(int size) {
closedRangeCheck(size, 0, Integer.MAX_VALUE);
this.openWorldScopeSize = size;
}
/**
* Returns the number of index atoms.
* @return this.numberOfIndexAtoms
*/
public int numberOfIndexAtoms() { return numberOfIndexAtoms; }
/**
* Sets the number of index atoms.
* @requires 0 <= atoms <= this.kodkodOptions.integers().max()
* @return this.numberOfIndexAtoms' = atoms
* @throws IllegalArgumentException - atoms < 0
*/
public void setNumberOfIndexAtoms(int atoms) {
closedRangeCheck(atoms, 0, kodkodOptions.integers().max());
this.numberOfIndexAtoms = atoms;
}
/**
* Returns the recursion limit.
* @return this.recursionLimit
*/
public int recursionLimit() { return recursionLimit; }
/**
* Sets the recursion limit.
* @return this.recursionLimit' = limit
* @throws IllegalArgumentException - limit <= 0
*/
public void setRecursionLimit(int limit) {
closedRangeCheck(limit, 1, Integer.MAX_VALUE);
this.recursionLimit = limit;
}
/**
* Returns the (modifiable) kodkod options. Note that
* modifying the bitwidth field of the returned object
* will modify this.numberOfContexts, if necessary, so
* that it's never larger than this.kodkodOptions.integers().max().
* @return this.kodkodOptions
*/
public kodkod.engine.config.Options kodkodOptions() {
return kodkodOptions;
}
/**
* Returns the primordial concrete types (modifiable).
* @return this.primordialConcreteTypes
*/
public Set<TypeReference> primordialConcreteTypes() {
return primordialConcreteTypes;
}
/**
* Returns the undefined type.
* @return this.undefinedType
*/
public TypeReference undefinedType() {
return undefinedType;
}
/**
* Sets the undefined type.
* @effects this.undefinedType' = undefined
*/
public void setUndefinedType(TypeReference undefined) {
this.undefinedType = undefined;
}
/**
* Returns the memory model used for analysis of concurrent code.
* @return this.memoryModel
*/
public MemoryModel memoryModel() {
return memoryModel;
}
/**
* Sets the memory model used for analysis of concurrent code.
* @effects this.memoryModel' = memoryModel
* @throws NullPointerException - memoryModel = null
*/
public void setMemoryModel(MemoryModel memoryModel) {
this.memoryModel = memoryModel;
}
/**
* Returns true if the assert statements in code should be handled as
* assumptions instead of assertions. The default is false.
* @return this.assertsAreAssumptions
*/
public boolean assertsAreAssumptions() { return assertsAreAssumptions; }
/**
* Sets the flag for handling the translation of assert statements.
* @effects this.assertsAreAssumptions' = assertsAreAssumptions
*/
public void setAssertsAreAssumptions(boolean assertsAreAssumptions) {
this.assertsAreAssumptions = assertsAreAssumptions;
}
public String getEclipseProjectName() {
return eclipseProjectName;
}
public void setEclipseProjectName(String eclipseProjectName) {
this.eclipseProjectName = eclipseProjectName;
}
/**
* Returns a string view of these options.
* @return a string view of these options.
*/
public String toString() {
final StringBuilder s = new StringBuilder();
s.append("Options:\n");
s.append(" loopUnrollDepth: " + loopUnrollDepth + "\n");
s.append(" openWorldScopeSize: " + openWorldScopeSize + "\n");
s.append(" numberOfIndexAtoms: " + numberOfIndexAtoms + "\n");
s.append(" recursionLimit: " + recursionLimit + "\n");
s.append(" primordialConcreteTypes: " + primordialConcreteTypes + "\n");
s.append(" undefinedType: " + undefinedType + "\n");
s.append(" kodkodOptions: " + kodkodOptions + "\n");
s.append(" memoryModel: " + memoryModel + "\n");
s.append(" assertsAreAssumptions: " + assertsAreAssumptions + "\n");
return s.toString();
}
}