Search in sources :

Example 41 with Expression

use of com.sri.ai.expresso.api.Expression in project aic-expresso by aic-sri-international.

the class Conjunction method addNTimes.

@Override
public Expression addNTimes(Expression value, Expression n, Context context) {
    Expression result;
    if (value.equals(TRUE) || n.equals(ZERO)) {
        result = TRUE;
    } else if (n.getValue() instanceof Number) {
        // we already know value is not true and n is greater than zero from the previous condition having failed
        result = FALSE;
    } else // n is a symbolic value, so now it all depends on its being greater than zero
    if (IfThenElse.isIfThenElse(n)) {
        Expression condition = IfThenElse.condition(n);
        Expression thenBranch = IfThenElse.thenBranch(n);
        Expression elseBranch = IfThenElse.elseBranch(n);
        Expression newThenBranch = addNTimes(value, thenBranch, context);
        Expression newElseBranch = addNTimes(value, elseBranch, context);
        // do not simplify to condition so it is a DPLL solution
        result = IfThenElse.make(condition, newThenBranch, newElseBranch, false);
    } else {
        // it will only be true if n is zero
        result = apply(EQUAL, n, Expressions.ZERO);
    }
    return result;
}
Also used : Expression(com.sri.ai.expresso.api.Expression)

Example 42 with Expression

use of com.sri.ai.expresso.api.Expression in project aic-expresso by aic-sri-international.

the class CommutativeAssociative method make.

/**
	 * Similar to {@link Expressions#apply(Object, Object...)},
	 * but makes a simplified function application of an associative commutative operator,
	 * that is, its application but for the cases in which there are no arguments, or a single argument.
	 * When there are no arguments, a given neutral element value is returned.
	 * When a single argument is provided, it is returned itself.
	 * @param isIdempotent TODO
	 */
public static Expression make(Object functor, List<Expression> arguments, Expression neutralElement, boolean isIdempotent) {
    Predicate<Expression> notEqualToNeutralElement = Predicates.not(new Equals<Expression>(neutralElement));
    arguments = Util.collectToList(arguments, notEqualToNeutralElement);
    if (isIdempotent) {
        Set<Expression> argumentsSet = new LinkedHashSet<Expression>(arguments);
        arguments = new ArrayList<Expression>(argumentsSet);
    }
    if (arguments.isEmpty()) {
        return Expressions.wrap(neutralElement);
    }
    if (arguments.size() == 1) {
        return arguments.get(0);
    }
    Expression result = Expressions.makeExpressionOnSyntaxTreeWithLabelAndSubTrees(Expressions.wrap(functor), arguments);
    result = Associative.associateWhenSureOperatorIsAssociative(result);
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Expression(com.sri.ai.expresso.api.Expression)

Example 43 with Expression

use of com.sri.ai.expresso.api.Expression in project aic-expresso by aic-sri-international.

the class CommutativeAssociative method apply.

@Override
public Expression apply(Expression expression, Context context) {
    if (!expression.hasFunctor(getFunctor())) {
        return expression;
    }
    if (!isExtensional(expression)) {
        return expression;
    }
    List<Expression> arguments = expression.getArguments();
    if (arguments.isEmpty()) {
        return getNeutralElementExpression();
    }
    if (arguments.size() == 1) {
        return expression.get(0);
    }
    LinkedList<Expression> operableArguments = new LinkedList<Expression>();
    LinkedList<Expression> nonOperableArguments = new LinkedList<Expression>();
    int indexOfFirstOperable = Util.collect(arguments, operableArguments, getIsOperableArgumentExpressionPredicate(), nonOperableArguments);
    if (operableArguments.size() == 0) {
        // everything is an non-operable argument, nothing that can be done.
        return expression;
    }
    if (operableArguments.contains(getAbsorbingElement())) {
        return getAbsorbingElement();
    }
    // get result on operable arguments
    Expression resultOnOperableArgumentsExpression = operationOnOperableArguments(operableArguments);
    // a distinct but equal instance that would keep being re-evaluated by the same manipulator.
    if (operableArguments.size() == 1) {
        if (operableArguments.getFirst().equals(getNeutralElementExpression())) {
            // we don't need to include the neutral element, and are left with non-operable arguments only, done.
            Expression result = makeExpressionWithSameFunctorAsThis(nonOperableArguments);
            return result;
        } else {
            // the expression is formed by non-operable arguments and a single non-neutral operable argument, nothing else to do.
            return expression;
        }
    }
    // if there are no non-operable arguments, that's it.
    if (nonOperableArguments.size() == 0) {
        return resultOnOperableArgumentsExpression;
    }
    // if there are non-operable arguments, put them together with operables's result, unless this is the neutral element.
    // changing semantics, and therefore, for clarity, the name. It's ok to modify it since it's been created locally.
    LinkedList<Expression> argumentsOfResultingExpression = nonOperableArguments;
    if (!resultOnOperableArgumentsExpression.equals(getNeutralElement())) {
        argumentsOfResultingExpression.add(indexOfFirstOperable, resultOnOperableArgumentsExpression);
    }
    // return operation on result on operable and non-operable arguments.
    Expression result = makeExpressionWithSameFunctorAsThis(argumentsOfResultingExpression);
    return result;
}
Also used : Expression(com.sri.ai.expresso.api.Expression) LinkedList(java.util.LinkedList)

Example 44 with Expression

use of com.sri.ai.expresso.api.Expression in project aic-expresso by aic-sri-international.

the class CommutativeAssociative method make.

/**
	 * Makes a commutative associative application from arguments in an iterator's range.
	 * This is potentially efficient in that it will stop as soon as the result is determined
	 * when it finds an absorbing element.
	 * If the arguments are being computed on the fly (for example, the iterator is a UnaryFunctionIterator),
	 * this can save a lot of time.
	 */
public static Expression make(Object functor, Iterator<? extends Expression> argumentsIterator, Expression absorbingElement, Expression neutralElement, boolean isIdempotent) {
    absorbingElement = Expressions.wrap(absorbingElement);
    List<Expression> arguments = new LinkedList<Expression>();
    while (argumentsIterator.hasNext()) {
        Expression argument = argumentsIterator.next();
        if (argument.equals(absorbingElement)) {
            return absorbingElement;
        }
        if (!argument.equals(neutralElement)) {
            arguments.add(argument);
        }
    }
    Expression result = make(functor, arguments, neutralElement, isIdempotent);
    return result;
}
Also used : Expression(com.sri.ai.expresso.api.Expression) LinkedList(java.util.LinkedList)

Example 45 with Expression

use of com.sri.ai.expresso.api.Expression in project aic-expresso by aic-sri-international.

the class CommutativeAssociativeOnNumbers method dealWithInfinity.

/**
	 * If arguments of expression contain {@link Expressions#INFINITY} but not {@link Expressions#MINUS_INFINITY}, returns INFINITY;
	 * if they contain {@link Expressions#MINUS_INFINITY} but not {@link Expressions#INFINITY}, returns MINUS_INFINITY;
	 * if they contain both, throw an error
	 * if tye contain none, returns the result provided by provided fallback function
	 * @param expression
	 * @param context
	 * @param fallback
	 * @return
	 */
public static Expression dealWithInfinity(Expression expression, Context context, BinaryFunction<Expression, Context, Expression> fallback) {
    Expression result;
    boolean containsInfinity = thereExists(expression.getArguments(), EQUALS_INFINITY);
    boolean containsMinusInfinity = thereExists(expression.getArguments(), EQUALS_MINUS_INFINITY);
    if (containsInfinity) {
        if (containsMinusInfinity) {
            throw new Error(expression.getFunctor() + " undefined for application to both positive and negative infinity: " + expression);
        } else {
            result = INFINITY;
        }
    } else {
        if (containsMinusInfinity) {
            result = MINUS_INFINITY;
        } else {
            result = fallback.apply(expression, context);
        }
    }
    return result;
}
Also used : Expression(com.sri.ai.expresso.api.Expression)

Aggregations

Expression (com.sri.ai.expresso.api.Expression)1392 Test (org.junit.Test)259 ArrayList (java.util.ArrayList)196 Context (com.sri.ai.grinder.api.Context)187 Type (com.sri.ai.expresso.api.Type)124 TrueContext (com.sri.ai.grinder.core.TrueContext)113 IndexExpressionsSet (com.sri.ai.expresso.api.IndexExpressionsSet)100 ExtensionalIndexExpressionsSet (com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet)91 QuantifiedExpression (com.sri.ai.expresso.api.QuantifiedExpression)90 Context (com.sri.ai.grinder.sgdpllt.api.Context)87 Theory (com.sri.ai.grinder.api.Theory)78 Map (java.util.Map)78 LambdaExpression (com.sri.ai.expresso.api.LambdaExpression)71 IntensionalSet (com.sri.ai.expresso.api.IntensionalSet)68 List (java.util.List)68 DefaultLambdaExpression (com.sri.ai.expresso.core.DefaultLambdaExpression)63 CommonTheory (com.sri.ai.grinder.application.CommonTheory)55 LinkedHashMap (java.util.LinkedHashMap)55 LinkedHashSet (java.util.LinkedHashSet)54 Pair (com.sri.ai.util.base.Pair)52