public Object visitConnectedSentence(ConnectedSentence sentence, Object arg) { ArgData ad = (ArgData)arg; Sentence first = sentence.getFirst(); Sentence second = sentence.getSecond(); first.accept(this, arg); if (Connectors.isAND(sentence.getConnector())) { ad.clauses.Add(new Clause()); } second.accept(this, arg); return(sentence); }
public Object visitConnectedSentence(ConnectedSentence sentence, Object arg) { // Distribute V over ^: // This will cause flattening out of nested ^s and Vs Sentence alpha = (Sentence)sentence.getFirst().accept(this, arg); Sentence beta = (Sentence)sentence.getSecond().accept(this, arg); // (alpha V (beta ^ gamma)) equivalent to // ((alpha V beta) ^ (alpha V gamma)) if (Connectors.isOR(sentence.getConnector()) && beta is ConnectedSentence) { ConnectedSentence betaAndGamma = (ConnectedSentence)beta; if (Connectors.isAND(betaAndGamma.getConnector())) { beta = betaAndGamma.getFirst(); Sentence gamma = betaAndGamma.getSecond(); return(new ConnectedSentence(Connectors.AND, (Sentence)(new ConnectedSentence(Connectors.OR, alpha, beta)).accept(this, arg), (Sentence)(new ConnectedSentence(Connectors.OR, alpha, gamma)).accept(this, arg))); } } // ((alpha ^ gamma) V beta) equivalent to // ((alpha V beta) ^ (gamma V beta)) if (Connectors.isOR(sentence.getConnector()) && alpha is ConnectedSentence) { ConnectedSentence alphaAndGamma = (ConnectedSentence)alpha; if (Connectors.isAND(alphaAndGamma.getConnector())) { alpha = alphaAndGamma.getFirst(); Sentence gamma = alphaAndGamma.getSecond(); return(new ConnectedSentence(Connectors.AND, (Sentence)(new ConnectedSentence(Connectors.OR, alpha, beta)).accept(this, arg), (Sentence)(new ConnectedSentence(Connectors.OR, gamma, beta)).accept(this, arg))); } } return(new ConnectedSentence(sentence.getConnector(), alpha, beta)); }
public Object visitNotSentence(NotSentence notSentence, Object arg) { // CNF requires NOT (~) to appear only in literals, so we 'move ~ // inwards' by repeated application of the following equivalences: Sentence negated = notSentence.getNegated(); // ~(~alpha) equivalent to alpha (double negation elimination) if (negated is NotSentence) { return(((NotSentence)negated).getNegated().accept(this, arg)); } if (negated is ConnectedSentence) { ConnectedSentence negConnected = (ConnectedSentence)negated; Sentence alpha = negConnected.getFirst(); Sentence beta = negConnected.getSecond(); // ~(alpha ^ beta) equivalent to (~alpha V ~beta) (De Morgan) if (Connectors.isAND(negConnected.getConnector())) { // I need to ensure the ~s are moved in deeper Sentence notAlpha = (Sentence)(new NotSentence(alpha)).accept( this, arg); Sentence notBeta = (Sentence)(new NotSentence(beta)).accept( this, arg); return(new ConnectedSentence(Connectors.OR, notAlpha, notBeta)); } // ~(alpha V beta) equivalent to (~alpha ^ ~beta) (De Morgan) if (Connectors.isOR(negConnected.getConnector())) { // I need to ensure the ~s are moved in deeper Sentence notAlpha = (Sentence)(new NotSentence(alpha)).accept( this, arg); Sentence notBeta = (Sentence)(new NotSentence(beta)).accept( this, arg); return(new ConnectedSentence(Connectors.AND, notAlpha, notBeta)); } } // in addition, rules for negated quantifiers: if (negated is QuantifiedSentence) { QuantifiedSentence negQuantified = (QuantifiedSentence)negated; // I need to ensure the ~ is moved in deeper Sentence notP = (Sentence)(new NotSentence(negQuantified .getQuantified())).accept(this, arg); // ~FORALL x p becomes EXISTS x ~p if (Quantifiers.isFORALL(negQuantified.getQuantifier())) { return(new QuantifiedSentence(Quantifiers.EXISTS, negQuantified .getVariables(), notP)); } // ~EXISTS x p becomes FORALL x ~p if (Quantifiers.isEXISTS(negQuantified.getQuantifier())) { return(new QuantifiedSentence(Quantifiers.FORALL, negQuantified .getVariables(), notP)); } } return(new NotSentence((Sentence)negated.accept(this, arg))); }