package org.archstudio.prolog.engine;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.archstudio.prolog.op.Evaluable;
import org.archstudio.prolog.op.Executable;
import org.archstudio.prolog.term.ComplexTerm;
import org.archstudio.prolog.term.ListTerm;
import org.archstudio.prolog.term.StringTerm;
import org.archstudio.prolog.term.Term;
import org.archstudio.prolog.term.VariableTerm;
import com.google.common.collect.Lists;
public class PrologUtils {
public static final VariableTerm DONT_CARE_VARIABLE = new VariableTerm("_");
static private AtomicInteger temporaryVarialeCounter = new AtomicInteger();
private PrologUtils() {
}
public static final Set<VariableTerm> extractVariables(Set<VariableTerm> variables, Term term) {
if (term instanceof VariableTerm) {
if (!DONT_CARE_VARIABLE.equals(((VariableTerm) term).getName())) {
variables.add((VariableTerm) term);
}
}
else if (term instanceof ComplexTerm) {
for (Term t : ((ComplexTerm) term).getTerms()) {
extractVariables(variables, t);
}
}
else if (term instanceof ListTerm) {
if (((ListTerm) term).getHead() != null) {
extractVariables(variables, ((ListTerm) term).getHead());
}
if (((ListTerm) term).getTail() != null) {
extractVariables(variables, ((ListTerm) term).getTail());
}
}
return variables;
}
public static final ComplexTerm resolveComplexTerm(ProofContext proofContext, Term t,
Map<VariableTerm, Term> variables) {
t = t.resolve(proofContext, variables);
if (t instanceof ComplexTerm) {
return (ComplexTerm) t;
}
throw new RuntimeException("Not complex term: " + t);
}
public static final Executable resolveExecutable(ProofContext proofContext, Term t,
Map<VariableTerm, Term> variables) {
t = t.resolve(proofContext, variables);
if (t instanceof Executable) {
return (Executable) t;
}
throw new RuntimeException("Not executable: " + t);
}
public static final Evaluable resolveEvaluable(ProofContext proofContext, Term t, Map<VariableTerm, Term> variables) {
t = t.resolve(proofContext, variables);
if (t instanceof Evaluable) {
return (Evaluable) t;
}
throw new RuntimeException("Not evaluable: " + t);
}
public static final String resolveString(ProofContext proofContext, Term t, Map<VariableTerm, Term> variables) {
t = t.resolve(proofContext, variables);
if (t instanceof StringTerm) {
return (String) ((StringTerm) t).getValue();
}
return t.toString();
}
public static final Number evaluate(ProofContext proofContext, Term term, Map<VariableTerm, Term> variables) {
return resolveEvaluable(proofContext, term, variables).evaluate(proofContext, variables);
}
public static final BigDecimal toBigDecimal(java.lang.Number n) {
return n instanceof BigDecimal ? (BigDecimal) n : new BigDecimal((BigInteger) n);
}
public static final Iterable<Map<VariableTerm, Term>> negate(Iterable<Map<VariableTerm, Term>> result,
Map<VariableTerm, Term> variables) {
if (result.iterator().hasNext()) {
return emptyVariablesList();
}
return Collections.singleton(variables);
}
public static final Iterable<Map<VariableTerm, Term>> emptyVariablesList() {
return Collections.emptyList();
}
public static final List<Term> termOrListTerms(final Term t) {
List<Term> terms = Lists.newArrayList();
if (t instanceof ListTerm) {
for (Term t2 : ((ListTerm) t).asList()) {
terms.addAll(termOrListTerms(t2));
}
}
else {
terms.add(t);
}
return terms;
}
public static final VariableTerm getTemporaryVariableTerm() {
return new VariableTerm("_G" + temporaryVarialeCounter.incrementAndGet());
}
public static Iterable<Map<VariableTerm, Term>> execute(ProofContext proofContext,
UnificationEngine unificationEngine, Term t) {
return execute(proofContext, unificationEngine, t, Collections.<VariableTerm, Term> emptyMap());
}
public static Iterable<Map<VariableTerm, Term>> execute(ProofContext proofContext,
UnificationEngine unificationEngine, Term t, Map<VariableTerm, Term> variables) {
proofContext.reset();
return resolveExecutable(proofContext, t, variables).execute(proofContext, unificationEngine, t, variables);
}
}