Created
October 29, 2011 18:53
-
-
Save hodzanassredin/1324924 to your computer and use it in GitHub Desktop.
prolog in csharp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace Prolog1 | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var p = new Prolog(); | |
p.AddFact(new Fact("like", "dima", "apple")); | |
p.AddFact(new Fact("like", "alex", "apple")); | |
p.AddFact(new Fact("like", "serg", "microsoft")); | |
p.AddRule(IfSombodyLikeSomethingThenFrendIsSomeoneWhoLikeTheSame); | |
p.AddRule(EveryFactIsCommutattive); | |
var dimaAndAlexAreFriends = new Fact("friend", "dima", "alex"); | |
Console.WriteLine(dimaAndAlexAreFriends + " " + p.Is(dimaAndAlexAreFriends).ToString()); | |
var friends = p.Match(new Fact("friend", "", "dima"), true); | |
foreach (var friend in friends) | |
{ | |
Console.WriteLine(friend); | |
} | |
Console.ReadKey(); | |
} | |
public static IEnumerable<Fact> IfSombodyLikeSomethingThenFrendIsSomeoneWhoLikeTheSame(Fact newFact, IEnumerable<Fact> existingFacts) | |
{ | |
if (newFact.Predicate != "like") return new List<Fact>(); | |
return existingFacts.Where(f => f.Predicate == "like" | |
&& f.Subject != newFact.Subject | |
&& f.Object == newFact.Object).Select(x=>new Pair(x.Subject,newFact.Subject)) | |
.GenerateCommutativeFacts("friend"); | |
} | |
public static IEnumerable<Fact> EveryFactIsCommutattive(Fact newFact, IEnumerable<Fact> existingFacts) | |
{ | |
return new List<Fact> { newFact.ToCommutative() }; | |
} | |
} | |
public class Fact | |
{ | |
public Fact(string predicate, string subject, string @object) | |
{ | |
Predicate = predicate; | |
Subject = subject; | |
Object = @object; | |
} | |
public string Predicate; | |
public string Subject; | |
public string Object; | |
public bool Match(Fact f, bool commutative) | |
{ | |
var res = (f.Object.Empty() || f.Object == Object) | |
&& (f.Subject.Empty() || f.Subject == Subject) | |
&& (f.Predicate.Empty() || f.Predicate == Predicate); | |
if (!res && commutative) | |
return (f.Object.Empty() || f.Object == Subject) | |
&& (f.Subject.Empty() || f.Subject == Object) | |
&& (f.Predicate.Empty() || f.Predicate == Predicate); | |
return res; | |
} | |
public override string ToString() | |
{ | |
return Predicate + "(" + Subject + ", " + Object + ")"; | |
} | |
public Fact ToCommutative() | |
{ | |
return new Fact(Predicate, Object, Subject); | |
} | |
public static bool operator ==(Fact c1, Fact c2) | |
{ | |
return c1.Object == c2.Object && c1.Subject == c2.Subject && c1.Predicate == c2.Predicate; | |
} | |
public static bool operator !=(Fact c1, Fact c2) | |
{ | |
return !(c1 == c2); | |
} | |
public override bool Equals(object obj) | |
{ | |
return obj is Fact && (obj as Fact) == this; | |
} | |
} | |
public class Pair | |
{ | |
public Pair(string a, string b) | |
{ | |
A = a; | |
B = b; | |
} | |
public string A; | |
public string B; | |
public override string ToString() | |
{ | |
return B + " and " + A; | |
} | |
} | |
public static class Exts | |
{ | |
public static bool Empty(this string str) | |
{ | |
return string.IsNullOrEmpty(str); | |
} | |
public static IEnumerable<Fact> GenerateCommutativeFacts(this IEnumerable<Pair> pairs, String predicate) | |
{ | |
return pairs.Select(x => new List<Fact>{ new Fact(predicate, x.A, x.B) | |
, new Fact(predicate, x.A, x.B)}).SelectMany(x => x); | |
} | |
public static IEnumerable<Fact> GenerateFacts(this IEnumerable<Pair> pairs, String predicate) | |
{ | |
return pairs.Select(x => new Fact(predicate, x.A, x.B)); | |
} | |
} | |
public class Prolog | |
{ | |
public readonly List<Fact> facts = new List<Fact>(); | |
List<Func<Fact, IEnumerable<Fact>, IEnumerable<Fact>>> rules = new List<Func<Fact, IEnumerable<Fact>, IEnumerable<Fact>>>(); | |
private bool AddFact(Fact triplet, bool useRules) | |
{ | |
if (facts.Count(x => x == triplet) == 0) | |
{ | |
facts.Add(triplet); | |
if (rules.Count > 0 && useRules) GenerateNewFacts(); | |
return true; | |
} | |
return false; | |
} | |
public bool AddFact(Fact triplet) | |
{ | |
return AddFact(triplet, true); | |
} | |
private int AddFacts(IEnumerable<Fact> triplets, bool useRules) | |
{ | |
int res = 0; | |
foreach (var fact in triplets) | |
{ | |
if (AddFact(fact, useRules)) res++; ; | |
} | |
return res; | |
} | |
public void AddRule(Func<Fact, IEnumerable<Fact>, IEnumerable<Fact>> r) | |
{ | |
rules.Add(r); | |
GenerateNewFacts(); | |
} | |
private void GenerateNewFacts() | |
{ | |
var done = false; | |
while (!done) | |
{ | |
var newFacts = new List<Fact>(); | |
foreach (var rule in rules) | |
{ | |
foreach (var fact in facts) | |
{ | |
newFacts.AddRange(rule(fact, facts)); | |
} | |
} | |
; | |
done = AddFacts(newFacts, false) == 0; | |
} | |
} | |
public bool Is(Fact factToCheck) | |
{ | |
return facts.Count(f => f == factToCheck) == 1; | |
} | |
public IEnumerable<Fact> Match(Fact factToMatch, bool commutative) | |
{ | |
return facts.Where(f => f.Match(factToMatch, commutative)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment