use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.
the class TupleValuedFreeVariablesSimplifier method createReverseLookupMap.
private static Map<Expression, Pair<Expression, Integer>> createReverseLookupMap(Map<Expression, List<Pair<Expression, Integer>>> freeVariableComponentsMap) {
Map<Expression, Pair<Expression, Integer>> result = new LinkedHashMap<>();
for (Map.Entry<Expression, List<Pair<Expression, Integer>>> freeVariableComponents : freeVariableComponentsMap.entrySet()) {
Expression freeVariable = freeVariableComponents.getKey();
for (Pair<Expression, Integer> component : freeVariableComponents.getValue()) {
Expression componentVariable = component.first;
Integer componentIndex = component.second;
result.put(componentVariable, new Pair<>(freeVariable, componentIndex));
}
}
return result;
}
use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.
the class TupleValuedFreeVariablesSimplifier method extendContextWithComponentVariables.
private static Context extendContextWithComponentVariables(Context context, Map<Expression, TupleType> freeVariablesOfTupleType, Map<Expression, List<Pair<Expression, Integer>>> freeVariableComponentsMap) {
Map<String, String> mapFromSymbolNameToTypeName = new LinkedHashMap<>();
Set<Type> componentTypes = new LinkedHashSet<>();
for (Map.Entry<Expression, TupleType> freeVariableOfTupleType : freeVariablesOfTupleType.entrySet()) {
Expression freeVariable = freeVariableOfTupleType.getKey();
TupleType freeVariableTupleType = freeVariableOfTupleType.getValue();
componentTypes.addAll(freeVariableTupleType.getElementTypes());
List<Pair<Expression, Integer>> components = freeVariableComponentsMap.get(freeVariable);
for (Pair<Expression, Integer> freeVariableComponent : components) {
Expression freeVariableComponentVar = freeVariableComponent.first;
Type freeVariableComponentType = freeVariableTupleType.getElementTypes().get(freeVariableComponent.second - 1);
mapFromSymbolNameToTypeName.put(freeVariableComponentVar.toString(), freeVariableComponentType.getName());
}
}
Context result = (Context) GrinderUtil.extendRegistryWith(mapFromSymbolNameToTypeName, componentTypes, context);
return result;
}
use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.
the class IndexExpressions method getIndexAndDomain.
public static Pair<Expression, Expression> getIndexAndDomain(Expression indexExpression) {
boolean bothIndexAndDomain = indexExpression.hasFunctor("in") && indexExpression.numberOfArguments() == 2;
Expression index;
Expression indexDomain;
if (bothIndexAndDomain) {
index = indexExpression.get(0);
indexDomain = indexExpression.get(1);
} else {
index = indexExpression;
indexDomain = type(index);
}
return new Pair<Expression, Expression>(index, indexDomain);
}
use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.
the class DefaultPolynomial method divide.
@Override
public Pair<Polynomial, Polynomial> divide(Polynomial divisor) throws IllegalArgumentException {
assertSameVariables(divisor);
Pair<Polynomial, Polynomial> result;
if (isZero()) {
// 0 / divisor = 0
result = new Pair<>(this, this);
} else // Base case
if (isMonomial() && divisor.isMonomial()) {
Pair<Monomial, Monomial> monomialQuotientAndRemainder = asMonomial().divide(divisor.asMonomial());
result = new Pair<>(makeFromMonomial(monomialQuotientAndRemainder.first, getVariables()), makeFromMonomial(monomialQuotientAndRemainder.second, getVariables()));
} else if (divisor.isNumericConstant()) {
// In this case do not need to worry about remainders as can always
// divide using a numeric constant divisor.
Monomial monomialDivisor = divisor.asMonomial();
List<Monomial> quotients = new ArrayList<>();
for (Monomial term : getMonomials()) {
Pair<Monomial, Monomial> monomialQuotientAndRemainder = term.divide(monomialDivisor);
if (!monomialQuotientAndRemainder.second.isZero()) {
throw new IllegalStateException("Got an unexpected remainder from " + term + " / " + divisor);
}
quotients.add(monomialQuotientAndRemainder.first);
}
result = new Pair<>(new DefaultPolynomial(quotients, getVariables()), makeFromMonomial(DefaultMonomial.ZERO, getVariables()));
} else {
// Univariate case
if (getVariables().size() == 1) {
// TODO - implement faster synthetic division version
// see: https://en.wikipedia.org/wiki/Synthetic_division
// Perform Polynomial Long Division
Polynomial quotient = makeFromMonomial(DefaultMonomial.ZERO, getVariables());
Polynomial remainder = this;
Monomial leadingDivisorTerm = divisor.getMonomials().get(0);
do {
Monomial leadingNumeratorTerm = remainder.getMonomials().get(0);
Pair<Monomial, Monomial> monomialQuotientAndRemainder = leadingNumeratorTerm.divide(leadingDivisorTerm);
if (!monomialQuotientAndRemainder.second.isZero()) {
// Could not divide, i.e. have a remainder
break;
}
Polynomial monomialQuotient = makeFromMonomial(monomialQuotientAndRemainder.first, getVariables());
quotient = quotient.add(monomialQuotient);
remainder = remainder.minus(divisor.times(monomialQuotient));
} while (!remainder.isZero());
result = new Pair<>(quotient, remainder);
} else {
// TODO - Multivariate case, currently not supported
// See: https://en.wikipedia.org/wiki/Gr%C3%B6bner_basis
// for generalization of long division to the multivariate case.
result = new Pair<>(makeFromMonomial(DefaultMonomial.ZERO, getVariables()), this);
}
}
return result;
}
use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.
the class AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver method makeLowerBoundsAndStrictness.
/**
* A method setting {@link #lowerBoundsIncludingImplicitOnes} and {@link #fromLowerBoundsIncludingImplicitOnesToStrictness}
* from constraint and variable's type.
* @param context
*/
protected void makeLowerBoundsAndStrictness(Context context) {
AbstractSingleVariableConstraint abstractSingleVariableConstraint = (AbstractSingleVariableConstraint) constraint;
FunctionIterator<Expression, Pair<Expression, Boolean>> lowerBoundsAndStrictnessFromPositiveNormalizedAtomsIterator = functionIterator(predicateIterator(abstractSingleVariableConstraint.getPositiveNormalizedAtoms(), // X > Y, so Y is a strict lower bound
e -> e.hasFunctor(GREATER_THAN)), // bound is strict
e -> processExplicitLowerBoundAndStrictnessPair(e.get(1), true, context));
FunctionIterator<Expression, Pair<Expression, Boolean>> lowerBoundsAndStrictnessFromNegativeNormalizedAtomsIterator = functionIterator(predicateIterator(abstractSingleVariableConstraint.getNegativeNormalizedAtoms(), e -> e.hasFunctor(LESS_THAN)), // not (X < Y) <=> X >= Y, so bound is non-strict
e -> processExplicitLowerBoundAndStrictnessPair(e.get(1), false, context));
Pair<Expression, Boolean> typeLowerBoundAndStrictness = getTypeLowerBoundAndStrictness(context);
Iterator<Pair<Expression, Boolean>> lowerBoundsAndStrictnessIterator = new NestedIterator<>(lowerBoundsAndStrictnessFromPositiveNormalizedAtomsIterator, lowerBoundsAndStrictnessFromNegativeNormalizedAtomsIterator, typeLowerBoundAndStrictness);
lowerBoundsIncludingImplicitOnes = arrayList();
fromLowerBoundsIncludingImplicitOnesToStrictness = map();
for (Pair<Expression, Boolean> boundAndStrictness : in(lowerBoundsAndStrictnessIterator)) {
Expression bound = boundAndStrictness.first;
lowerBoundsIncludingImplicitOnes.add(bound);
Boolean strictness = boundAndStrictness.second;
Boolean previousStrictness = fromLowerBoundsIncludingImplicitOnesToStrictness.get(bound);
if (previousStrictness == null || (!previousStrictness && strictness)) {
// if no strictness information so far, store current one; otherwise, only need to change it if previous occurrences were non-strict and this one is strict
fromLowerBoundsIncludingImplicitOnesToStrictness.put(bound, strictness);
}
}
}
Aggregations