001 package aima.logic.fol.kb.data; 002 003 import aima.logic.fol.parsing.ast.AtomicSentence; 004 import aima.logic.fol.parsing.ast.Term; 005 006 /** 007 * Artificial Intelligence A Modern Approach (2nd Edition): page 204. 008 * 009 * A literal is either an atomic sentence (a positive literal) or 010 * a negated atomic sentence (a negative literal). 011 * 012 */ 013 014 /** 015 * @author Ciaran O'Reilly 016 * 017 */ 018 public class Literal { 019 private AtomicSentence atom = null; 020 private boolean negativeLiteral = false; 021 private String strRep = null; 022 private int hashCode = 0; 023 024 public Literal(AtomicSentence atom) { 025 this.atom = atom; 026 } 027 028 public Literal(AtomicSentence atom, boolean negated) { 029 this.atom = atom; 030 this.negativeLiteral = negated; 031 } 032 033 public Literal newInstance(AtomicSentence atom) { 034 return new Literal(atom, negativeLiteral); 035 } 036 037 public boolean isPositiveLiteral() { 038 return !negativeLiteral; 039 } 040 041 public boolean isNegativeLiteral() { 042 return negativeLiteral; 043 } 044 045 public AtomicSentence getAtomicSentence() { 046 return atom; 047 } 048 049 public String toString() { 050 if (null == strRep) { 051 StringBuilder sb = new StringBuilder(); 052 if (isNegativeLiteral()) { 053 sb.append("~"); 054 } 055 sb.append(getAtomicSentence().toString()); 056 strRep = sb.toString(); 057 } 058 059 return strRep; 060 } 061 062 @Override 063 public boolean equals(Object o) { 064 065 if (this == o) { 066 return true; 067 } 068 if (o.getClass() != getClass()) { 069 // This prevents ReducedLiterals 070 // being treated as equivalent to 071 // normal Literals. 072 return false; 073 } 074 if (!(o instanceof Literal)) { 075 return false; 076 } 077 Literal l = (Literal) o; 078 return l.isPositiveLiteral() == isPositiveLiteral() 079 && l.getAtomicSentence().getSymbolicName().equals( 080 atom.getSymbolicName()) 081 && l.getAtomicSentence().getArgs().equals(atom.getArgs()); 082 } 083 084 @Override 085 public int hashCode() { 086 if (0 == hashCode) { 087 hashCode = 17; 088 hashCode = 37 * hashCode + (getClass().getSimpleName().hashCode()) 089 + (isPositiveLiteral() ? "+".hashCode() : "-".hashCode()) 090 + atom.getSymbolicName().hashCode(); 091 for (Term t : atom.getArgs()) { 092 hashCode = 37 * hashCode + t.hashCode(); 093 } 094 } 095 return hashCode; 096 } 097 }