package org.matheclipse.core.generic;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
import javax.annotation.Nullable;
import org.matheclipse.core.eval.EvalEngine;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IEvaluator;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.interfaces.IPattern;
import org.matheclipse.core.interfaces.ISymbol;
import com.google.common.base.Predicate;
public class Predicates {
private Predicates() {
}
private static class InASTPredicate implements Predicate, Serializable {
private final IAST target;
private InASTPredicate(IAST target) {
this.target = checkNotNull(target);
}
public boolean apply(IExpr t) {
for (IExpr expr : target) {
if (expr.equals(t)) {
return true;
}
}
return false;
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof InASTPredicate) {
InASTPredicate that = (InASTPredicate) obj;
return target.equals(that.target);
}
return false;
}
@Override
public int hashCode() {
return target.hashCode();
}
@Override
public String toString() {
return "In(" + target + ")";
}
private static final long serialVersionUID = 0;
}
/**
* Check if the evaluation of an unary AST object gives True.
*
*/
private static class IsUnaryTrue implements Predicate {
protected final EvalEngine fEngine;
protected final IAST fAST;
/**
* Define an unary AST with the header head. The apply() method evaluates the cretaed AST with the
* given expression and checks if the result equals True.
*
* @param head
* the AST's head expresion
*/
public IsUnaryTrue(final IExpr head) {
this(EvalEngine.get(), head);
}
/**
* Define an unary AST with the header head.
*
* @param engine
* the evaluation engine
* @param head
* the AST's head expresion
*/
public IsUnaryTrue(final EvalEngine engine, final IExpr head) {
fEngine = EvalEngine.get();
fAST = F.ast(head, 1, false);
}
/**
* Check if the evaluation of an unary AST object gives True, by setting the first argument of the AST to
* arg.
*
*/
public boolean apply(final IExpr arg) {
final IAST ast = fAST.clone();
ast.add(arg);
return fEngine.evalTrue(ast);
}
}
/**
* Check if the evaluation of an unary AST object gives True.
*
* @param head
* @return
*/
public static Predicate isTrue(IExpr head) {
if (head.isSymbol()) {
IEvaluator eval = ((ISymbol) head).getEvaluator();
if (eval != null && (eval instanceof Predicate>)) {
return (Predicate) eval;
}
}
return new IsUnaryTrue(head);
}
/**
* Check if the evaluation of an unary AST object gives True.
*
* @param engine
* @param head
* @return
*/
public static Predicate isTrue(final EvalEngine engine, final IExpr head) {
if (head.isSymbol()) {
IEvaluator eval = ((ISymbol) head).getEvaluator();
if (eval != null && (eval instanceof Predicate>)) {
return (Predicate) eval;
}
}
return new IsUnaryTrue(engine, head);
}
/**
* Returns a predicate that evaluates to {@code true} if the object reference being tested is one of the arguments of the given
* ast. It does not defensively copy the collection passed in, so future changes to it will alter the behavior of
* the predicate.
*
* @param ast
* the AST those arguments may contain the function input
*/
public static Predicate in(IAST ast) {
return new InASTPredicate(ast);
}
/**
* Returns a predicate that evaluates to {@code true} if the object reference being tested is one of the arguments of the given
* ast. It does not defensively copy the collection passed in, so future changes to it will alter the behavior of
* the predicate.
*
* @param expr
* the expr which may macth the function input
*/
public static Predicate in(IExpr expr) {
return new InASTPredicate(F.List(expr));
}
/**
* Returns a predicate that evaluates to {@code true} if the input is an instanceof IPattern.
*
* @return
*/
public static Predicate isPattern() {
return new Predicate() {
@Override
public boolean apply(IExpr input) {
return (input instanceof IPattern);
}
};
}
/**
* Returns a predicate that evaluates to {@code true} if input.isNumber() gives {@code true}.
*
* @return
*/
public static Predicate isNumber() {
return new Predicate() {
@Override
public boolean apply(IExpr input) {
return input.isNumber();
}
};
}
/**
* Returns a predicate that evaluates to {@code true} if input.isNumeric() gives {@code true}.
*
* @return
*/
public static Predicate isNumeric() {
return new Predicate() {
@Override
public boolean apply(IExpr input) {
return input.isNumeric();
}
};
}
/**
* Returns a predicate that evaluates to {@code true} if input.isSignedNumber() gives {@code true}.
*
* @return
*/
public static Predicate isSignedNumber() {
return new Predicate() {
@Override
public boolean apply(IExpr input) {
return input.isSignedNumber();
}
};
}
/**
* Returns a predicate that evaluates to {@code true} if the input is an AST list, which contains one of the given
* header elements at index position 0.
*
*/
public static Predicate isAST(final ISymbol[] heads) {
return new Predicate() {
@Override
public boolean apply(IExpr input) {
for (int i = 0; i < heads.length; i++) {
if (input.isAST(heads[i])) {
return true;
}
}
return false;
}
};
}
}
Ads help maintain this website.