All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.evosuite.symbolic.solver.Solver Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
 * contributors
 *
 * This file is part of EvoSuite.
 *
 * EvoSuite is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3.0 of the License, or
 * (at your option) any later version.
 *
 * EvoSuite is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with EvoSuite. If not, see .
 */
package org.evosuite.symbolic.solver;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.evosuite.symbolic.expr.Constraint;
import org.evosuite.symbolic.expr.ConstraintEvaluator;
import org.evosuite.symbolic.expr.Variable;
import org.evosuite.symbolic.expr.bv.IntegerVariable;
import org.evosuite.symbolic.expr.fp.RealVariable;
import org.evosuite.symbolic.expr.str.StringVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Interface for SMT solvers
 * 
 * @author Gordon Fraser
 */
public abstract class Solver {

	private final boolean addMissingVariables;

	protected boolean addMissingVariables() {
		return addMissingVariables;
	}

	public Solver() {
		addMissingVariables = false;
	}

	public Solver(boolean addMissingVariables) {
		this.addMissingVariables = addMissingVariables;
	}

	static Logger logger = LoggerFactory.getLogger(Solver.class);

	/**
	 * 
	 * @param constraints
	 *            a constraint system to be solved
	 * 
	 * @return a non-null result that is SAT or UNSAT
	 * @throws SolverTimeoutException
	 *             a timeout occurred while executing the solver
	 * @throws IOException
	 *             an IOException occurred while executing the solver
	 * @throws SolverParseException
	 *             the solver's result could not be parsed into a valid SolverResult
	 * @throws SolverEmptyQueryException
	 *             the solver
	 * @throws SolverErrorException
	 *             the solver reported an error after its execution
	 */
	public abstract SolverResult solve(Collection> constraints) throws SolverTimeoutException,
			IOException, SolverParseException, SolverEmptyQueryException, SolverErrorException;

	/**
	 * Returns a mapping from variables to their current concrete values.
	 * 
	 * @param variables
	 * @return a mapping from variables to their current concrete values.
	 */
	protected static Map getConcreteValues(Set> variables) {

		Map concrete_values = new HashMap();
		for (Variable v : variables) {
			String var_name = v.getName();
			Object concrete_value = v.getConcreteValue();
			concrete_values.put(var_name, concrete_value);
		}
		return concrete_values;
	}

	/**
	 * Creates a set with all the variables in the constraints.
	 * 
	 * @param constraints
	 *            the constraint system
	 * @return the set of variables in the constraint system
	 */
	protected static Set> getVariables(Collection> constraints) {
		Set> variables = new HashSet>();
		for (Constraint c : constraints) {
			variables.addAll(c.getLeftOperand().getVariables());
			variables.addAll(c.getRightOperand().getVariables());
		}
		return variables;
	}

	/**
	 * Restore all concrete values of the variables using the concrete_values
	 * mapping.
	 * 
	 * @param variables
	 * @param concrete_values
	 */
	protected static void setConcreteValues(Set> variables, Map concrete_values) {
		for (Variable v : variables) {

			String var_name = v.getName();

			if (!concrete_values.containsKey(var_name)) {
				continue;
			}

			Object concreteValue = concrete_values.get(var_name);

			if (v instanceof StringVariable) {
				StringVariable sv = (StringVariable) v;
				String concreteString = (String) concreteValue;
				sv.setConcreteValue(concreteString);
			} else if (v instanceof IntegerVariable) {
				IntegerVariable iv = (IntegerVariable) v;
				Long concreteInteger = (Long) concreteValue;
				iv.setConcreteValue(concreteInteger);
			} else if (v instanceof RealVariable) {
				RealVariable ir = (RealVariable) v;
				Double concreteReal = (Double) concreteValue;
				ir.setConcreteValue(concreteReal);
			} else {
				logger.warn("unknow variable type " + v.getClass().getName());
			}
		}
	}

	protected static boolean checkSAT(Collection> constraints, SolverResult satResult) {

		if (satResult == null) {
			throw new NullPointerException("satResult should be non-null");
		}

		if (!satResult.isSAT()) {
			throw new IllegalArgumentException("satResult should be SAT");
		}

		// back-up values
		Set> variables = getVariables(constraints);
		Map initialValues = getConcreteValues(variables);
		// set new values
		Map newValues = satResult.getModel();
		setConcreteValues(variables, newValues);

		try {
			// check SAT with new values
			ConstraintEvaluator evaluator = new ConstraintEvaluator();
			for (Constraint constraint : constraints) {
				Boolean evaluation = (Boolean) constraint.accept(evaluator, null);
				if (evaluation == null) {
					throw new NullPointerException();
				}
				if (evaluation == false) {
					return false;
				}
			}
			return true;
		} finally {
			// restore values
			setConcreteValues(variables, initialValues);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy