import net.astesana.javaluator.AbstractEvaluator;
import net.astesana.javaluator.BracketPair;
import net.astesana.javaluator.Operator;
import net.astesana.javaluator.Parameters;
import java.util.*;
class ExpandLogic extends AbstractEvaluator<String> {
/* The logical NOT operator. */
final static Operator NOT = new Operator("~", 1, Operator.Associativity.RIGHT, 3);
/* The logical AND operator. */
final static Operator AND = new Operator("*", 2, Operator.Associativity.LEFT, 2);
/* The logical OR operator. */
final static Operator OR = new Operator("+", 2, Operator.Associativity.LEFT, 1);
private static final Parameters PARAMETERS;
static {
// Create the evaluator's parameters
PARAMETERS = new Parameters();
PARAMETERS.add(NOT);
PARAMETERS.add(AND);
PARAMETERS.add(OR);
// Add the parentheses
PARAMETERS.addExpressionBracket(BracketPair.PARENTHESES);
}
public ExpandLogic() {
super(PARAMETERS);
}
@Override
protected String toValue(String literal, Object evaluationContext) {
return literal;
}
static Set<List<String>> allComb(String[][] opts) {
Set<List<String>> results = new HashSet<List<String>>();
if (opts.length == 1) {
for (String s : opts[0])
results.add(new ArrayList<String>(Arrays.asList(s)));
} else
for (String str : opts[0]) {
String[][] tail = Arrays.copyOfRange(opts, 1, opts.length);
for (List<String> combs : allComb(tail)) {
combs.add(str);
results.add(combs);
}
}
return results;
}
@Override
protected String evaluate(Operator operator, Iterator<String> operands,
Object evaluationContext) {
List<String> tree = (List<String>) evaluationContext;
String eval = "";
String o1 = operands.next();
if (operator == NOT) {
String[] orSplit = o1.split("\\" + OR.getSymbol());
String[][] andVars = new String[orSplit.length][];
for (int i = 0; i < orSplit.length; i++) {
String[] andSplit = orSplit[i].split("\\" + AND.getSymbol());
for (int k = 0; k < andSplit.length; k++) {
if (andSplit[k].contains("~"))
andSplit[k] = andSplit[k].substring(1);
else
andSplit[k] = NOT.getSymbol() + andSplit[k];
}
andVars[i] = andSplit;
}
Set<List<String>> combinations = allComb(andVars);
for (List<String> combination : combinations) {
for (String var : combination) {
eval += var + AND.getSymbol();
}
eval = eval.substring(0, eval.length()-1) + OR.getSymbol();
}
eval = eval.substring(0, eval.length() - 1);
} else if (operator == AND) {
String o2 = operands.next();
Set<String> terms = new HashSet<String>();
for (String andVar : o1.split("\\+")) {
for (String term : o2.split("\\+")) {
terms.add(andVar + AND.getSymbol() + term);
}
}
for (String term : terms) {
eval += term + "+";
}
if (!eval.isEmpty())
eval = eval.substring(0, eval.length() - 1);
} else if (operator == OR) {
eval = o1 + operator.getSymbol() + operands.next();
}
tree.add(eval);
return eval;
}
}
public class SimpleLogic extends AbstractEvaluator<String> {
/* The logical AND operator. */
final static Operator AND = new Operator("*", 2, Operator.Associativity.LEFT, 2);
/* The logical OR operator. */
final static Operator OR = new Operator("+", 2, Operator.Associativity.LEFT, 1);
private static final Parameters PARAMETERS;
static {
// Create the evaluator's parameters
PARAMETERS = new Parameters();
// Add the supported operators
PARAMETERS.add(AND);
PARAMETERS.add(OR);
}
public SimpleLogic() {
super(PARAMETERS);
}
@Override
protected String toValue(String literal, Object evaluationContext) {
return literal;
}
@Override
protected String evaluate(Operator operator, Iterator<String> operands,
Object evaluationContext) {
List<String> tree = (List<String>) evaluationContext;
String o1 = operands.next();
String o2 = operands.next();
String eval = "";
if (operator == AND) {
boolean result = true;
if (o1.contains("0") || o2.contains("0"))
eval = "0";
else {
Set<String> vars = new TreeSet<String>();
Collections.addAll(vars, o1.split("\\*"));
vars.remove("1");
if (!vars.contains(o2) && !o2.equals("1"))
vars.add(o2);
if (vars.contains("~" + o2) || o2.contains("~") && vars.contains(o2.substring(1, o2.length())))
eval = "0";
else {
for (String var : vars)
eval += var + operator.getSymbol();
if (!eval.isEmpty())
eval = eval.substring(0, eval.length() - 1);
}
}
} else if (operator == OR) {
Set<String> vars = new TreeSet<String>();
Collections.addAll(vars, o1.split("\\+"));
vars.remove("0");
if (vars.contains("1") || o2.equals("1")) {
eval = "1";
} else if (!o2.equals("0")) {
Set<String> o2Vars = new HashSet<String>();
Collections.addAll(o2Vars, o2.split("\\*"));
int o2VarsLength = o2Vars.size();
boolean o2HasNot = o2.contains("~");
boolean equals = false;
Set<String> newVars = new HashSet<String>();
Iterator<String> varsIterator = vars.iterator();
while (varsIterator.hasNext()) {
String var = varsIterator.next();
if (var.equals(o2)) {
equals = true;
break;
}
Set<String> o1Vars = new HashSet<String>();
Collections.addAll(o1Vars, var.split("\\*"));
int o1VarsLength = o1Vars.size();
boolean o1HashNot = var.contains("~");
if (o1VarsLength == o2VarsLength) {
if (o1HashNot || o2HasNot) {
String newVar = checkDisjunktionSimilarity(o1Vars, o2Vars);
if (newVar != null) {
newVars.add(newVar);
varsIterator.remove();
equals = true;
}
}
} else if (o1VarsLength > o2VarsLength) {
if (o1Vars.containsAll(o2Vars)) {
varsIterator.remove();
} else if (o1HashNot || o2HasNot) {
String newVar = checkDisjunktionSimilarity(o2Vars, o1Vars);
if (newVar != null) {
newVars.add(newVar);
equals = true;
}
}
} else {
if (o2Vars.containsAll(o1Vars)) {
equals = true;
break;
} else if (o1HashNot || o2HasNot) {
String newVar = checkDisjunktionSimilarity(o1Vars, o2Vars);
if (newVar != null) {
newVars.add(newVar);
equals = true;
}
}
}
}
if (!equals)
vars.add(o2);
vars.addAll(newVars);
for (String var : vars)
eval += var + operator.getSymbol();
if (!eval.isEmpty())
eval = eval.substring(0, eval.length() - 1);
} else {
eval = o1;
}
} else {
throw new IllegalArgumentException();
}
tree.add(eval);
return eval;
}
public static String checkDisjunktionSimilarity(Set<String> smallOp, Set<String> bigOp) {
boolean similar = false, oneNot = false;
String newVar = "";
Iterator<String> o2VarsIterator = bigOp.iterator();
while (o2VarsIterator.hasNext()) {
String o2Var = o2VarsIterator.next();
if (!(smallOp.contains("~" + o2Var) || smallOp.contains(o2Var.substring(1)))) {
newVar += o2Var + AND.getSymbol();
if (smallOp.contains(o2Var))
similar = true;
} else {
similar = true;
if (oneNot == false)
oneNot = true;
else {
oneNot = false;
break;
}
}
}
if (similar && oneNot) {
if (newVar.length() > 1)
newVar = newVar.substring(0, newVar.length() - 1);
return newVar;
}
return null;
}
public static void main(String[] args) {
String term = "t * (a*b + 1 + (a + c)) + a*b*t + a*c + a*c*d + c*d";
term = "~(a+~b*c)";
ExpandLogic expandLogic = new ExpandLogic();
String expandLogicR = doIt(expandLogic, term);
cout(expandLogicR);
SimpleLogic simpleLogic = new SimpleLogic();
String result = doIt(simpleLogic, expandLogicR);
cout(result);
}
private static String doIt(AbstractEvaluator<String> evaluator, String expression) {
List<String> sequence = new ArrayList<String>();
evaluator.evaluate(expression, sequence);
System.out.println("Evaluation sequence for :" + expression);
for (String string : sequence) {
// System.out.println(string);
}
System.out.println();
return sequence.get(sequence.size() - 1);
}
public static void cout(Object o) {
System.out.println(o);
}
}