Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2013, SRI International
* All rights reserved.
* Licensed under the The BSD 3-Clause License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://opensource.org/licenses/BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the aic-expresso nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sri.ai.grinder.sgdpllt.library.boole;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.AND;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.DISEQUALITY;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.EQUALITY;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.EQUIVALENCE;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.IMPLICATION;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.NOT;
import static com.sri.ai.grinder.sgdpllt.library.FunctorConstants.OR;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.google.common.annotations.Beta;
import com.google.common.collect.Lists;
import com.sri.ai.expresso.api.Expression;
import com.sri.ai.expresso.api.FunctionApplication;
import com.sri.ai.expresso.helper.Expressions;
import com.sri.ai.grinder.sgdpllt.library.Equality;
/**
* A collection of utility routines related to handling boolean expressions.
*
* @author saadati
*
*/
@Beta
public class BooleanUtil {
/**
*
* @param expression
* @return removes any duplicates from expression
*/
public static Expression removeUnnecessary(Expression expression) {
if (expression.getSyntacticFormType().equals(FunctionApplication.SYNTACTIC_FORM_TYPE)) {
Expression functor = expression.getFunctor();
if ( And.isConjunction(expression) || Or.isDisjunction(expression) ) {
boolean isConjunction = And.isConjunction(expression);
List arguments = expression.getArguments();
ArrayList newArguments = new ArrayList();
for (Expression arg: arguments) {
if ( (isConjunction && arg.equals(Expressions.TRUE)) || (!isConjunction && arg.equals(Expressions.FALSE)) ) {
continue;
}
boolean isDuplicate = false;
Expression arg2 = removeUnnecessary(arg);
for (Expression nArg: newArguments) {
if ( areEquivalent(arg2, nArg) ) {
isDuplicate = true;
break;
}
}
if ( !isDuplicate ) {
newArguments.add(arg2);
}
}
if ( newArguments.size() == 1 ) {
return newArguments.get(0);
}
else {
return Expressions.makeExpressionOnSyntaxTreeWithLabelAndSubTrees(functor, newArguments);
}
}
else if ( functor.equals(NOT) ) {
return Expressions.apply(functor, removeUnnecessary(expression.get(0)));
}
}
return expression;
}
private static boolean areEquivalent(Expression literal1, Expression literal2) {
if ( literal1.hasFunctor(NOT) ) {
if ( literal2.hasFunctor(NOT) ) {
return areEquivalent(literal1.get(0), literal2.get(0));
}
else if ( literal2.hasFunctor(DISEQUALITY) ) {
return areEquivalent(literal1.get(0), Expressions.apply(EQUALITY, literal2.get(0), literal2.get(1)));
}
}
else if ( literal2.hasFunctor(NOT) ) {
if ( literal1.hasFunctor(DISEQUALITY) ) {
return areEquivalent(literal2.get(0), Expressions.apply(EQUALITY, literal1.get(0), literal1.get(1)));
}
}
else if ( literal1.hasFunctor(DISEQUALITY) && literal2.hasFunctor(DISEQUALITY) ) {
return pairwiseEquivalent(literal1.get(0), literal1.get(1), literal2.get(0), literal2.get(1));
}
else if ( literal1.hasFunctor(EQUALITY) && literal2.hasFunctor(EQUALITY) ) {
for (Expression term1: literal1.getArguments()) {
boolean conjunction = true;
for (Expression term2: literal2.getArguments()) {
conjunction = conjunction && term1.equals(term2);
if ( !conjunction ) {
break;
}
}
if ( conjunction ) {
return true;
}
}
// return pairwiseEquivalent(literal1.get(0), literal1.get(1), literal2.get(0), literal2.get(1));
}
return false;
}
private static boolean pairwiseEquivalent(Expression x1, Expression y1, Expression x2, Expression y2) {
return (x1.equals(x2) && y1.equals(y2)) || (x1.equals(y2) && y1.equals(x2));
}
/**
*
* @param expression
* @return true if expression is of the form "x=y" or "not (x != y)"
*/
public static boolean isEquality(Expression expression) {
return (expression.hasFunctor(EQUALITY) && expression.getArguments().size() == 2) ||
(expression.hasFunctor(NOT) && isNotEquality(expression.get(0)));
}
/**
*
* @param expression
* @return true if expression is of the form x=y=...=z"
*/
public static boolean isMultiEquality(Expression expression) {
return (expression.hasFunctor(EQUALITY) && expression.getArguments().size()>2);
}
public static Expression expandMultiEquality(Expression expression, Expression mainVar) {
Expression result = expression;
if ( isMultiEquality(expression) && expression.getArguments().contains(mainVar) ) {
ArrayList newEqualities = new ArrayList();
for (Expression var: expression.getArguments()) {
if ( !var.equals(mainVar) ) {
Expression newEq = Equality.make(mainVar, var);
newEqualities.add(newEq);
}
}
result = And.make(newEqualities);
}
return result;
}
/**
*
* @param expression
* @return true if expression is either an equality or a disequality
*/
public static boolean isLiteral(Expression expression) {
return isEquality(expression) || isNotEquality(expression);
}
/**
*
* @param expression
* @return true if expression is either of the form "x=y" or "not (x != y)"
*/
public static boolean isNotEquality(Expression expression) {
return (expression.hasFunctor(NOT) && isEquality(expression.get(0))) || expression.hasFunctor(DISEQUALITY);
}
/**
*
* @param expression
* @return true if expression is a conjunction
*/
public static boolean isConjunction(Expression expression) {
return expression.hasFunctor(AND);
}
/**
*
* @param expression
* @return true if expression is a disjunction
*/
public static boolean isDisjunction(Expression expression) {
return expression.hasFunctor(OR);
}
/**
*
* @param expression
* @return true if expression is an implication
*/
public static boolean isImplication(Expression expression) {
return expression.hasFunctor(IMPLICATION);
}
/**
*
* @param expression
* @return true if expression is an Equivalence
*/
public static boolean isEquivalence(Expression expression) {
return expression.hasFunctor(EQUIVALENCE);
}
/**
*
* @param expression
* @return true if expression is a disjunction
*/
public static boolean isNegation(Expression expression) {
return expression.hasFunctor(NOT);
}
/**
*
* @param expression
* @param element
* @return true if element occurs in expression
*/
public static boolean occurs(Expression expression, Expression element) {
return Expressions.containsAnyOfGivenCollectionAsSubExpression(expression, Lists.newArrayList(element));
}
public static Set getTerms(Expression expression) {
Set set = new LinkedHashSet();
if ( expression.hasFunctor(EQUALITY) || expression.hasFunctor(DISEQUALITY) ) {
set.add(expression.get(0));
set.add(expression.get(1));
}
else if ( expression.hasFunctor(NOT) ) {
set.addAll(getTerms(expression.get(0)));
}
else if ( expression.hasFunctor(OR) || expression.hasFunctor(AND) || expression.hasFunctor(IMPLICATION)) {
for (Expression arg: expression.getArguments()) {
set.addAll(getTerms(arg));
}
}
return set;
}
}