Friday, July 21, 2017

Expression evaluation over time - Was?


A closer look at the Was query to determine if something has been, builds heavily on the previous articles in this series.

Other articles in the AI Knowledge Based Reasoning series on this site:
Knowledge based reasoning in .net c#
Reasoning in Open or Closed models
Logic Expression evaluation with open-world assumption
Expression evaluation on object based models
Expression evaluation over time
Expression evaluation over time - Was?

Definition of Was

So lets start with defining what we mean when we say Was.
Was Mikaela angry?
Is there a previous frame where the logical expression Feeling(Angry) results in true?
There is also a meaning of this to not be the case at some point after it was true.

Lets look at this in a table form to get our bearings straight.
FrameNameOccupationEye-colorHair-color
1MikaelaStudentBlueBrown
2MikaelaPearlescent
3MikaelaPink
4MikaelaJunior Software DeveloperBlue
5MikaelaSoftware DeveloperBlonde
6MikaelaSenior Software DeveloperPearlescent
7MikaelaSoftware ArchitectBrown

At this point was could ask,

WAS Occupation(Student)
Would be true, as there is a frame where Mikaela was a student. and after that something else.

WAS Name(Mikaela)
Would not be true, as she is Mikaela and has never had any other name

WAS Occupation(Software Architect)
Would not be true, as she currently is and there is no previous frame where she was

WAS HairColor(Brown)
Would be true, she still is in the current frame, but there was other hair colors for at least one frame and all the way back there was Brown again.

Unit tests

Lets look at this in unit test form

[TestClass]
public class RelativeWasTest
{
    [TestMethod]
    public void RelativeWasTest_True()
    {
        Context target;
        var obj = CreateTarget(out target);
            
        var expr2 = new ExpressionIs(new KnowledgeRelation { Subject = "Student", Relation = "Occupation of", Target = obj.ToString() });
        var relative = new RelativeWas(expr2);
        var actual = target.Evaluate(relative);
        Assert.AreEqual(EvaluationResult.True, actual);
    }
    [TestMethod]
    public void RelativeWasTest_False()
    {
        Context target;
        var obj = CreateTarget(out target);

        var expr2 = new ExpressionIs(new KnowledgeRelation { Subject = "Lawyer", Relation = "Occupation of", Target = obj.ToString() });
        var relative = new RelativeWas(expr2);
        var actual = target.Evaluate(relative);
        Assert.AreEqual(EvaluationResult.False, actual);
    }
    [TestMethod]
    public void RelativeWasTest_True_PeriodOfWasNot()
    {
        Context target;
        var obj = CreateTarget(out target);

        var expr2 = new ExpressionIs(new KnowledgeRelation { Subject = "Black", Relation = "HairColor of", Target = obj.ToString() });
        var relative = new RelativeWas(expr2);
        var actual = target.Evaluate(relative);
        Assert.AreEqual(EvaluationResult.True, actual);
    }
    [TestMethod]
    public void RelativeWasTest_NotSure()
    {
        Context target;
        var obj = CreateTarget(out target);

        var expr2 = new ExpressionIs(new KnowledgeRelation { Subject = "Student", Relation = "Lunch of", Target = obj.ToString() });
        var relative = new RelativeWas(expr2);
        var actual = target.Evaluate(relative);
        Assert.AreEqual(EvaluationResult.NotSure, actual);
    }

    private static Person CreateTarget(out Context target)
    {
        var obj = new Person("Alice")
        {
            Occupation = "Student",
            HairColor = "Black"
        };
        target = new Context(obj.ToString());
        target.AddFrame(FrameFactory.Create(obj));

        obj.Occupation = string.Empty;
        obj.HairColor = "Pearlescent";
        target.AddFrame(FrameFactory.Create(obj));

        obj.Occupation = string.Empty;
        obj.HairColor = "Pink";
        target.AddFrame(FrameFactory.Create(obj));

        obj.Occupation = "Lawyer";
        obj.HairColor = "Black";
        target.AddFrame(FrameFactory.Create(obj));
        return obj;
    }
}

And just to make things interesting its not the exact example as in this post. Just noticed it now, but anyway. The idea is the same.

How to implement this based on the IRelative interface and Context class from the previous post.

public class RelativeWas : IRelative
{
 private readonly AExpression _expression;

 public RelativeWas(AExpression expression)
 {
  _expression = expression;
 }

 public EvaluationResult Evaluate(Context context)
 {
  var wasNot = false;
  for (int frameIndex = context.Frames.Count - 1; frameIndex >= 0; frameIndex--)
  {
   var result = context.Evaluate(_expression, frameIndex);

   if (result == EvaluationResult.NotSure)
    return EvaluationResult.NotSure;
   if (wasNot)
   {
    if (result == EvaluationResult.True)
     return EvaluationResult.True;
   }
   else
   {
    if (result == EvaluationResult.False)
     wasNot = true;
   }
  }
  return EvaluationResult.False;
 }
}


Thank you for reading! Here comes a video of our cat Prime trying fresh catnip for the first time!
All code provided as-is. This is copied from my own code-base, May need some additional programming to work.

No comments:

Post a Comment