public void Add_Variable_Tag_SimpleWFN(string n1, string tag, string expectedResult, Refactorization r) { string result = string.Empty; if(r == Refactorization.New) { SimpleName name = new SimpleName(n1); SimpleName resName = null; for (long i = 0; i < reps; i++) { resName = SimpleWFN.AddVariableTag(name, tag); } result = resName.ToString(); } else if(r == Refactorization.Current) { Name name = Name.BuildName(n1); Name resName = null; for (long i = 0; i < reps; i++) { resName = name.ReplaceUnboundVariables("_tag"); } result = RemoveWhiteSpace(resName.ToString()); } Assert.AreEqual(expectedResult, result); }
public void Unify_NonUnifiableNames_False(string n1, string n2, Refactorization r) { IEnumerable<Substitution> bindings = new List<Substitution>(); var isUnifiable = true; if (r == Refactorization.Current) { var name1 = Name.BuildName(n1); var name2 = Name.BuildName(n2); for (int i = 0; i < unifierReps; i++) { isUnifiable = Unifier.Unify(name1, name2, out bindings); } }else if(r == Refactorization.New) { var name1 = new SimpleName(n1); var name2 = new SimpleName(n2); for (int i = 0; i < unifierReps; i++) { isUnifiable = SimpleUnifier.Unify(name1, name2, out bindings); } } Assert.That(!isUnifiable); Assert.That(bindings == null); }
//return the idx jump on the valName or -1 if it can't add the substitution private static int FindSubsAux(Literal var, Literal val, SimpleName valName, IDictionary <string, Substitution> bindings) { //first, analyse if the value is a composed name or a single parameter string valDescription; int valLiteralCount; if (val.type == LiteralType.Root) { SimpleName auxName = null; auxName = SimpleWFN.BuildNameFromContainedLiteral(valName, val); valDescription = auxName.ToString(); valLiteralCount = auxName.literals.Count; } else { valDescription = val.description; valLiteralCount = 1; } //check if a binding for the same variable already exists Substitution existingSub = null; bindings.TryGetValue(var.description, out existingSub); if (existingSub != null) { if (existingSub.SubValue.ToString().RemoveWhiteSpace().EqualsIgnoreCase(valDescription)) { return(valLiteralCount); } else { return(-1); } } //if there was no existing binding to the variable try { bindings[var.description] = new Substitution(var.description, valDescription); return(valLiteralCount); } catch (BadSubstitutionException) { return(-1); } }
public static SimpleName MakeGround(SimpleName n, Dictionary <string, SimpleName> bindings) { var literals = new List <Literal>(); foreach (var l in n.literals) { if (bindings.ContainsKey(l.description)) { var nameValue = bindings[l.description]; var subName = new SimpleName(nameValue.literals); foreach (var subL in subName.literals) { subL.depth += l.depth; } literals.AddRange(subName.literals); } else { literals.Add(l); } } return(new SimpleName(literals)); }
/// <summary> /// Unifying Method, receives two WellFormedNames and tries /// to find a list of Substitutions that will make /// both names syntatically equal. The algorithm performs Occur Check, /// as such the unification of [X] and Luke([X]) will allways fail. /// /// The method goes on each symbol (for both names) at a time, and tries to find /// a substitution between them. Take into account that the Unification between /// [X](John,Paul) and Friend(John,[X]) fails because the algorithm considers [X] /// to be the same variable /// </summary> /// <see cref="FAtiMA.Core.WellFormedNames.Substitution"/> /// <see cref="FAtiMA.Core.WellFormedNames.Name"/> /// <param name="name1">The first Name</param> /// <param name="name2">The second Name</param> /// <param name="bindings">The out paramenter for the founded substitutions</param> /// <returns>True if the names are unifiable, in this case the bindings list will contain the found Substitutions, otherwise it will be empty</returns> public static bool Unify(SimpleName name1, SimpleName name2, out IEnumerable <Substitution> bindings) { bindings = null; if (name1 == null || name2 == null) { return(false); } if (SimpleWFN.IsGrounded(name1) && SimpleWFN.IsGrounded(name2)) { if (SimpleWFN.Match(name1, name2)) { bindings = Enumerable.Empty <Substitution>(); return(true); } else { return(false); } } bindings = FindSubst(name1, name2); return(bindings != null); }
//return the idx jump on the valName or -1 if it can't add the substitution private static int FindSubsAux(Literal var, Literal val, SimpleName valName, IDictionary<string, Substitution> bindings) { string valDescription; SimpleName auxName = null; if (val.type == LiteralType.Root) { auxName = SimpleWFN.BuildNameFromContainedLiteral(valName, val); valDescription = auxName.ToString(); } else { valDescription = val.description; } //check if a binding for the same variable already exists Substitution existingSub = null; bindings.TryGetValue(var.description, out existingSub); if (existingSub != null) { if (existingSub.Value.ToString().RemoveWhiteSpace().EqualsIgnoreCase("valDescription")) return 1; else return -1; } //if there was no existing binding to the variable try { bindings[var.description] = new Substitution(var.description, valDescription); if (var.type == LiteralType.Param && val.type == LiteralType.Root) return auxName.literals.Count; else return 1; } catch (BadSubstitutionException) { return -1; } }
private static IEnumerable<Substitution> FindSubst(SimpleName n1, SimpleName n2) { // SubstitutionSet bindings = new SubstitutionSet(); Dictionary<string, Substitution> bindings = new Dictionary<string, Substitution>(); var arrayLit1 = n1.literals.ToArray(); var arrayLit2 = n2.literals.ToArray(); var idx1 = 0; var idx2 = 0; do { var l1 = arrayLit1[idx1]; var l2 = arrayLit2[idx2]; //neither literal is a variable if (!SimpleWFN.IsVariable(l1) && !SimpleWFN.IsVariable(l2)) { if (l1.description.EqualsIgnoreCase(l2.description)) { idx1++; idx2++; continue; } else { return null; } } //both literals are a variable if (SimpleWFN.IsVariable(l1) && SimpleWFN.IsVariable(l2)) { if (!l1.description.EqualsIgnoreCase(l2.description)) { if (bindings.ContainsKey(l1.description)) return null; bindings[l1.description] = new Substitution(l1.description, l2.description); } idx1++; idx2++; continue; } //only l1 is a variable if (SimpleWFN.IsVariable(l1) && !SimpleWFN.IsVariable(l2)) { var res = FindSubsAux(l1, l2, n2, bindings); if (res == -1) return null; else { idx1++; idx2 += res; continue; } } //only l2 is a variable if (!SimpleWFN.IsVariable(l1) && SimpleWFN.IsVariable(l2)) { var res = FindSubsAux(l2, l1, n1, bindings); if (res == -1) return null; else { idx1 += res; idx2++; continue; } } throw new Exception("Unexpected Situation"); } while (idx1 < arrayLit1.Length && idx2 < arrayLit2.Length); if (idx1 == arrayLit1.Length && idx2 == arrayLit2.Length) { return bindings.Values; // full match } else { return null; // only partial match }; }
//not really needed for now but might be useful for building sub names public static SimpleName BuildNameFromNLiteral(SimpleName name, int n) { if (name.literals[n].type != LiteralType.Root) return new SimpleName(name.literals[n].description); var list = name.literals.Skip(n + 1).TakeWhile(l => l.depth > name.literals[n].depth); return new SimpleName(list.Prepend(name.literals[n])); }
private static IEnumerable <Substitution> FindSubst(SimpleName n1, SimpleName n2) { // SubstitutionSet bindings = new SubstitutionSet(); Dictionary <string, Substitution> bindings = new Dictionary <string, Substitution>(); var idx1 = 0; var idx2 = 0; do { var l1 = n1.literals[idx1]; var l2 = n2.literals[idx2]; //neither literal is a variable if (!SimpleWFN.IsVariable(l1) && !SimpleWFN.IsVariable(l2)) { if (l1.description.EqualsIgnoreCase(l2.description)) { idx1++; idx2++; continue; } else { return(null); } } //both literals are a variable if (SimpleWFN.IsVariable(l1) && SimpleWFN.IsVariable(l2)) { if (!l1.description.EqualsIgnoreCase(l2.description)) { if (bindings.ContainsKey(l1.description)) { return(null); } bindings[l1.description] = new Substitution(l1.description, l2.description); } idx1++; idx2++; continue; } //only l1 is a variable if (SimpleWFN.IsVariable(l1) && !SimpleWFN.IsVariable(l2)) { var res = FindSubsAux(l1, l2, n2, bindings); if (res == -1) { return(null); } else { idx1++; idx2 += res; continue; } } //only l2 is a variable if (!SimpleWFN.IsVariable(l1) && SimpleWFN.IsVariable(l2)) { var res = FindSubsAux(l2, l1, n1, bindings); if (res == -1) { return(null); } else { idx1 += res; idx2++; continue; } } throw new Exception("Unexpected Situation"); } while (idx1 < n1.literals.Count && idx2 < n2.literals.Count); if (idx1 == n1.literals.Count && idx2 == n2.literals.Count) { return(bindings.Values); // full match } else { return(null); // only partial match }; }
public static bool HasSelf(SimpleName name) { return(name.literals.Any(l => l.description == Name.SELF_STRING)); }
public static IEnumerable <Literal> GetVariables(SimpleName name) { return(name.literals.Where(l => IsVariable(l))); }
public static bool HasSelf(SimpleName name) { return name.literals.Any(l => l.description == Name.SELF_STRING); }
public static IEnumerable<Literal> GetVariables(SimpleName name) { return name.literals.Where(l => IsVariable(l)); }
public static int GetNumberOfTerms(SimpleName name) { return name.literals.Count(l => l.depth <= 1); }
//not really needed for now but might be useful for building sub names public static List<SimpleName> GetAllComposedNames(SimpleName name) { List<SimpleName> res = new List<SimpleName>(); for (int i = 1; i < name.literals.Count; i++) { if (name.literals.ElementAt(i).type == LiteralType.Root) { res.Add(BuildNameFromNLiteral(name, i)); } } return res; }
/// <summary> /// Verifies if a specific variable is contained inside this Name. /// </summary> /// <param name="variable">The variable Name we want to verify</param> /// <exception cref="ArgumentException">Thrown if the given argument is not a variable definition.</exception> public static bool ContainsVariable(SimpleName name, string variable) { var v = Name.BuildName(variable); if (!v.IsVariable) throw new ArgumentException("Invalid variable", variable); return GetVariables(name).Any(l => l.description.EqualsIgnoreCase(variable)); }
public static bool ContainsUniversal(SimpleName name) { return name.literals.Any(l => l.description == Name.UNIVERSAL_STRING); }
public static int GetNumberOfTerms(SimpleName name) { return(name.literals.Count(l => l.depth <= 1)); }
public static bool ContainsUniversal(SimpleName name) { return(name.literals.Any(l => l.description == Name.UNIVERSAL_STRING)); }
public static bool IsGrounded(SimpleName name) { return name.isGrounded; }
public static bool IsGrounded(SimpleName name) { return(name.isGrounded); }
public static SimpleName MakeGround(SimpleName n, Dictionary<string, SimpleName> bindings) { var literals = new List<Literal>(); foreach (var l in n.literals) { if (bindings.ContainsKey(l.description)) { var nameValue = bindings[l.description]; var subName = new SimpleName(nameValue.literals); foreach(var subL in subName.literals) { subL.depth += l.depth; } literals.AddRange(subName.literals); } else { literals.Add(l); } } return new SimpleName(literals); }
public static bool Match(SimpleName n1, SimpleName n2) { if (SimpleWFN.GetNumberOfTerms(n1) != SimpleWFN.GetNumberOfTerms(n2)) { return(false); } var idx1 = 0; var idx2 = 0; do { var l1 = n1.literals[idx1]; var l2 = n2.literals[idx2]; //auxiliary variables bool typesMatch = l1.type == l2.type; bool l1IsUniv = l1.description == Name.UNIVERSAL_STRING; bool l2IsUniv = l2.description == Name.UNIVERSAL_STRING; bool existsUniversal = l1IsUniv || l2IsUniv; //The easy matching scenario is when both types match if (typesMatch) { if (existsUniversal || l1.description.EqualsIgnoreCase(l2.description)) { idx1++; idx2++; continue; } return(false); //no universals and different descritions } //eg. matching S with S(A) if (!typesMatch && !existsUniversal) { return(false); } //l1 is a universal and l2 has a different type if (!typesMatch && l1IsUniv) { //l1 is a universal parameter and n2 is a root if (l1.type == LiteralType.Param) { // the index on n2 must jump until it reaches the depth of l1 again idx2 += FindJumpUntilDepthN(n2.literals, idx2, l1.depth); idx1++; continue; } //a root universal never matches any parameter except a universal if (l1.type == LiteralType.Root && !l2IsUniv) { return(false); } } //the last case is when l2 is the universal if (!typesMatch && l2IsUniv) { if (l2.type == LiteralType.Param) { // the index on n2 must jump until it reaches the depth of n1 again idx1 += FindJumpUntilDepthN(n1.literals, idx1, l2.depth); idx2++; continue; } //a root universal never matches any parameter except a universal if (l2.type == LiteralType.Root && !l1IsUniv) { return(false); } } } while (idx1 < n1.literals.Count && idx2 < n2.literals.Count); if (idx1 == n1.literals.Count && idx2 == n2.literals.Count) { return(true); // full match } else { return(false); // only partial match } }
public static bool Match(SimpleName n1, SimpleName n2) { if (SimpleWFN.GetNumberOfTerms(n1) != SimpleWFN.GetNumberOfTerms(n2)) return false; var idx1 = 0; var idx2 = 0; do { var l1 = n1.literals[idx1]; var l2 = n2.literals[idx2]; //auxiliary variables bool typesMatch = l1.type == l2.type; bool l1IsUniv = l1.description == Name.UNIVERSAL_STRING; bool l2IsUniv = l2.description == Name.UNIVERSAL_STRING; bool existsUniversal = l1IsUniv || l2IsUniv; //The easy matching scenario is when both types match if (typesMatch) { if (existsUniversal || l1.description.EqualsIgnoreCase(l2.description)) { idx1++; idx2++; continue; } return false; //no universals and different descritions } //eg. matching S with S(A) if (!typesMatch && !existsUniversal) { return false; } //l1 is a universal and l2 has a different type if (!typesMatch && l1IsUniv) { //l1 is a universal parameter and n2 is a root if (l1.type == LiteralType.Param) { // the index on n2 must jump until it reaches the depth of l1 again idx2 += FindJumpUntilDepthN(n2.literals, idx2, l1.depth); idx1++; continue; } //a root universal never matches any parameter except a universal if (l1.type == LiteralType.Root && !l2IsUniv) return false; } //the last case is when l2 is the universal if (!typesMatch && l2IsUniv) { if (l2.type == LiteralType.Param) { // the index on n2 must jump until it reaches the depth of n1 again idx1 += FindJumpUntilDepthN(n1.literals, idx1, l2.depth); idx2++; continue; } //a root universal never matches any parameter except a universal if (l2.type == LiteralType.Root && !l1IsUniv) return false; } } while (idx1 < n1.literals.Count && idx2 < n2.literals.Count); if (idx1 == n1.literals.Count && idx2 == n2.literals.Count) { return true; // full match } else { return false; // only partial match } }
public void HasSelf(string nStr, bool expectedResult, Refactorization r) { bool result = false; if (r == Refactorization.Current) { var name = Name.BuildName(nStr); for (long i = 0; i < reps; i++) { result = name.HasSelf(); } } else if (r == Refactorization.New) { var name = new SimpleName(nStr); for (long i = 0; i < reps; i++) { result = SimpleWFN.HasSelf(name); } } Assert.AreEqual(expectedResult, result); }
public void MatchNames_True(string n1, string n2, Refactorization r) { bool result = false; if(r == Refactorization.Current) { var name = Name.BuildName(n1); var name2 = Name.BuildName(n2); for (long i = 0; i < reps; i++) { result = name.Match(name2); } } else if (r == Refactorization.New) { var name = new SimpleName(n1); var name2 = new SimpleName(n2); for (long i = 0; i < reps; i++) { result = SimpleWFN.Match(name, name2); } } Assert.IsTrue(result); }
public static SimpleName RemoveVariableTag(SimpleName name, string tag) { var clone = new SimpleName(name.literals); foreach (var v in GetVariables(clone)) { v.description = v.description.Replace(tag + "]", "]"); } return clone; }
public static SimpleName BuildNameFromContainedLiteral(SimpleName name, Literal literal) { if (literal.type != LiteralType.Root) return new SimpleName(new Literal[] { literal }); var i = name.literals.IndexOf(literal); var list = name.literals.Skip(i+1).TakeWhile(l => l.depth > literal.depth); return new SimpleName(list.Prepend(literal)); }
public void MakeGround_GroundedName(string n1, string var, string sub, string expectedResult, Refactorization r) { String result = string.Empty; if (r == Refactorization.New) { var name = new SimpleName(n1); SimpleName nameResult = null; Dictionary<string, SimpleName> subs = new Dictionary<string, SimpleName>(); subs[var] = new SimpleName(sub); for (long i = 0; i < reps; i++) { nameResult = SimpleWFN.MakeGround(name, subs); } result = nameResult.ToString(); } else if (r == Refactorization.Current) { var name = Name.BuildName(n1); Name nameResult = null; SubstitutionSet subSet = new SubstitutionSet(); subSet.AddSubstitution(new Substitution("[x]/J(I)")); for (long i = 0; i < reps; i++) { nameResult = name.MakeGround(subSet); } } Assert.AreEqual(expectedResult, result); }
public static SimpleName ReplaceLiterals(SimpleName name, string oldLit, string newLit) { var clone = new SimpleName(name.literals); foreach (var l in clone.literals.Where(l => l.description == oldLit)) { l.description = newLit; } return clone; }
public void ReplaceLiterals(string n1, string t1, string t2, string expectedResult, Refactorization r) { string resultStr = string.Empty; if(r == Refactorization.Current) { Name result = null; var name = Name.BuildName(n1); for (long i = 0; i < reps; i++) { result = name.SwapTerms((Name)t1, (Name)t2); } resultStr = RemoveWhiteSpace(result.ToString()); }else if(r == Refactorization.New) { SimpleName result = null; var name = new SimpleName(n1); for (long i = 0; i < reps; i++) { result = SimpleWFN.ReplaceLiterals(name, t1, t2); } resultStr = result.ToString(); } Assert.That(string.Equals(resultStr, expectedResult, StringComparison.InvariantCultureIgnoreCase)); }
public void Unify_UnifiableNames_True(string n1, string n2, string[] result, Refactorization r) { var expectedBindings = result.Select(s => new Substitution(s)); IEnumerable<Substitution> bindings = null; var isUnifiable = false; if(r == Refactorization.Current) { var name1 = Name.BuildName(n1); var name2 = Name.BuildName(n2); for (int i = 0; i < unifierReps; i++) { isUnifiable = Unifier.Unify(name1, name2, out bindings); } } else if(r == Refactorization.New) { var name1 = new SimpleName(n1); var name2 = new SimpleName(n2); for (int i = 0; i < unifierReps; i++) { isUnifiable = SimpleUnifier.Unify(name1, name2, out bindings); } } Assert.That(isUnifiable); if (result.Any()) { Assert.That(bindings, Is.EquivalentTo(expectedBindings)); } else { Assert.That(bindings.Count() == 0); } }
public void ToString(string n1, string expectedResult, Refactorization r) { string result = string.Empty; if (r == Refactorization.Current) { var name = Name.BuildName(n1); for (long i = 0; i < reps; i++) { result = name.ToString(); } result = RemoveWhiteSpace(result); } else if (r == Refactorization.New) { var name = new SimpleName(n1); for (long i = 0; i < reps; i++) { result = name.ToString(); } } Assert.That(string.Equals(expectedResult, result, StringComparison.InvariantCultureIgnoreCase)); }
/// <summary> /// Unifying Method, receives two WellFormedNames and tries /// to find a list of Substitutions that will make /// both names syntatically equal. The algorithm performs Occur Check, /// as such the unification of [X] and Luke([X]) will allways fail. /// /// The method goes on each symbol (for both names) at a time, and tries to find /// a substitution between them. Take into account that the Unification between /// [X](John,Paul) and Friend(John,[X]) fails because the algorithm considers [X] /// to be the same variable /// </summary> /// <see cref="FAtiMA.Core.WellFormedNames.Substitution"/> /// <see cref="FAtiMA.Core.WellFormedNames.Name"/> /// <param name="name1">The first Name</param> /// <param name="name2">The second Name</param> /// <param name="bindings">The out paramenter for the founded substitutions</param> /// <returns>True if the names are unifiable, in this case the bindings list will contain the found Substitutions, otherwise it will be empty</returns> public static bool Unify(SimpleName name1, SimpleName name2, out IEnumerable<Substitution> bindings) { bindings = null; if (name1 == null || name2 == null) return false; if (SimpleWFN.IsGrounded(name1) && SimpleWFN.IsGrounded(name2)) { if (SimpleWFN.Match(name1, name2)) { bindings = Enumerable.Empty<Substitution>(); return true; } else { return false; } } bindings = FindSubst(name1, name2); return bindings != null; }