Exemple #1
0
        /// <summary>
        /// Assesses the state of asserted facts and then decides what to do next.
        /// </summary>
        public static void ProcessRequest(string request)
        {
            Facts.Fact goalblob = ParseRequest(request);
            InitializeSession();

            while (true)
            {
                // Get the response object from the interview engine
                Engine.Response response = Engine.Investigate(new List <Facts.Fact>()
                {
                    goalblob
                });

                // Ask the current question, or display the results
                if (!response.InvestigationComplete)
                {
                    // Ask the next question
                    DisplayQuestion(response);

                    // Get and validate the answer
                    GetAndParseAnswer(response);
                }
                else
                {
                    DisplayResults(goalblob);
                    break;
                }
            }

//             Display all facts that have been asserted (for diagnostic purposes)
//             Console.WriteLine("\nFacts: \n" + Facts.AssertedFacts());
        }
Exemple #2
0
        /// <summary>
        /// Displays a question to the user.
        /// </summary>
        private static void DisplayQuestion(Engine.Response response)
        {
            // Get data about the next question
            Facts.Fact theFact = response.NextFact;
            Question   theQ    = Templates.GetQ(theFact.Relationship);

            // TODO: Display appropriate question control (using theQ.questionType)

            // White space
            Console.WriteLine();

            // Display progress percentage
            Console.WriteLine("Percent complete: " + response.PercentComplete);

            // Display question text
            string qText = theFact.QuestionText(); // QuestionText(theFact, theQ);

            Console.WriteLine(qText);
            AkkTest.assertedRelationship = AkkTest.AddUnitTestAssertRel(theFact, theQ);

            // Display an explanation (if any)
            if (theQ.explanation != "")
            {
                Console.WriteLine("Note: " + theQ.explanation);
            }
        }
Exemple #3
0
        /// <summary>
        /// Adds a fact to the proof tree.
        /// </summary>
        public static void AddToProofTree(Facts.Fact f)
        {
            // Fact should be added if it is a regular rule that is
            // not already on the tree (to avoid repeats), or if it
            // is an input rule.
            bool addIt = true;

            foreach (ProofTreeNode n in ProofTree)
            {
                Facts.Fact f2 = n.TheFact;
                if (f.Relationship == f2.Relationship && Util.AreEqual(f.Arg1, f2.Arg1) && Util.AreEqual(f.Arg2, f2.Arg2) && Util.AreEqual(f.Arg3, f2.Arg3))
                {
                    addIt = false;
                }
            }

            // Approximates Akkadian function depth
            int depth = new StackTrace().FrameCount;

            // Sometimes the stack trace overestimates the function depth
            // (for example, in Switch() statements).  The following code
            // compensates for this by de-indenting facts so they're not
            // more than one level deeper than their parent level.
//            int depthOfLastFact = 0;
//            if (ProofTree.Count > 0) depthOfLastFact = ProofTree[ProofTree.Count-1].Depth;
//            depth = Math.Min(depth, depthOfLastFact+1);

            if (addIt)
            {
                // TODO: Filter out repeats, etc.
                ProofTree.Add(new ProofTreeNode(f, depth));
            }
        }
Exemple #4
0
 /// <summary>
 /// General response constructor.
 /// </summary>
 public Response(bool done, Facts.Fact next, int percent, List <Facts.Fact> goals)
 {
     InvestigationComplete = done;
     NextFact        = next;
     PercentComplete = percent;
     Goals           = goals;
 }
Exemple #5
0
 public Factoid(Facts.Fact f)
 {
     FactType     = f.GetTvarType();
     Relationship = f.Relationship;
     Arg1         = Util.ArgToString(f.Arg1);
     Arg2         = Util.ArgToString(f.Arg2);
     Arg3         = Util.ArgToString(f.Arg3);
     QuestionText = f.QuestionText();
 }
Exemple #6
0
        /// <summary>
        /// Asks the next question or displays the interview results.
        /// </summary>
        public static Response Investigate(List <Facts.Fact> goals)
        {
            // Default outputs
            bool allDone = true;
            int  percent = 0;

            Facts.Fact theNextFact = new Facts.Fact("", null, null, null);

            InitializeProofTree();

            // Pre-evaluate each goal in order to cache the results of
            // each evaluted function in the FactBase.  This will make
            // look-ahead short-circuiting work in the interview.
            // There will obviously be performance implications to
            // evaluating each goal twice.  However, a four-line fix
            // to a vexing problem feels delightful.  And the caching
            // may end up making things tolerable after all.
            //
            // But note that the look-ahead short-circuiting issue is not
            // completely solved: it will still fail in large rules where
            // the intermediate conditions are not checked/pre-evaluated.
            foreach (Facts.Fact g in goals)
            {
                g.Value();
            }

//            Console.WriteLine(ShowProofTree());

            // Prepare to look for unknown facts
            Facts.GetUnknowns = true;
            Facts.Unknowns.Clear();

            // Iterate through each goal
            foreach (Facts.Fact g in goals)
            {
                if (!g.Value().HasBeenDetermined)
                {
                    allDone = false;
                }
            }
            Facts.GetUnknowns = false;

            // Determine the next fact and the percent complete
            if (!allDone)
            {
                theNextFact = Facts.Unknowns[0];
                percent     = ProgressPercentage(Facts.Count(), Facts.Unknowns.Count);
            }

            return(new Engine.Response(allDone, theNextFact, percent, goals));
        }
        /// <summary>
        /// Adds the assertion relationship to the .akk unit test text.
        /// </summary>
        public static string AddUnitTestAssertRel(Facts.Fact theF, Question theQ)
        {
            string result = "- " + theQ.relationship + "(" + ((Thing)theF.Arg1).Id;

            if (theF.Arg2 == null)
            {
                // e.g. Rel(p) =
                result += ") = ";
            }
            else
            {
                // e.g. Rel(p,q) =
                result += "," + ((Thing)theF.Arg2).Id + ") = ";
            }

            return(result);
        }
Exemple #8
0
        /// <summary>
        /// Displays the engine's results of the interview session.
        /// </summary>
        private static void DisplayResults(Facts.Fact goal)
        {
            Console.WriteLine("\n");

            // Indent and format results
            string tline = "\t" + goal.ValueAsString().Replace("\n", "\n\t");

            // For eternal values, only show value
            if (goal.Value().IsEternal)
            {
                tline = tline.Replace("DawnOfTime   ", "");
            }

            // Concatenate question and answer
            string result = "\t" + goal.QuestionText() + "\n\n" + tline + "\n";

            // Add result to test case
            Tvar testResult = goal.GetFunction().Invoke();

            AkkTest.CloseUnitTest(testResult, goal.Relationship);

            Console.WriteLine(result);
        }
Exemple #9
0
 public ProofTreeNode(Facts.Fact fact, int depth)
 {
     TheFact = fact;
     Depth   = depth;
 }
Exemple #10
0
        /// <summary>
        /// Takes an income packet and instantiates a Hammurabi session.
        /// </summary>
        public Packet Assess(Packet request)
        {
            // Start timer
            DateTime startTime = DateTime.Now;

            // Pre-evaluate each goal to enable look-ahead short circuiting.
            // See Hammurabi | Core | Engine.cs, line ~81, for an explanation.
            foreach (Factoid g in request.Goals)
            {
                Facts.Fact gb = new Facts.Fact(g.Relationship, g.Arg1, g.Arg2, g.Arg3);
                gb.Value();
            }

            // Start a fresh session
//            Facts.Clear();
            Facts.GetUnknowns = true;
            Facts.Unknowns.Clear();
            bool allDone = true;

            request.PercentageComplete = 100;

            // Assert facts into a Hammurabi session
            foreach (Factoid f in request.AssertedFacts)
            {
                AssertFact(f);
            }

            // Iterate through each goal
            foreach (Factoid g in request.Goals)
            {
                Facts.Fact gb = new Facts.Fact(g.Relationship, g.Arg1, g.Arg2, g.Arg3);

                // Assign to a variable so it's only evaluated once
                Tvar gbVal = gb.Value();

                // Convert Tvar to timeline object
                g.Timeline = TvarToTimeline(gbVal);

                // All goals resolved?
                if (!gbVal.HasBeenDetermined)
                {
                    allDone = false;
                }
            }

            // Stop looking for unknown facts
            Facts.GetUnknowns = false;

            // Determine the next fact and the percent complete
            if (!allDone)
            {
//                Factoid neededFact = new Factoid("Tnum","USC.Tit26.Sec151.ThresholdAmount","Jim","","");
//                Facts.Fact f = new Facts.Fact("USC.Tit26.Sec151.ThresholdAmount", null, null, null);
//                Factoid neededFact = new Factoid(f);

                Factoid neededFact = new Factoid(Facts.Unknowns[0]);
                request.NeededFacts = new List <Factoid>()
                {
                    neededFact
                };

                request.PercentageComplete = Interactive.Engine.ProgressPercentage(Facts.Count(), Facts.Unknowns.Count);
            }

            // Add elapsed time to response object
            request.ResponseTimeInMs = Convert.ToInt32((DateTime.Now - startTime).TotalMilliseconds);

            return(request);
        }