001 /* 002 * Created on Sep 2, 2003 by Ravi Mohan 003 * 004 */ 005 package aima.logic.propositional.algorithms; 006 007 import java.util.HashSet; 008 import java.util.Hashtable; 009 import java.util.Iterator; 010 import java.util.Set; 011 012 import aima.logic.propositional.parsing.PLVisitor; 013 import aima.logic.propositional.parsing.ast.BinarySentence; 014 import aima.logic.propositional.parsing.ast.FalseSentence; 015 import aima.logic.propositional.parsing.ast.MultiSentence; 016 import aima.logic.propositional.parsing.ast.Sentence; 017 import aima.logic.propositional.parsing.ast.Symbol; 018 import aima.logic.propositional.parsing.ast.TrueSentence; 019 import aima.logic.propositional.parsing.ast.UnarySentence; 020 021 /** 022 * @author Ravi Mohan 023 * 024 */ 025 026 public class Model implements PLVisitor { 027 028 Hashtable<String, Boolean> h = new Hashtable<String, Boolean>(); 029 030 public Boolean getStatus(Symbol symbol) { 031 Object status = h.get(symbol.getValue()); 032 if (status != null) { 033 return (Boolean) status; 034 } 035 return null; 036 } 037 038 public boolean isTrue(Symbol symbol) { 039 Object status = h.get(symbol.getValue()); 040 if (status != null) { 041 return ((Boolean) status).booleanValue(); 042 } 043 return false; 044 } 045 046 public boolean isFalse(Symbol symbol) { 047 Object status = h.get(symbol.getValue()); 048 if (status != null) { 049 return !((Boolean) status).booleanValue(); 050 } 051 return false; 052 } 053 054 private boolean isUnknown(Symbol s) { 055 Object o = h.get(s.getValue()); 056 return (o == null); 057 058 } 059 060 public Model extend(Symbol symbol, boolean b) { 061 Model m = new Model(); 062 return extend(symbol.getValue(), b); 063 } 064 065 public Model extend(String s, boolean b) { 066 Model m = new Model(); 067 Iterator<String> i = this.h.keySet().iterator(); 068 while (i.hasNext()) { 069 String key = i.next(); 070 Boolean value = h.get(key); 071 String newKey = new String((key).toCharArray()); 072 if (value == null) { 073 throw new RuntimeException(); 074 } 075 m.h.put(key, value); 076 } 077 m.h.put(s, new Boolean(b)); 078 return m; 079 } 080 081 public void print() { 082 Iterator i = h.keySet().iterator(); 083 while (i.hasNext()) { 084 Object key = i.next(); 085 Object value = h.get(key); 086 System.out.print(key + " = " + value + " "); 087 // System.out.print (key +" = " +((Boolean)value).booleanValue()); 088 } 089 System.out.println(); 090 } 091 092 public boolean isTrue(Sentence clause) { 093 Object result = clause.accept(this, null); 094 return (result == null) ? false 095 : ((Boolean) result).booleanValue() == true; 096 } 097 098 public boolean isFalse(Sentence clause) { 099 Object o = clause.accept(this, null); 100 return (o != null) ? ((Boolean) o).booleanValue() == false : false; 101 } 102 103 public boolean isUnknown(Sentence clause) { // TODO TEST WELL 104 Object o = clause.accept(this, null); 105 return (o == null); 106 } 107 108 public Model flip(Symbol s) { 109 if (isTrue(s)) { 110 return extend(s, false); 111 } 112 if (isFalse(s)) { 113 return extend(s, true); 114 } 115 return this; 116 } 117 118 @Override 119 public String toString() { 120 return h.toString(); 121 } 122 123 // VISITOR METHODS 124 public Object visitSymbol(Symbol s, Object arg) { 125 return getStatus(s); 126 } 127 128 public Object visitTrueSentence(TrueSentence ts, Object arg) { 129 return Boolean.TRUE; 130 } 131 132 public Object visitFalseSentence(FalseSentence fs, Object arg) { 133 return Boolean.FALSE; 134 } 135 136 public Object visitNotSentence(UnarySentence fs, Object arg) { 137 Object negatedValue = fs.getNegated().accept(this, null); 138 if (negatedValue != null) { 139 return new Boolean(!((Boolean) negatedValue).booleanValue()); 140 } else { 141 return null; 142 } 143 } 144 145 public Object visitBinarySentence(BinarySentence bs, Object arg) { 146 Object firstValue = bs.getFirst().accept(this, null); 147 Object secondValue = bs.getSecond().accept(this, null); 148 if ((firstValue == null) || (secondValue == null)) { // strictly not 149 // true for or/and 150 // -FIX later 151 return null; 152 } else { 153 String operator = bs.getOperator(); 154 if (operator.equals("AND")) { 155 return evaluateAnd((Boolean) firstValue, (Boolean) secondValue); 156 } 157 if (operator.equals("OR")) { 158 return evaluateOr((Boolean) firstValue, (Boolean) secondValue); 159 } 160 if (operator.equals("=>")) { 161 return evaluateImplied((Boolean) firstValue, 162 (Boolean) secondValue); 163 } 164 if (operator.equals("<=>")) { 165 return evaluateBiConditional((Boolean) firstValue, 166 (Boolean) secondValue); 167 } 168 return null; 169 } 170 } 171 172 public Object visitMultiSentence(MultiSentence fs, Object argd) { 173 // TODO remove this? 174 return null; 175 } 176 177 private Boolean evaluateAnd(Boolean firstValue, Boolean secondValue) { 178 if ((firstValue.equals(Boolean.TRUE)) 179 && (secondValue.equals(Boolean.TRUE))) { 180 return Boolean.TRUE; 181 } else { 182 return Boolean.FALSE; 183 } 184 } 185 186 private Boolean evaluateOr(Boolean firstValue, Boolean secondValue) { 187 if ((firstValue.equals(Boolean.TRUE)) 188 || (secondValue.equals(Boolean.TRUE))) { 189 return Boolean.TRUE; 190 } else { 191 return Boolean.FALSE; 192 } 193 } 194 195 private Boolean evaluateImplied(Boolean firstValue, Boolean secondValue) { 196 if ((firstValue.equals(Boolean.TRUE)) 197 && (secondValue.equals(Boolean.FALSE))) { 198 return Boolean.FALSE; 199 } else { 200 return Boolean.TRUE; 201 } 202 } 203 204 private Boolean evaluateBiConditional(Boolean firstValue, 205 Boolean secondValue) { 206 if (firstValue.equals(secondValue)) { 207 return Boolean.TRUE; 208 } else { 209 return Boolean.FALSE; 210 } 211 } 212 213 public Set<Symbol> getAssignedSymbols() { 214 Set<Symbol> set = new HashSet<Symbol>(); 215 Iterator i = this.h.keySet().iterator(); 216 while (i.hasNext()) { 217 Symbol key = new Symbol((String) i.next()); 218 if (!(isUnknown(key))) { 219 set.add(key); 220 } 221 } 222 return set; 223 } 224 225 public boolean matches(String variable, boolean value) { 226 if (value) { 227 return isTrue(new Symbol(variable)); 228 } else if (!(value)) { 229 return isFalse(new Symbol(variable)); 230 } 231 return false; 232 } 233 234 }