package org.matheclipse.core.builtin.function;
import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractCoreFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;
import org.matheclipse.core.patternmatching.IPatternMatcher;
import org.matheclipse.core.patternmatching.PatternMatcher;
public class FreeQ extends AbstractCoreFunctionEvaluator {
public FreeQ() {
}
public IExpr evaluate(final IAST ast) {
Validate.checkSize(ast, 3);
IExpr arg1 = F.eval(ast.arg1());
IExpr arg2 = F.eval(ast.arg2());
final IPatternMatcher matcher = new PatternMatcher(arg2);
if (matcher.isRuleWithoutPatterns()) {
// special for FreeQ(), don't implemented in MemberQ()!
if (arg1.isOrderlessAST() && arg2.isOrderlessAST() && arg1.head().equals(arg2.head())) {
if (!isFreeOrderless((IAST) arg1, (IAST) arg1)) {
return F.False;
}
}
}
return F.bool(arg1.isFree(matcher, true));
}
/**
* Checks if orderless1.size() is greaterequal orderless2.size() and returns false, if
* every argument in orderless2 equals an argument in orderless1. I.e. orderless1
* doesn't contain every argument of orderless2.
*
* @param orderless1
* @param orderless2
* @return false if orderless1.size() is greaterequal orderless2.size() and if every
* argument in orderless2 equals an argument in orderless1
*/
public boolean isFreeOrderless(IAST orderless1, IAST orderless2) {
if (orderless1.size() >= orderless2.size()) {
IExpr temp;
boolean evaled = false;
int[] array = new int[orderless1.size()];
for (int i = 1; i < orderless2.size(); i++) {
temp = orderless2.get(i);
evaled = false;
for (int j = 1; j < orderless1.size(); j++) {
if (array[j] != (-1) && temp.equals(orderless1.get(j))) {
array[j] = -1;
evaled = true;
break;
}
}
if (!evaled) {
break;
}
}
if (evaled) {
return false;
}
}
return true;
}
}
Ads help maintain this website.