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    }