public override bool CanMapVariables(Expression other) { if (other is Negation == false) return false; return Negated.CanMapVariables(((Negation)other).Negated); }
private static Expression CleanParentheses(Expression literal) { var negation = literal as Negation; if (negation != null) { Expression body = negation.Negated; return new Negation(CleanParentheses(body)); } var disjunction = literal as Disjunction; if (disjunction != null) { Expression[] ors = disjunction.Constituents; return new Disjunction(ors.Select(CleanParentheses).ToArray()); } var fact = literal as Fact; if (fact != null) { if (fact.RelationName == GameContainer.Parser.TokDistinct) { Term term1 = CleanParentheses(fact.GetTerm(0)); Term term2 = CleanParentheses(fact.GetTerm(1)); return new VariableFact(true, fact.RelationName, term1, term2); } return CleanParentheses(fact); } throw new Exception("Unexpected literal type in GdlCleaner"); }
public override Expression ApplySubstitution(Substitution sigma) { var newSentences = new Expression[_sentences.Length]; for (int i = 0; i < _sentences.Length; i++) newSentences[i] = _sentences[i].ApplySubstitution(sigma); return new Disjunction(newSentences); }
public static void VisitAll(Expression gdl, GdlVisitor visitor) { visitor.VisitGdl(gdl); var rule = gdl as Implication; if (rule != null) VisitRule(rule, visitor); else VisitLiteral(gdl, visitor); }
public override Expression ApplySubstitution(Substitution sigma) { var newSentences = new Expression[Conjuncts.Length]; for (int i = 0; i < Conjuncts.Length; i++) newSentences[i] = Conjuncts[i].ApplySubstitution(sigma); // TODO: remove duplicates if any were created during application of substitution return new Conjunction(false, newSentences); }
private Expression RenameLiteral(Expression literal, Dictionary<TermVariable, TermVariable> renamings) { var negation = literal as Negation; if (negation != null) return RenameNot(negation, renamings); var disjunction = literal as Disjunction; if (disjunction != null) return RenameOr(disjunction, renamings); var fact = (Fact)literal; return fact.RelationName == GameContainer.Parser.TokDistinct ? RenameDistinct(fact, renamings) : RenameSentence(fact, renamings); }
public override bool CanMapVariables(Expression other) { var sl = other as Conjunction; if (sl == null) return false; if (NumConjuncts() != sl.NumConjuncts()) return false; for (int i = 0; i < NumConjuncts(); i++) if (GetConjunct(i).CanMapVariables(sl.GetConjunct(i)) == false) return false; return true; }
public override bool CanMapVariables(Expression other) { var os = other as Disjunction; if (os == null) return false; if (NumDisjuncts() != os.NumDisjuncts()) return false; for (int i = 0; i < NumDisjuncts(); i++) if (GetDisjunct(i).CanMapVariables(os.GetDisjunct(i)) == false) return false; return true; }
private static Expression SubstituteLiteral(Expression literal, Substitution theta) { var negation = literal as Negation; if (negation != null) return SubstituteNot(negation, theta); var disjunction = literal as Disjunction; if (disjunction != null) return SubstituteOr(disjunction, theta); var fact = (Fact) literal; return fact.RelationName == GameContainer.Parser.TokDistinct ? SubstituteDistinct(fact, theta) : SubstituteSentence(fact, theta); }
public Disjunction(bool clone, Expression[] sentences) { if (sentences == null) _sentences = EmptySentences; else { if (clone) _sentences = (Expression[])sentences.Clone(); else _sentences = sentences; } _hashcode = 0; foreach (var conjunct in _sentences) _hashcode = _hashcode ^ conjunct.GetHashCode(); }
private static void ReinsertLiteralInRightPlace(List<Expression> ruleBody, Expression literalToReinsert) { HashSet<TermVariable> setVars = new HashSet<TermVariable>(); for (int i = 0; i < ruleBody.Count; i++) { Expression literal = ruleBody[i]; if (literal is Fact) { setVars.UnionWith(literal.VariablesOrEmpty); if (AllVarsInLiteralAlreadySet(literalToReinsert, setVars)) { ruleBody.Insert(i + 1, literalToReinsert); return; } } } }
private static void VisitLiteral(Expression literal, GdlVisitor visitor) { visitor.VisitLiteral(literal); var fact = literal as Fact; if (fact != null) { if (fact.RelationName == GameContainer.Parser.TokDistinct) VisitDistinct(fact, visitor); else VisitSentence(fact, visitor); } else if (literal is Negation) VisitNot((Negation) literal, visitor); else if (literal is Disjunction) VisitOr((Disjunction) literal, visitor); else throw new Exception("Unexpected GdlLiteral type " + literal.GetType()); }
/// <summary> /// Unification will try to find a mapping that will go from the second expression to the first. /// </summary> /// <param name="exp1">Expression to map to</param> /// <param name="exp2">Expression to map from</param> /// <returns>List of mappigs that satify. If none exist returns null</returns> public static Substitution Mgu(Expression exp1, Expression exp2) { if (exp1.GetType() != exp2.GetType()) return null; var fact1 = exp1 as Fact; if (fact1 != null) return Mgu(fact1, (Fact) exp2); var dis1 = exp1 as Disjunction; if (dis1 != null) return Mgu(dis1, (Disjunction) exp2); var neg1 = exp1 as Negation; if (neg1 != null) return Mgu(neg1, (Negation)exp2); throw new Exception("Unhandled type in unifier Mgu"); }
public static Expression[] SortDistincts(Expression[] expressions) { var varsSoFar = new HashSet<TermVariable>(); var heldDistincts = new List<Fact>(); var newAntes = new List<Expression>(); foreach (Expression ante in expressions) { var vars = ante.VariablesOrEmpty; var fact = ante as Fact; if (fact != null && fact.RelationName == GameContainer.Parser.TokDistinct) { if (vars.Any(v => !varsSoFar.Contains(v))) heldDistincts.Add(fact); else newAntes.Add(fact); } else { newAntes.Add(ante); int beforeCount = varsSoFar.Count; varsSoFar.UnionWith(vars); if (beforeCount != varsSoFar.Count) { for (int i = heldDistincts.Count - 1; i >= 0; i--) { var current = heldDistincts[i]; if (current.VariablesOrEmpty.All(v => varsSoFar.Contains(v))) { heldDistincts.RemoveAt(i); newAntes.Add(current); } } } } } return newAntes.ToArray(); }
private static bool Mgu(Expression exp1, Expression exp2, Substitution subsSoFar) { if (exp1.GetType() != exp2.GetType()) return false; var fact1 = exp1 as Fact; if (fact1 != null) return Mgu(fact1, (Fact)exp2, subsSoFar); var dis1 = exp1 as Disjunction; if (dis1 != null) return Mgu(dis1, (Disjunction)exp2, subsSoFar); var neg1 = exp1 as Negation; if (neg1 != null) return Mgu(neg1, (Negation)exp2, subsSoFar); throw new Exception("Unhandled type in unifier Mgu"); }
/// <summary> /// Can this expression be mapped to the other expression? An expression can be mapped to another expression /// if and only if there is a unifier from the one to the other that only makes variable assignments. /// /// <para/> /// Note that this relationship is <b>not</b> symmetric: one expression can be mapped to another expression, /// despite that second relation not mapping to the first. /// </summary> /// <param name="other">The expression with which to test mapping.</param> /// <returns>True if <b>this</b> can be mapped to <paramref name="other"/>.</returns> public abstract bool CanMapVariables(Expression other);
/// <summary> /// Same as Equal but doesn't matter about the order for Conjunctions and Disjunctions /// </summary> /// <param name="target"></param> /// <returns></returns> public abstract bool IsEquivalent(Expression target);
public override bool IsEquivalent(Expression target) { return Equals(target); }
public override bool IsEquivalent(Expression target) { if (!(target is Conjunction)) return false; foreach (Expression s in Constituents) { bool matched = target.Constituents.Any(t => t.IsEquivalent(s)); if (!matched) return false; } return true; }
private static bool AllVarsInLiteralAlreadySet(Expression literal, HashSet<TermVariable> setVars) { return literal.VariablesOrEmpty.All(setVars.Contains); }
private static Expression ReplaceRelationInLiteral(Expression literal, ISentenceForm trueForm) { var sentence = literal as Fact; if (sentence != null) if (trueForm.Matches(sentence)) { var terms = sentence.GetTerms(); var function = terms[0] as TermFunction; Debug.Assert(function != null); return new VariableFact(true, function.FunctionName, function.Arguments); } else return literal; var not = literal as Negation; if (not != null) return new Negation(ReplaceRelationInLiteral(not.Negated, trueForm)); var or = literal as Disjunction; if (or != null) { var newOrBody = new List<Expression>(); for (int i = 0; i < or.GetDisjuncts().Count(); i++) newOrBody.Add(ReplaceRelationInLiteral(or.Constituents[i], trueForm)); return new Disjunction(newOrBody.ToArray()); } throw new Exception(string.Format("Unanticipated GDL literal type {0} encountered in Relationizer", literal.GetType())); }
public Implication ExamineRule(GdlList rule) { // First element is the IMPLIEDBY token; ignore it. // Second element is the head of the rule. It's a relation (fact). var head = (Fact)ExamineRelation(rule[1]); // Everything thereafter are the antecedent relations. var conjuncts = new Expression[rule.Arity - 1]; // Create the conjunct list for (int i = 2; i < rule.Size; i++) conjuncts[i - 2] = ExamineRelation(rule[i]); conjuncts = DistinctSorter.SortDistincts(conjuncts); // Create a rule structure and add it to our list. return new Implication(false, head, conjuncts); }
private Expression ExamineListRelation(GdlList relation, int relName) { // First: check to see if this is a logical operator, i.e. one of not/or/and if (relName == _parser.TokNotOp) // The next element must be a sentence return new Negation(ExamineRelation(relation[1])); if (relName == _parser.TokOrOp) { // all the rest of the elements are relations (sentences), not terms. var disjuncts = new Expression[relation.Arity]; for (int i = 1; i <= relation.Arity; i++) disjuncts[i - 1] = ExamineRelation(relation[i]); return new Disjunction(false, disjuncts); } // Second case: normal relation. //TODO: Make sure this symbol isn't a function/object symbol already. //if (IsFunctionSymbol(relName) || IsObjectSymbol(relName)) // throw new Exception(string.Format("Symbol '{0}' ({1}) already exists, but not as a relation symbol!", relName, _parser.SymbolTable[relName])); // Add the relation name to our list of relation symbols. AddRelationSymbol(relName, relation.Arity); // Examine each term of the relation for (int i = 1; i <= relation.Arity; i++) ExamineTerm(relation[i]); // Convert the relation to a (ground or variable) fact. return Fact.FromExpression(relation); }
public static Expression Substitute(Expression literal, Substitution theta) { return SubstituteLiteral(literal, theta); }
/// <summary> /// if a conjunction contains a single conjunction as an expression return its conjects rather then the single conjunction /// </summary> /// <param name="conjuncts"></param> /// <returns></returns> static Expression[] UnwrapToBaseExpressions(Expression[] conjuncts) { if (conjuncts.Length != 1) return conjuncts; var conjunction = conjuncts[0] as Conjunction; return conjunction != null ? UnwrapToBaseExpressions(conjunction.Conjuncts) : conjuncts; }
public override Expression Uniquefy(Dictionary<TermVariable, TermVariable> varMap) { var newSentences = new Expression[Conjuncts.Length]; for (int i = 0; i < Conjuncts.Length; i++) newSentences[i] = Conjuncts[i].Uniquefy(varMap); return new Conjunction(false, newSentences); }
public Negation(Expression negated) { Negated = negated; }
/// <summary> /// If the expression is a Negation or Disjunction then expand it one level - otherwise just return it /// </summary> private static List<Expression> ExpandFirstOr(Expression gdl) { var not = gdl as Negation; if (not != null) { Expression negated = not.Negated; if (negated is Disjunction) throw new Exception("This should have been cleaned up by the gdl cleaner"); List<Expression> expandedChild = ExpandFirstOr(negated); return expandedChild.Select(g => new Negation(g)).Cast<Expression>().ToList(); } var or = gdl as Disjunction; if (or != null) return or.GetDisjuncts().ToList(); var fact = gdl as Fact; if (fact != null) //Can safely be ignored, won't contain 'or' return new List<Expression> { gdl }; if (gdl is Implication) throw new Exception("An implication has been nested - this shouldn't occur"); throw new Exception("An expression type hasn't been handled - possibly a conjunction?"); }
public Conjunction(Expression[] sentences) : this(true, sentences) { }
public override bool CanMapVariables(Expression other) { if (other is VariableFact == false) return false; var vf = (VariableFact)other; if (RelationName != vf.RelationName || Arity != vf.Arity) return false; var varMappings = new Dictionary<TermVariable, TermVariable>(); for (int i = 0; i < Arity; i++) if (GetTerm(i).CanMapVariables(vf.GetTerm(i), varMappings) == false) return false; return true; }