use of org.matheclipse.core.interfaces.IAssociation in project symja_android_library by axkr.
the class ASTAssociation method evaluate.
/**
* {@inheritDoc}
*/
@Override
public IExpr evaluate(EvalEngine engine) {
if (isEvalFlagOff(IAST.BUILT_IN_EVALED)) {
IAssociation result = F.NIL;
for (int i = 1; i < size(); i++) {
IExpr arg = getRule(i);
if (arg.isRule()) {
// for Rules eval rhs / for RuleDelayed don't
IExpr temp = engine.evaluateNIL(arg.second());
if (temp.isPresent()) {
if (!result.isPresent()) {
result = copy();
}
result.set(i, getRule(i).setAtCopy(2, temp));
}
}
}
if (result.isPresent()) {
result.addEvalFlags(IAST.BUILT_IN_EVALED);
return result;
}
addEvalFlags(IAST.BUILT_IN_EVALED);
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IAssociation in project symja_android_library by axkr.
the class IOFunctions method templateRender.
/**
* Render the template string with the <code>args</code> parameters. Typically the <code>args
* </code> are a <code>List</code> or an <code>Association</code> expression, otherwise the <code>
* args</code> parameter will be ignored.
*
* @param templateStr
* @param args
* @return the rendered template as a {@link String} expression
*/
public static String templateRender(String templateStr, IExpr args) {
try {
Map<String, Object> context = new HashMap<>();
if (args.isListOrAssociation()) {
if (args.isList()) {
IAST list = (IAST) args;
for (int i = 1; i < list.size(); i++) {
context.put(Integer.toString(i), list.get(i).toString());
}
} else if (args.isAssociation()) {
IAssociation assoc = (IAssociation) args;
for (int i = 1; i < assoc.size(); i++) {
IAST rule = assoc.getRule(i);
IExpr lhs = rule.arg1();
IExpr rhs = rule.arg2();
context.put(lhs.toString(), rhs.toString());
}
}
}
Writer writer = new StringWriter();
templateApply(templateStr, writer, context);
return writer.toString();
} catch (IOException e) {
LOGGER.error("IOFunctions.templateRender()", e);
}
return templateStr;
}
use of org.matheclipse.core.interfaces.IAssociation in project symja_android_library by axkr.
the class Programming method part.
/**
* Get the <code>Part[...]</code> of an expression. If the expression is no <code>IAST</code>
* return the expression.
*
* @param arg1 the expression from which parts should be extracted
* @param ast the <code>Part[...]</code> expression
* @param pos the index position from which the sub-expressions should be extracted
* @param engine the evaluation engine
* @return
*/
public static IExpr part(final IAST arg1, final IAST ast, int pos, EvalEngine engine) {
final IExpr arg2 = engine.evaluate(ast.get(pos));
int p1 = pos + 1;
int[] span = arg2.isSpan(arg1.size());
if (span != null) {
int start = span[0];
int last = span[1];
int step = span[2];
return spanPart(ast, pos, arg1, arg2, start, last, step, p1, engine);
} else if (arg2.equals(S.All)) {
return spanPart(ast, pos, arg1, arg2, 1, arg1.size() - 1, 1, p1, engine);
} else if (arg2.isReal()) {
final int indx = ast.get(pos).toIntDefault();
if (indx == Integer.MIN_VALUE) {
// Part `1` of `2` does not exist.
return IOFunctions.printMessage(S.Part, "partw", F.list(ast.get(pos), arg1), engine);
}
IExpr result = getIndex(arg1, indx, engine);
if (result.isPresent()) {
if (p1 < ast.size()) {
if (result.isASTOrAssociation()) {
return part((IAST) result, ast, p1, engine);
} else {
// Part specification `1` is longer than depth of object.
return IOFunctions.printMessage(S.Part, "partd", F.list(result), engine);
}
}
return result;
}
return F.NIL;
} else if (arg1.isAssociation()) {
IAssociation assoc = (IAssociation) arg1;
if (arg2.isList()) {
IExpr temp = null;
final IAST list = (IAST) arg2;
// list.size());
final IAssociation result = F.assoc();
for (int i = 1; i < list.size(); i++) {
final IExpr listArg = list.get(i);
if (listArg.isReal()) {
final int indx = listArg.toIntDefault();
if (indx == Integer.MIN_VALUE) {
// Part `1` of `2` does not exist.
return IOFunctions.printMessage(S.Part, "partw", F.list(listArg, arg1), engine);
}
IExpr ires = getIndexRule(arg1, indx, engine);
if (ires.isPresent()) {
if (p1 < ast.size()) {
if (ires.isASTOrAssociation()) {
temp = part((IAST) ires, ast, p1, engine);
if (temp.isPresent()) {
try {
result.appendRule(temp);
} catch (IndexOutOfBoundsException ioobex) {
return IOFunctions.printMessage(S.Part, "pkspec1", F.list(temp), engine);
}
} else {
// an error occurred
return F.NIL;
}
} else {
// Part specification `1` is longer than depth of object.
return IOFunctions.printMessage(S.Part, "partd", F.list(ires), engine);
}
} else {
try {
result.appendRule(ires);
} catch (IndexOutOfBoundsException ioobex) {
return IOFunctions.printMessage(S.Part, "pkspec1", F.list(ires), engine);
}
}
} else {
return F.NIL;
}
} else if (listArg.isAST(S.Key, 2)) {
result.appendRule(assoc.getRule(listArg.first()));
} else if (listArg.isString()) {
result.appendRule(assoc.getRule(listArg));
} else if (listArg.isNumber()) {
// The expression `1` cannot be used as a part specification.
return IOFunctions.printMessage(S.Part, "pkspec1", F.list(list), engine);
}
}
return result;
}
IExpr result = F.NIL;
if (arg2.isAST(S.Key, 2)) {
result = assoc.getValue(arg2.first());
} else if (arg2.isString()) {
result = assoc.getValue(arg2);
}
if (result.isPresent()) {
if (p1 < ast.size()) {
if (result.isASTOrAssociation()) {
return part((IAST) result, ast, p1, engine);
} else {
// Part specification `1` is longer than depth of object.
return IOFunctions.printMessage(S.Part, "partd", F.list(result), engine);
}
}
return result;
}
} else if (arg2.isList()) {
IExpr temp = null;
final IAST list = (IAST) arg2;
final IASTAppendable result = F.ast(arg1.head(), list.size());
for (int i = 1; i < list.size(); i++) {
final IExpr listArg = list.get(i);
if (listArg.isReal()) {
final int indx = listArg.toIntDefault();
if (indx == Integer.MIN_VALUE) {
// Part `1` of `2` does not exist.
return IOFunctions.printMessage(S.Part, "partw", F.list(listArg, arg1), engine);
}
IExpr ires = getIndex(arg1, indx, engine);
if (ires.isPresent()) {
if (p1 < ast.size()) {
if (ires.isASTOrAssociation()) {
temp = part((IAST) ires, ast, p1, engine);
if (temp.isPresent()) {
result.append(temp);
} else {
// an error occurred
return F.NIL;
}
} else {
// Part specification `1` is longer than depth of object.
return IOFunctions.printMessage(S.Part, "partd", F.list(ires), engine);
}
} else {
result.append(ires);
}
} else {
return F.NIL;
}
} else if (listArg.isNumber() || listArg.isString()) {
// The expression `1` cannot be used as a part specification.
return IOFunctions.printMessage(S.Part, "pkspec1", F.list(list), engine);
}
}
return result;
}
// The expression `1` cannot be used as a part specification.
return IOFunctions.printMessage(S.Part, "pkspec1", F.list(arg2), engine);
}
use of org.matheclipse.core.interfaces.IAssociation in project symja_android_library by axkr.
the class ASTDataset method newAssociationOfAssociations.
/**
* Create a <code>Dataset</code> object from a (head-)association <code><|...|></code> of
* (sub-)associations. Each key in the (head-)association is used in the first column the
* (sub-)association represents the other columns of a row in the <code>Dataset</code>. The
* left-hand-side of each singular rule in a (sub-)association was assumed to be the name of the
* resulting <code>Dataset</code> columns. Identical names maps the right-hand-side values of the
* rule to the same columns in the resulting dataset.
*
* @param assocOfAssociations
* @return {@link F#NIL} if the <code>Dataset</code> cannot be created
*/
public static IExpr newAssociationOfAssociations(IAssociation assocOfAssociations) {
// 1. phase: build up column names; reserve 1 column for header assoc
List<String> colNames = new ArrayList<String>();
Set<String> colNamesSet = new HashSet<String>();
colNamesSet.add("");
colNames.add("");
for (int i = 1; i < assocOfAssociations.size(); i++) {
IAssociation assoc = (IAssociation) assocOfAssociations.get(i);
for (int j = 1; j < assoc.size(); j++) {
IAST rule = assoc.getRule(j);
String columnName = rule.first().toString();
if (!colNamesSet.contains(columnName)) {
colNamesSet.add(columnName);
colNames.add(columnName);
}
}
}
if (colNames.size() > 0) {
// 2. phase: define the columns
Table table = Table.create();
Column<?>[] cols = new Column<?>[colNames.size()];
for (int i = 0; i < colNames.size(); i++) {
cols[i] = ExprColumn.create(colNames.get(i));
}
table.addColumns(cols);
// 3. phase: add the values
for (int i = 1; i < assocOfAssociations.size(); i++) {
IExpr rule = assocOfAssociations.getRule(i);
IAssociation assoc = (IAssociation) rule.second();
Row row = table.appendRow();
row.setExpr("", rule.first());
for (int j = 1; j < assoc.size(); j++) {
rule = assoc.getRule(j);
String columnName = rule.first().toString();
IExpr value = rule.second();
row.setExpr(columnName, value);
}
}
return newTablesawTable(table);
}
return F.NIL;
}
use of org.matheclipse.core.interfaces.IAssociation in project symja_android_library by axkr.
the class EvalEngine method evalAttributes.
/**
* Evaluate an AST according to the attributes set in the header symbol. The evaluation steps are
* controlled by the header attributes.
*
* @param symbol the header symbol
* @param mutableAST the AST which should be evaluated. If <code>symbol</code> has attribute
* {@link ISymbol#ORDERLESS} the mutableAST will be modified.
* @return <code>F.NIL</code> if no evaluation was possible
*/
public IExpr evalAttributes(ISymbol symbol, IASTMutable mutableAST) {
final int astSize = mutableAST.size();
if (astSize == 2) {
return evalASTArg1(mutableAST);
}
IExpr result = mutableAST.head().evaluateHead(mutableAST, this);
if (result.isPresent()) {
return result;
}
if (astSize != 1) {
IASTMutable returnResult = F.NIL;
final int attributes = symbol.getAttributes();
if ((attributes & ISymbol.SEQUENCEHOLD) != ISymbol.SEQUENCEHOLD) {
if ((result = F.flattenSequence(mutableAST)).isPresent()) {
return result;
}
}
IASTMutable resultList = evalArgs(mutableAST, attributes);
if (resultList.isPresent()) {
return resultList;
}
// ONEIDENTITY is checked in the evalASTArg1() method!
if (ISymbol.hasFlatAttribute(attributes)) {
// associative symbol
IASTAppendable flattened;
if ((flattened = EvalAttributes.flatten(mutableAST)).isPresent()) {
returnResult = flattened;
mutableAST = returnResult;
}
}
result = evalTagSetPlusTimes(mutableAST);
if (result.isPresent()) {
return result;
}
if ((ISymbol.LISTABLE & attributes) == ISymbol.LISTABLE && !((mutableAST.getEvalFlags() & IAST.IS_LISTABLE_THREADED) == IAST.IS_LISTABLE_THREADED)) {
// thread over the lists
resultList = threadASTListArgs(mutableAST, S.Thread, "tdlen");
if (resultList.isPresent()) {
return evalArgs(resultList, ISymbol.NOATTRIBUTE).orElse(resultList);
}
int indx = mutableAST.indexOf(x -> x.isAssociation());
if (indx > 0) {
return ((IAssociation) mutableAST.get(indx)).mapThread(mutableAST, indx);
}
}
if ((ISymbol.NUMERICFUNCTION & attributes) == ISymbol.NUMERICFUNCTION) {
if (!((ISymbol.HOLDALL & attributes) == ISymbol.HOLDALL)) {
if (mutableAST.exists(x -> x.isIndeterminate())) {
return S.Indeterminate;
}
IExpr temp = mutableAST.extractConditionalExpression(false);
if (temp.isPresent()) {
return temp;
}
}
} else if (mutableAST.isBooleanFunction() || mutableAST.isComparatorFunction()) {
IExpr temp = mutableAST.extractConditionalExpression(false);
if (temp.isPresent()) {
return temp;
}
}
if (astSize > 2 && ISymbol.hasOrderlessAttribute(attributes)) {
// commutative symbol
EvalAttributes.sortWithFlags(mutableAST);
}
return returnResult;
}
return F.NIL;
}
Aggregations