aima.core.logic.propositional.parsing.ast.Sentence Maven / Gradle / Ivy
package aima.core.logic.propositional.parsing.ast;
import java.util.Arrays;
import java.util.List;
import aima.core.logic.common.ParseTreeNode;
import aima.core.logic.propositional.parsing.PLVisitor;
import aima.core.util.Util;
/**
* Artificial Intelligence A Modern Approach (3rd Edition): page 244.
*
* The base of the knowledge representation language for propositional logic.
* Note: this class hierarchy defines the abstract syntax representation used
* for representing propositional logic.
*
* @author Ciaran O'Reilly
* @author Ravi Mohan
*
*/
public abstract class Sentence implements ParseTreeNode {
/**
*
* @return the logical connective associated with this sentence if it has
* one (i.e. is a ComplexSentence), null otherwise.
*/
public Connective getConnective() {
return null;
}
/**
*
* @return the number of simpler sentences contained in this sentence. Will
* only be > 0 if a Complex Sentence.
*/
public int getNumberSimplerSentences() {
return 0;
}
/**
* Get the simplified sentence, at the specified offset (starts at 0),
* contained by this Sentence if it is a Complex Sentence, null otherwise.
*
* @param offset
* the offset of the contained simplified sentence to retrieve.
* @return the simplified sentence, at the specified offset, contained by
* this sentence (if a complex sentence), null otherwise.
*/
public Sentence getSimplerSentence(int offset) {
return null;
}
/**
*
* @return true if a complex sentence with a Not connective, false
* otherwise.
*/
public boolean isNotSentence() {
return hasConnective(Connective.NOT);
}
/**
*
* @return true if a complex sentence with an And connective, false
* otherwise.
*/
public boolean isAndSentence() {
return hasConnective(Connective.AND);
}
/**
*
* @return true if a complex sentence with an Or connective, false
* otherwise.
*/
public boolean isOrSentence() {
return hasConnective(Connective.OR);
}
/**
*
* @return true if a complex sentence with an Implication connective, false
* otherwise.
*/
public boolean isImplicationSentence() {
return hasConnective(Connective.IMPLICATION);
}
/**
*
* @return true if a complex sentence with a Biconditional connective, false
* otherwise.
*/
public boolean isBiconditionalSentence() {
return hasConnective(Connective.BICONDITIONAL);
}
/**
*
* @return true if a proposition symbol, false otherwise.
*/
public boolean isPropositionSymbol() {
return getConnective() == null;
}
/**
*
* @return true if a complex sentence containing a single simpler sentence,
* false otherwise.
*/
public boolean isUnarySentence() {
return hasConnective(Connective.NOT);
}
/**
*
* @return true if a complex sentence containing two simpler sentences,
* false otherwise.
*/
public boolean isBinarySentence() {
return getConnective() != null && !hasConnective(Connective.NOT);
}
/**
* Allow a PLVisitor to walk over the abstract syntax tree represented by this
* Sentence.
*
* @param plv
* a Propositional Logic visitor.
* @param arg
* an optional argument for use by the visior.
* @return a result specific to the visitors behavior.
*/
public R accept(PLVisitor plv, A arg) {
R result = null;
if (isPropositionSymbol()) {
result = plv.visitPropositionSymbol((PropositionSymbol) this, arg);
} else if (isUnarySentence()) {
result = plv.visitUnarySentence((ComplexSentence) this, arg);
} else if (isBinarySentence()) {
result = plv.visitBinarySentence((ComplexSentence) this, arg);
}
return result;
}
/**
* Utility routine that will create a string representation of a given
* Sentence and place it inside brackets if it is a complex sentence that
* has lower precedence than this complex sentence.
*
* Note: this is a form of pretty printing, whereby we only add brackets in
* the concrete syntax representation as needed to ensure it can be parsed
* back again into an equivalent abstract syntax representation used here.
*
* @param parentConnective
* the connective of the parent sentence.
* @param childSentence
* a simpler child sentence.
* @return a String representation of the Sentence, bracketed if the parent
* based on its connective has higher precedence.
*/
public String bracketSentenceIfNecessary(Connective parentConnective,
Sentence childSentence) {
String result = null;
if (childSentence instanceof ComplexSentence) {
ComplexSentence cs = (ComplexSentence) childSentence;
if (cs.getConnective().getPrecedence() < parentConnective
.getPrecedence()) {
result = "(" + childSentence + ")";
}
}
if (result == null) {
result = childSentence.toString();
}
return result;
}
/**
* Create a disjunction of disjuncts.
* @param disjuncts
* the disjuncts from which to create the disjunction.
* @return a disjunction of the given disjuncts.
*/
public static Sentence newDisjunction(Sentence... disjuncts) {
return newDisjunction(Arrays.asList(disjuncts));
}
/**
* Create a disjunction of disjuncts.
* @param disjuncts
* the disjuncts from which to create the disjunction.
* @return a disjunction of the given disjuncts.
*/
public static Sentence newDisjunction(List disjuncts) {
if (disjuncts.size() == 0) {
return PropositionSymbol.FALSE;
}
else if (disjuncts.size() == 1) {
return disjuncts.get(0);
}
return new ComplexSentence(Util.first(disjuncts), Connective.OR, newDisjunction(Util.rest(disjuncts)));
}
/**
* Create a conjunction of conjuncts.
* @param conjuncts
* the conjuncts from which to create the conjunction.
* @return a conjunction of the given conjuncts.
*/
public static Sentence newConjunction(Sentence... conjuncts) {
return newConjunction(Arrays.asList(conjuncts));
}
/**
* Create a conjunction of conjuncts.
* @param conjuncts
* the conjuncts from which to create the conjunction.
* @return a conjunction of the given conjuncts.
*/
public static Sentence newConjunction(List conjuncts) {
if (conjuncts.size() == 0) {
return PropositionSymbol.TRUE;
}
else if (conjuncts.size() == 1) {
return conjuncts.get(0);
}
return new ComplexSentence(Util.first(conjuncts), Connective.AND, newConjunction(Util.rest(conjuncts)));
}
//
// PROTECTED
//
protected boolean hasConnective(Connective connective) {
// Note: can use '==' as Connective is an enum.
return getConnective() == connective;
}
}