public object VisitConnectedSentence(ConnectedSentence sentence, object arg) { ArgData ad = (ArgData)arg; ISentence first = sentence.First; ISentence second = sentence.Second; first.Accept(this, arg); if (Connectors.IsAnd(sentence.Connector)) { 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 var alpha = (ISentence)sentence.First.Accept(this, arg); var beta = (ISentence)sentence.Second.Accept(this, arg); // (alpha V (beta ^ gamma)) equivalent to // ((alpha V beta) ^ (alpha V gamma)) if (Connectors.IsOr(sentence.Connector) && beta is ConnectedSentence) { var betaAndGamma = (ConnectedSentence)beta; if (Connectors.IsAnd(betaAndGamma.Connector)) { beta = betaAndGamma.First; var gamma = betaAndGamma.Second; return(new ConnectedSentence(Connectors.And, (ISentence)(new ConnectedSentence(Connectors.Or, alpha, beta)).Accept(this, arg), (ISentence)(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.Connector) && alpha is ConnectedSentence) { var alphaAndGamma = (ConnectedSentence)alpha; if (Connectors.IsAnd(alphaAndGamma.Connector)) { alpha = alphaAndGamma.First; var gamma = alphaAndGamma.Second; return(new ConnectedSentence( Connectors.And, (ISentence)(new ConnectedSentence(Connectors.Or, alpha, beta)).Accept(this, arg), (ISentence)(new ConnectedSentence(Connectors.Or, gamma, beta)).Accept(this, arg))); } } return(new ConnectedSentence(sentence.Connector, 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: ISentence negated = notSentence.Negated; // ~(~alpha) equivalent to alpha (double negation elimination) if (negated is NotSentence) { return(((NotSentence)negated).Negated.Accept(this, arg)); } if (negated is ConnectedSentence) { ConnectedSentence negConnected = (ConnectedSentence)negated; ISentence alpha = negConnected.First; ISentence beta = negConnected.Second; // ~(alpha ^ beta) equivalent to (~alpha V ~beta) (De Morgan) if (Connectors.IsAnd(negConnected.Connector)) { // I need to ensure the ~s are moved in deeper ISentence notAlpha = (ISentence)(new NotSentence(alpha)).Accept( this, arg); ISentence notBeta = (ISentence)(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.Connector)) { // I need to ensure the ~s are moved in deeper ISentence notAlpha = (ISentence)(new NotSentence(alpha)).Accept( this, arg); ISentence notBeta = (ISentence)(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 ISentence notP = (ISentence)(new NotSentence(negQuantified .Quantified)).Accept(this, arg); // ~ForAll x p becomes Exists x ~p if (Quantifiers.IsForall(negQuantified.Quantifier)) { return(new QuantifiedSentence(Quantifiers.Exists, negQuantified .Variables, notP)); } // ~Exists x p becomes ForAll x ~p if (Quantifiers.IsExists(negQuantified.Quantifier)) { return(new QuantifiedSentence(Quantifiers.ForAll, negQuantified .Variables, notP)); } } return(new NotSentence((ISentence)negated.Accept(this, arg))); }