Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2013, SRI International
* All rights reserved.
* Licensed under the The BSD 3-Clause License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://opensource.org/licenses/BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the aic-expresso nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sri.ai.expresso.helper;
import static com.sri.ai.util.Util.mapIntoList;
import static com.sri.ai.util.Util.thereExists;
import static com.sri.ai.util.base.PairOf.pairOf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.sri.ai.expresso.api.CompoundSyntaxTree;
import com.sri.ai.expresso.api.CountingFormula;
import com.sri.ai.expresso.api.Expression;
import com.sri.ai.expresso.api.ExpressionAndSyntacticContext;
import com.sri.ai.expresso.api.FunctionApplication;
import com.sri.ai.expresso.api.IndexExpressionsSet;
import com.sri.ai.expresso.api.IntensionalSet;
import com.sri.ai.expresso.api.LambdaExpression;
import com.sri.ai.expresso.api.Parser;
import com.sri.ai.expresso.api.Symbol;
import com.sri.ai.expresso.api.SyntaxLeaf;
import com.sri.ai.expresso.api.SyntaxTree;
import com.sri.ai.expresso.api.Tuple;
import com.sri.ai.expresso.core.DefaultCountingFormula;
import com.sri.ai.expresso.core.DefaultExistentiallyQuantifiedFormula;
import com.sri.ai.expresso.core.DefaultExtensionalMultiSet;
import com.sri.ai.expresso.core.DefaultExtensionalUniSet;
import com.sri.ai.expresso.core.DefaultFunctionApplication;
import com.sri.ai.expresso.core.DefaultIntensionalMultiSet;
import com.sri.ai.expresso.core.DefaultIntensionalUniSet;
import com.sri.ai.expresso.core.DefaultLambdaExpression;
import com.sri.ai.expresso.core.DefaultSymbol;
import com.sri.ai.expresso.core.DefaultTuple;
import com.sri.ai.expresso.core.DefaultUniversallyQuantifiedFormula;
import com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet;
import com.sri.ai.grinder.api.Registry;
import com.sri.ai.grinder.core.PruningPredicate;
import com.sri.ai.grinder.helper.FunctionSignature;
import com.sri.ai.grinder.parser.antlr.AntlrGrinderParserWrapper;
import com.sri.ai.grinder.sgdpllt.library.FunctorConstants;
import com.sri.ai.grinder.sgdpllt.library.IsVariable;
import com.sri.ai.grinder.sgdpllt.library.boole.And;
import com.sri.ai.grinder.sgdpllt.library.boole.ForAll;
import com.sri.ai.grinder.sgdpllt.library.boole.ThereExists;
import com.sri.ai.grinder.sgdpllt.library.indexexpression.IndexExpressions;
import com.sri.ai.grinder.sgdpllt.library.set.extensional.ExtensionalSets;
import com.sri.ai.util.Util;
import com.sri.ai.util.base.Equals;
import com.sri.ai.util.base.NotContainedBy;
import com.sri.ai.util.base.Pair;
import com.sri.ai.util.base.PairOf;
import com.sri.ai.util.base.SingletonListMaker;
import com.sri.ai.util.collect.FunctionIterator;
import com.sri.ai.util.collect.IntegerIterator;
import com.sri.ai.util.collect.ZipIterator;
import com.sri.ai.util.math.Rational;
/**
* A class of helper methods for {@link Expression}s.
*
* @author braz
*/
@Beta
public class Expressions {
/**
* An unmodifiable empty list of expressions.
*/
public static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList());
public static final Expression TRUE = Expressions.makeSymbol("true");
public static final Expression FALSE = Expressions.makeSymbol("false");
public static final Expression MINUS_ONE = Expressions.makeSymbol(-1);
public static final Expression ZERO = Expressions.makeSymbol(0);
public static final Expression ZERO_POINT_FIVE = Expressions.makeSymbol(0.5);
public static final Expression ONE = Expressions.makeSymbol(1);
public static final Expression TWO = Expressions.makeSymbol(2);
public static final Expression THREE = Expressions.makeSymbol(3);
public static final Expression X = Expressions.makeSymbol("X");
public static final Expression Y = Expressions.makeSymbol("Y");
public static final Expression Z = Expressions.makeSymbol("Z");
public static final Expression UNKNOWN = Expressions.makeSymbol("Unknown");
//
private static final SingletonListMaker INTEGER_SINGLETON_LIST_MAKER = new SingletonListMaker();
/**
* Returns an expression represented by a given syntax tree.
* Scheduled to be removed once expressions are no longer based on syntax trees.
*/
@Deprecated
public static Expression makeFromSyntaxTree(SyntaxTree syntaxTree) {
if (syntaxTree instanceof CompoundSyntaxTree) {
Expression result = makeExpressionOnSyntaxTreeWithLabelAndSubTrees(syntaxTree.getLabel(), syntaxTree.getImmediateSubTrees().toArray());
// Expression result = new ExpressionOnCompoundSyntaxTree(syntaxTree);
return result;
}
if (syntaxTree instanceof SyntaxLeaf) {
SyntaxLeaf syntaxLeaf = (SyntaxLeaf) syntaxTree;
Expression result;
if (syntaxLeaf.isStringLiteral()) {
result = Expressions.makeStringLiteral((String)syntaxLeaf.getValue());
}
else {
result = Expressions.makeSymbol(syntaxLeaf.getValue());
}
// Expression result = new ExpressionOnSyntaxLeaf(syntaxTree);
return result;
}
throw new Error("Syntax tree " + syntaxTree + " should be either a CompoundSyntaxTree or a Symbol");
}
public static final Function SYNTAX_TREE_TO_EXPRESSION = new Function() {
@Override
public Expression apply(SyntaxTree input) {
Expression result = makeFromSyntaxTree(input);
return result;
}
};
/**
* Makes Expression based on a syntax tree with given label and sub-trees, or {@link Expression}s from whose syntax trees must be used.
*/
public static Expression makeExpressionOnSyntaxTreeWithLabelAndSubTrees(Object label, Object... subTreeObjects) {
return makeExpressionOnSyntaxTreeWithLabelAndSubTreesWithRandomPredicatesSignatures(null, label, subTreeObjects);
}
public static Expression makeExpressionOnSyntaxTreeWithLabelAndSubTreesWithRandomPredicatesSignatures(Collection randomPredicatesSignatures, Object label, Object... subTreeObjects) {
Expression result;
if (label.equals(ForAll.LABEL)) {
result = makeDefaultUniversallyQuantifiedFormulaFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(ThereExists.LABEL)) {
result = makeDefaultExistentiallyQuantifiedFormulaFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(CountingFormula.LABEL)) {
result = makeDefaultCountingFormulaExpressionFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(LambdaExpression.LABEL)) {
result = makeDefaultLambdaExpressionFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(Tuple.TUPLE_LABEL) || label.equals("tuple")) {
result = makeDefaultTupleFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(ExtensionalSets.UNI_SET_LABEL)) {
result = makeDefaultExtensionalUniSetFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(ExtensionalSets.MULTI_SET_LABEL)) {
result = makeDefaultExtensionalMultiSetFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(IntensionalSet.UNI_SET_LABEL)) {
result = makeDefaultIntensionalUniSetFromLabelAndSubTrees(label, subTreeObjects);
}
else if (label.equals(IntensionalSet.MULTI_SET_LABEL)) {
result = makeDefaultIntensionalMultiSetFromLabelAndSubTrees(label, subTreeObjects);
}
else {
result = makeDefaultFunctionApplicationFromLabelAndSubTrees(label, subTreeObjects);
}
return result;
}
private static Expression makeDefaultCountingFormulaExpressionFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
Expression indexExpressionsKleeneList = subTreeExpressions.get(0);
IndexExpressionsSet indexExpressions = new ExtensionalIndexExpressionsSet(ensureListFromKleeneList(indexExpressionsKleeneList));
Expression body = subTreeExpressions.get(1);
Expression result = new DefaultCountingFormula(indexExpressions, body);
return result;
}
private static Expression makeDefaultLambdaExpressionFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
Expression indexExpressionsKleeneList = subTreeExpressions.get(0);
IndexExpressionsSet indexExpressions = new ExtensionalIndexExpressionsSet(ensureListFromKleeneList(indexExpressionsKleeneList));
Expression body = subTreeExpressions.get(1);
Expression result = new DefaultLambdaExpression(indexExpressions, body);
return result;
}
private static Expression makeDefaultUniversallyQuantifiedFormulaFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
Expression indexExpressionsKleeneList = subTreeExpressions.get(0);
IndexExpressionsSet indexExpressions = new ExtensionalIndexExpressionsSet(ensureListFromKleeneList(indexExpressionsKleeneList));
Expression body = subTreeExpressions.get(1);
Expression result = new DefaultUniversallyQuantifiedFormula(indexExpressions, body);
return result;
}
private static Expression makeDefaultExistentiallyQuantifiedFormulaFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
Expression indexExpressionsKleeneList = subTreeExpressions.get(0);
IndexExpressionsSet indexExpressions = new ExtensionalIndexExpressionsSet(ensureListFromKleeneList(indexExpressionsKleeneList));
Expression body = subTreeExpressions.get(1);
Expression result = new DefaultExistentiallyQuantifiedFormula(indexExpressions, body);
return result;
}
private static Expression makeDefaultFunctionApplicationFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
if (subTreeObjects.length == 1 && subTreeObjects[0] instanceof Collection) {
subTreeObjects = ((Collection) subTreeObjects[0]).toArray();
}
Expression labelExpression = makeFromObject(label);
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
Expression result = new DefaultFunctionApplication(labelExpression, subTreeExpressions);
return result;
}
private static Expression makeDefaultTupleFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
if (subTreeObjects.length == 1 && subTreeObjects[0] instanceof Collection) {
subTreeObjects = ((Collection) subTreeObjects[0]).toArray();
}
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
if (subTreeExpressions.size() == 1) {
subTreeExpressions = new ArrayList(Expressions.ensureListFromKleeneList(subTreeExpressions.get(0)));
}
Expression result = new DefaultTuple(subTreeExpressions);
return result;
}
private static Expression makeDefaultExtensionalUniSetFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
if (subTreeObjects.length == 1 && subTreeObjects[0] instanceof Collection) {
subTreeObjects = ((Collection) subTreeObjects[0]).toArray();
}
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
if (subTreeExpressions.size() == 1) {
subTreeExpressions = new ArrayList(Expressions.ensureListFromKleeneList(subTreeExpressions.get(0)));
}
Expression result = new DefaultExtensionalUniSet(subTreeExpressions);
return result;
}
private static Expression makeDefaultExtensionalMultiSetFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
if (subTreeObjects.length == 1 && subTreeObjects[0] instanceof Collection) {
subTreeObjects = ((Collection) subTreeObjects[0]).toArray();
}
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
if (subTreeExpressions.size() == 1) {
subTreeExpressions = new ArrayList(Expressions.ensureListFromKleeneList(subTreeExpressions.get(0)));
}
Expression result = new DefaultExtensionalMultiSet(subTreeExpressions);
return result;
}
private static Expression makeDefaultIntensionalUniSetFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
if (subTreeObjects.length == 1 && subTreeObjects[0] instanceof Collection) {
subTreeObjects = ((Collection) subTreeObjects[0]).toArray();
}
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
if (subTreeExpressions.size() == 1) {
subTreeExpressions = new ArrayList(Expressions.ensureListFromKleeneList(subTreeExpressions.get(0)));
}
Expression scopingExpression = subTreeExpressions.get(0);
IndexExpressionsSet indexExpressions = new ExtensionalIndexExpressionsSet(
(scopingExpression == null || scopingExpression.numberOfArguments() == 0)?
Util.list()
: new ArrayList(Expressions.ensureListFromKleeneList(scopingExpression.get(0))));
Expression conditioningSyntaxTree = subTreeExpressions.get(2);
Expression condition = conditioningSyntaxTree == null? Expressions.TRUE : conditioningSyntaxTree.get(0);
Expression result = new DefaultIntensionalUniSet(indexExpressions, subTreeExpressions.get(1), condition);
return result;
}
private static Expression makeDefaultIntensionalMultiSetFromLabelAndSubTrees(Object label, Object[] subTreeObjects) {
if (subTreeObjects.length == 1 && subTreeObjects[0] instanceof Collection) {
subTreeObjects = ((Collection) subTreeObjects[0]).toArray();
}
ArrayList subTreeExpressions = Util.mapIntoArrayList(subTreeObjects, Expressions::makeFromObject);
if (subTreeExpressions.size() == 1) {
subTreeExpressions = new ArrayList(Expressions.ensureListFromKleeneList(subTreeExpressions.get(0)));
}
Expression scopingExpression = subTreeExpressions.get(0);
IndexExpressionsSet indexExpressions = new ExtensionalIndexExpressionsSet(
(scopingExpression == null || scopingExpression.numberOfArguments() == 0)?
Util.list()
: new ArrayList(Expressions.ensureListFromKleeneList(scopingExpression.get(0))));
Expression conditioningSyntaxTree = subTreeExpressions.get(2);
Expression condition = conditioningSyntaxTree == null? Expressions.TRUE : conditioningSyntaxTree.get(0);
Expression result = new DefaultIntensionalMultiSet(indexExpressions, subTreeExpressions.get(1), condition);
return result;
}
/**
* @param object
*/
public static Expression makeFromObject(Object object) {
Expression result;
if (object == null) { // this is here for backwards compatibility with syntax-tree-based expressions, should be gone when they are.
result = null;
}
else if (object instanceof SyntaxTree) {
result = makeFromSyntaxTree((SyntaxTree) object);
}
else if (object instanceof Expression) {
result = (Expression) object;
}
else {
result = makeSymbol(object);
}
return result;
}
/**
* Makes an expression based on a symbol with given value.
*/
public static Symbol makeSymbol(Object object) {
return DefaultSymbol.createSymbol(object);
}
public static Tuple makeTuple(Expression... elements) {
return makeTuple(Arrays.asList(elements));
}
public static Tuple makeTuple(List elements) {
Tuple result = new DefaultTuple(elements);
return result;
}
public static Symbol makeStringLiteral(String object) {
return DefaultSymbol.createSymbol(object, true);
}
public static Symbol parseTextAndMakeSymbolOrStringLiteral(String symbolValue) {
boolean isSingleQuoted = symbolValue.startsWith("'") && symbolValue.endsWith("'");
boolean isDoubleQuoted = symbolValue.startsWith("\"") && symbolValue.endsWith("\"");
if (isSingleQuoted || isDoubleQuoted) {
// When parsing, whether a single quoted symbol or a string literal (i.e. double quoted)
// the value is that within the quotes and not the quotes themselves.
symbolValue = symbolValue.substring(1, symbolValue.length() - 1);
}
Symbol result;
if (isDoubleQuoted) {
result = makeStringLiteral(symbolValue);
}
else {
result = makeSymbol(symbolValue);
}
return result;
}
static private Parser parser = new AntlrGrinderParserWrapper();
/**
* Parse a string into an expression using {@link AntlrGrinderParserWrapper}.
*/
public static Expression parse(String string) {
Expression result = parse(string, parser.newDefaultErrorListener());
return result;
}
public static Expression parse(String string, Function errorMessageHandler) {
Expression result = parse(string, (Object offendingSymbol, int line, int charPositionInLine, String msg, Exception e) -> {
errorMessageHandler.apply(msg);
});
return result;
}
public static Expression parse(String string, Parser.ErrorListener errorListener) {
Expression result = parser.parse(string, errorListener);
return result;
}
/**
* If argument is a "kleene list" application, returns a {@link List} of its arguments;
* otherwise, returns a {@link List} containing this argument.
*/
public
static List ensureListFromKleeneList(Expression listOrSingleElementOfList) {
boolean isKleeneList = listOrSingleElementOfList != null && listOrSingleElementOfList.hasFunctor(FunctorConstants.KLEENE_LIST);
return (isKleeneList ? listOrSingleElementOfList.getArguments() : Lists.newArrayList(listOrSingleElementOfList));
}
/**
* Returns a "kleene list" application if given list of expressions is not singleton,
* and the single element itself otherwise.
* This is a inverse operation of {@ #ensureList(Expression)}.
*/
public static Expression makeKleeneListIfNeeded(List list) {
if (list.size() == 1) {
return list.get(0);
}
return Expressions.makeExpressionOnSyntaxTreeWithLabelAndSubTrees(FunctorConstants.KLEENE_LIST, list);
}
/**
* Given a symbol assumed to be an identifier,
* returns a symbol with a minimum 0 or more prime ("'") characters appended to it
* to make it unique, according to a given predicate indicating uniqueness.
*/
public static Expression primedUntilUnique(Expression symbol, Predicate isUnique) {
Symbol newSymbol = (Symbol) symbol;
while (! isUnique.apply(newSymbol)) {
newSymbol = Expressions.makeSymbol(newSymbol + "'");
}
return newSymbol;
}
/**
* Given a string,
* returns a string with a minimum 0 or more prime ("'") characters appended to it
* to make it unique, according to a given predicate indicating uniqueness.
*/
public static String primedUntilUnique(String symbol, Predicate isUnique) {
while (! isUnique.apply(symbol)) {
symbol = symbol + "'";
}
return symbol;
}
/**
* Given a symbol assumed to be an identifier,
* returns a symbol with a minimum 0 or more instances of a given prefix
* to make it unique, according to a given predicate indicating uniqueness.
*/
public static Expression prefixedUntilUnique(Expression symbol, String prefix, Predicate isUnique) {
while (! isUnique.apply(symbol)) {
symbol = Expressions.makeSymbol(prefix + symbol);
}
return symbol;
}
/**
* Given a symbol assumed to be an identifier,
* returns a symbol with a minimum 0 or more prime ("'") characters appended to it
* to make it unique in a given expression.
*/
public static Expression primedUntilUnique(Expression symbol, Expression expression, Registry registry) {
LinkedHashSet variableBeingReferenced = Expressions.getVariablesBeingReferenced(expression, registry.getIsUniquelyNamedConstantPredicate());
Predicate isUnique = new NotContainedBy(variableBeingReferenced);
Expression result = Expressions.primedUntilUnique(symbol, isUnique);
return result;
}
/**
* Given a proposed name for a variable ensure that a valid unique variable
* is returned.
*
* @param variableName
* a proposed name for the variable.
* @param expression
* an expression to check for other variables in order to ensure
* uniqueness.
* @param registry
* the context that the variable is being created in.
* @return a uniquely named variable in the context of the passed in
* expression.
*/
public static Expression makeUniqueVariable(
String variableName, Expression expression, Registry registry) {
// Variables have a leading captial
if (variableName.length() > 0) {
String leadingChar = variableName.substring(0, 1);
if (!leadingChar.equals(leadingChar.toUpperCase())) {
variableName = leadingChar.toUpperCase() + variableName.substring(1);
}
}
else {
variableName = "V";
}
Expression result = primedUntilUnique(Expressions.makeSymbol(variableName), expression, registry);
return result;
}
/**
* Given a collection of expressions c,
* returns a map with the an entry for each expression e in c,
* defined as follows:
* (key, value), if e is a binary application of functor on (key, value),
* and (e, defaultValueGivenKey.evaluate(e)) otherwise.
* This was originally motivated by the problem of mapping collections such as X in Integer, Y, Z in Real
* to something like X -> Integer, Y -> type(Y), Z -> Real.
*/
public static LinkedHashMap getRelationalMap(Collection expressions, Expression functor, Function defaultValueGivenKey) {
LinkedHashMap result = new LinkedHashMap();
for (Expression expression : expressions) {
Expression key;
Expression value;
if (expression.hasFunctor(functor)) {
key = expression.get(0);
value = expression.get(1);
}
else {
key = expression;
value = defaultValueGivenKey.apply(key);
}
result.put(key, value);
}
return result;
}
/** Indicates whether an expression is a Symbol representing a numeric constant. */
public static boolean isNumber(Expression expression) {
boolean result = expression.getSyntacticFormType().equals(Symbol.SYNTACTIC_FORM_TYPE) &&
expression.getValue() instanceof Number;
return result;
}
public static boolean isStringLiteral(Expression expression) {
boolean result = expression.getSyntacticFormType().equals(Symbol.SYNTACTIC_FORM_TYPE) &&
((Symbol)expression).isStringLiteral();
return result;
}
/** Indicates whether an expression is a Symbol representing a boolean constant. */
public static boolean isBooleanSymbol(Expression expression) {
boolean result = expression.equals(TRUE) || expression.equals(FALSE);
return result;
}
/** Assumes the expression is a Symbol and returns its value as Number. */
public static Number asNumber(Expression expression) {
return (Number) ((SyntaxLeaf) expression.getSyntaxTree()).getValue();
}
/** Gets an object and returns it if it is an expression, or an atomic expression containing it as value. */
public static Expression wrap(Object object) {
if (object == null || object instanceof Expression) {
return (Expression) object;
}
return makeSymbol(object);
}
/** The array version of {@link #wrap(Object)}. */
public static List wrap(Object[] array) {
LinkedList result = new LinkedList();
for (int i = 0; i!= array.length; i++) {
Expression wrap = wrap(array[i]);
result.add(wrap);
}
return result;
}
/** A version of {@link #wrap(Object)} getting an iterator and returning a list. */
public static List wrap(Iterator