Exercise 13 Tests

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Plato.Core;
using Plato.Core.Search;
using Plato.Language;
using Plato.Language.Parser;
using Plato.Core.Parser;
using Plato.Derivation.Parser;
using Plato.Derivation;

namespace Tests
{
    [TestFixture]
    public class Exercise13
    {
        Brain brain;
        Parser parser;
        TransformationParser transParser;
        WordMappingParser wordMappingParser;
        RuleParser ruleParser;

        [SetUp]
        public void SetUp()
        {
            brain = new Brain();
            parser = new Parser(brain);
            transParser = new TransformationParser(brain);
            wordMappingParser = new WordMappingParser(brain);
            ruleParser = new RuleParser(brain);

            parser.Parse(
@"speaker is_a person
self is_a person
person has_a first_name
person has_a age
'Daniel' is_a first_name
27 is_a number
number is_a age
'Plato'
self.first_name = 'Plato'
self.age = 51
'first'
person has_a eye
eye has_a color
blue is_a color
DanielBigham is_a person
DanielBigham is_a man
man has_a wife
wife is_a person
'Meredith' is_a first_name
person has_a last_name
'Bigham' is_a last_name
last_name is_a noun
sister is_a person
person has(count:0+) sister
plural_noun is_a noun
number_part
digit is_a number_part
teen_number is_a number_part
group_of_ten is_a number_part
100+_number_part is_a number_part
person has_a full_name
Canada
Canadian
born_in");

            wordMappingParser.Parse(
@"'name' -> first_name: noun
'nom' -> first_name: noun
'age' -> age: noun
'27' -> 27: noun
'I' -> speaker: noun
'you' -> self: noun
'is' -> is_am_are: verb
'am' -> is_am_are: verb
'are' -> is_am_are: verb
'eye' -> eye: noun
'color' -> color: noun
'colour' -> color: noun
'blue' -> blue: noun
'Daniel' -> DanielBigham: noun
'person' -> person: noun
'wife' -> wife: noun
'has' -> has_have: verb
'have' -> has_have: verb
'sisters' -> sister: plural_noun
'one' -> 1: digit
'two' -> 2: digit
'three' -> 3: digit
'four' -> 4: digit
'five' -> 5: digit
'six' -> 6: digit
'seven' -> 7: digit
'eight' -> 8: digit
'nine' -> 9: digit
'ten' -> 10: teen_number
'eleven' -> 11: teen_number
'twelve' -> 12: teen_number
'thirteen' -> 13: teen_number
'fourteen' -> 14: teen_number
'fifteen' -> 15: teen_number
'sixteen' -> 16: teen_number
'seventeen' -> 17: teen_number
'eighteen' -> 18: teen_number
'nineteen' -> 19: teen_number
'twenty' -> 20: group_of_ten
'thirty' -> 30: group_of_ten
'forty' -> 40: group_of_ten
'fifty' -> 50: group_of_ten
'sixty' -> 60: group_of_ten
'seventy' -> 70: group_of_ten
'eighty' -> 80: group_of_ten
'ninety' -> 90: group_of_ten
'hundred' -> 100: multiplier
'thousand' -> 1000: multiplier
'million' -> 1000000: multiplier
'billion' -> 1000000000: multiplier
'trillion' -> 1000000000000: multiplier
'quadrillion' -> 1000000000000000: multiplier");

            transParser.Parse(
@"my {noun} -> speaker.$1
mon {noun} -> speaker.$1
{noun} is {noun} -> $1 = $2
{noun} est {noun} -> $1 = $2
what is {noun} ? -> $1
{person} {is_am_are} {number} -> $1.age = $3
your {noun} -> self.$1
how old {is_am_are} {noun} ? -> $2.age
first name -> first_name
{noun} {noun} -> $1.$2
{noun} 's {noun} -> $1.$2
last name -> last_name
{noun} {has_have} {number} {noun} -> $1 has(count:$3) $4
{group_of_ten} {digit} -> # $1 + $2 (number_part)
{number_part} {multiplier} -> # $1 * $2 (100+_number_part)
{100+_number_part} {100+_number_part} -> # $1 + $2 (100+_number_part)
{100+_number_part} {number_part} -> # $1 + $2
");
        }

        /// <summary>
        /// Ensure we can parse variable literal subtokens such as '$2 $3'.
        /// </summary>
        [Test]
        public void ParseVariableLiteralToken()
        {
            VariableLiteralToken token =
                transParser.ParseVariableLiteralToken("'$2 $3'");

            Assert.AreEqual("$2", token.Tokens[0].ToString());
            Assert.AreEqual(" ", token.Tokens[1].ToString());
            Assert.AreEqual("$3", token.Tokens[2].ToString());
        }

        [Test]
        public void RuleParserTest1()
        {
            string str = @"
rule:
  $1 is_a person
  $1.first_name = $2
  $1.last_name = $3
  -> $1.full_name = '$2 $3'";

            Rule r = ruleParser.Parse(str);

            Assert.AreEqual(3, r.Conditions.Count);
            Assert.AreEqual(RuleType.Assignment, r.RuleType);
            Assert.AreEqual("$1 is_a person", r.Conditions[0].ToString());
            Assert.AreEqual("$1.first_name = $2", r.Conditions[1].ToString());
            Assert.AreEqual("$1.last_name = $3", r.Conditions[2].ToString());
            Assert.AreEqual("$1.full_name = '$2 $3'", r.Conclusion.ToString());
        }

        [Test]
        public void RuleParserTest2()
        {
            string str = @"
rule:
  $1 is_a person
  $1 born_in Canada
  -> $1 is_a Canadian";

            Rule r = ruleParser.Parse(str);

            Assert.AreEqual(2, r.Conditions.Count);
            Assert.AreEqual(RuleType.Relationship, r.RuleType);
            Assert.AreEqual("$1 is_a person", r.Conditions[0].ToString());
            Assert.AreEqual("$1 born_in Canada", r.Conditions[1].ToString());
            Assert.AreEqual("$1 is_a Canadian", r.Conclusion.ToString());
        }
    }
}