diff --git a/.gitignore b/.gitignore index 80e2cdb..06b5f23 100644 --- a/.gitignore +++ b/.gitignore @@ -222,4 +222,6 @@ project.lock.json ##### # End of core ignore list, below put you custom 'per project' settings (patterns or path) -##### \ No newline at end of file +##### +/GUI +/MultiAgentLanguageGUI/packages diff --git a/ModelsTests/CommonTests.cs b/ModelsTests/CommonTests.cs index 382b327..c7bd65e 100644 --- a/ModelsTests/CommonTests.cs +++ b/ModelsTests/CommonTests.cs @@ -2,6 +2,7 @@ using Ninject; using NUnit.Framework; using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using Action = MultiAgentLanguageModels.Action; @@ -62,5 +63,46 @@ public void GeneratingLogicExpression2() var notSigmaExpression = new LogicExpression(notSigma); Assert.AreEqual(@"[(\sigma)]", notSigmaExpression.ToProlog()); } + + [Test] + public void LogicExpressionCheck() + { + var sigma = new Fluent("sigma"); + var notSigma = new Not(sigma); + var notSigmaExpression = new LogicExpression(notSigma); + var actual = notSigmaExpression.EvaluateLogicExpression(); + var expected = new List>>() + { + new List>() + { + new Tuple("sigma", false) + } + }; + Assert.AreEqual(expected, actual); + } + + [Test] + public void LogicExpressionCheck2() + { + var sigma = new Fluent("sigma"); + var pi = new Fluent("pi"); + var beta = new Fluent("beta"); + var notSigma = new Not(sigma); + var ifPiBeta = new If(pi, beta); + var iffPiBetaSigma = new Iff(ifPiBeta, notSigma); + + var iffExpression = new LogicExpression(iffPiBetaSigma); + var actual = iffExpression.EvaluateLogicExpression().ToListOfStrings(); + var expected = new List() + { + @"[beta, pi, \sigma]", + @"[beta, \pi, \sigma]", + @"[\beta, \pi, \sigma]", + @"[\beta, pi, sigma]" + }; + var check1 = expected.TrueForAll(x => actual.Contains(x)); + var check2 = actual.TrueForAll(x => expected.Contains(x)); + Assert.True(check1 && check2); + } } } \ No newline at end of file diff --git a/MultiAgentLanguageModels/Fluent.cs b/MultiAgentLanguageModels/Fluent.cs index 774a2e7..770b920 100644 --- a/MultiAgentLanguageModels/Fluent.cs +++ b/MultiAgentLanguageModels/Fluent.cs @@ -4,14 +4,23 @@ public class Fluent : LogicElement { public string Name { get; set; } + public bool Value { get; set; } + public Fluent(string name) { Name = name; + Left = null; + Right = null; } public override string ToString() { return Name; } + + public override bool GetValue() + { + return Value; + } } } \ No newline at end of file diff --git a/MultiAgentLanguageModels/LogicElement.cs b/MultiAgentLanguageModels/LogicElement.cs index dcc2cf0..715550f 100644 --- a/MultiAgentLanguageModels/LogicElement.cs +++ b/MultiAgentLanguageModels/LogicElement.cs @@ -4,6 +4,7 @@ public abstract class LogicElement { public LogicElement Left { get; set; } public LogicElement Right { get; set; } + public abstract bool GetValue(); } public class Not : LogicElement @@ -13,6 +14,12 @@ public Not(LogicElement logicElement) Left = logicElement; Right = null; } + + public override bool GetValue() + { + return !Left.GetValue(); + } + public override string ToString() { return $"(\\{Left.ToString()})"; @@ -26,6 +33,12 @@ public Or(LogicElement left, LogicElement right) Left = left; Right = right; } + + public override bool GetValue() + { + return Left.GetValue() || Right.GetValue(); + } + public override string ToString() { return $"({Left.ToString()}+{Right.ToString()})"; @@ -39,6 +52,12 @@ public And(LogicElement left, LogicElement right) Left = left; Right = right; } + + public override bool GetValue() + { + return Left.GetValue() && Right.GetValue(); + } + public override string ToString() { return $"({Left.ToString()}*{Right.ToString()})"; @@ -52,6 +71,12 @@ public If(LogicElement left, LogicElement right) Left = left; Right = right; } + + public override bool GetValue() + { + return (!Left.GetValue()) || Right.GetValue(); + } + public override string ToString() { Not notLeft = new Not(Left); @@ -67,6 +92,12 @@ public Iff(LogicElement left, LogicElement right) Left = left; Right = right; } + + public override bool GetValue() + { + return ((!Left.GetValue()) || Right.GetValue()) && ((!Right.GetValue()) || Left.GetValue()); + } + public override string ToString() { If leftToRight = new If(Left, Right); diff --git a/MultiAgentLanguageModels/LogicExpression.cs b/MultiAgentLanguageModels/LogicExpression.cs index be18d9f..deafe94 100644 --- a/MultiAgentLanguageModels/LogicExpression.cs +++ b/MultiAgentLanguageModels/LogicExpression.cs @@ -1,24 +1,65 @@ -namespace MultiAgentLanguageModels +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MultiAgentLanguageModels { public class LogicExpression : IProlog { + + private List Fluents + { + get + { + List fluents = new List(); + List temp = new List(); + temp.Add(Element); + LogicElement logicElement; + while (temp.Count != 0) + { + logicElement = temp.First(); + temp.RemoveAt(0); + if (logicElement.GetType() == typeof(Fluent)) + { + fluents.Add(logicElement as Fluent); + } + else + { + if (logicElement.Left != null) + { + temp.Add(logicElement.Left); + } + if (logicElement.Right != null) + { + temp.Add(logicElement.Right); + } + } + } + return fluents.OrderBy(x => x.Name).ToList(); + } + } + public LogicElement Element { get; } private readonly bool empty = false; private static LogicExpression _empty; + + public string StringExpression { get => Element.ToString(); } + public static LogicExpression Empty { get { if (_empty == null) _empty = new LogicExpression(); return _empty; - } } + } + } private LogicExpression() { empty = true; } - + public LogicExpression(LogicElement element) { Element = element; @@ -28,5 +69,34 @@ public string ToProlog() { return empty ? "[]" : $"[{Element.ToString()}]"; } + + public List>> EvaluateLogicExpression() + { + List>> results = new List>>(); + var fluents = Fluents; + for(int i=0; i < Math.Pow(2, fluents.Count); i++) + { + var binary = Convert.ToString(i, 2).PadLeft(fluents.Count, '0').Select(x => x == '1' ? true : false).ToArray(); + for(int j = 0; j < fluents.Count; j++) + { + fluents[j].Value = binary[j]; + } + if (Element.GetValue()) + { + results.Add( + fluents.Select(x => new Tuple(x.Name, x.Value)).ToList() + ); + } + } + return results; + } + } + + public static class EvaluationExt + { + public static List ToListOfStrings(this List>> tuples) + { + return tuples.Select(x => $"[{x.Select(t => t.Item2 ? t.Item1 : $"\\{t.Item1}").Aggregate((a, b) => a + ", " + b)}]").ToList(); + } } } \ No newline at end of file