/// <summary> /// Creates a generator for objects of the specified types /// </summary> /// <param name="noun">Base common noun for the object</param> /// <param name="concepts">Other monadic concepts that must be true of the object</param> /// <param name="count">Number of objects of the specified type to include</param> public Generator(CommonNoun noun, IEnumerable <MonadicConceptLiteral> concepts, int count = 1) { Count = count; Noun = noun; Concepts = concepts.ToArray(); Rebuild(); }
public void NPListTest() { ParseAndExecute("tabby, persian, and siamese are kinds of cat"); Assert.IsTrue(CommonNoun.Find("tabby").IsImmediateSubKindOf(CommonNoun.Find("cat"))); Assert.IsTrue(CommonNoun.Find("persian").IsImmediateSubKindOf(CommonNoun.Find("cat"))); Assert.IsTrue(CommonNoun.Find("siamese").IsImmediateSubKindOf(CommonNoun.Find("cat"))); }
public Part(string[] name, CommonNoun kind, IEnumerable <MonadicConceptLiteral> modifiers) : base(name) { Name = name; AllParts[name] = this; Kind = kind; Modifiers = modifiers.ToArray(); }
public static CommonNoun LeastUpperBound(CommonNoun a, CommonNoun b) { if (a == null) { return(b); } if (b == null) { return(a); } if (a.IsSuperKindOf(b)) { return(a); } foreach (var super in a.Superkinds) { var lub = LeastUpperBound(super, b); if (lub != null) { return(lub); } } return(null); }
public Test(CommonNoun noun, IEnumerable <MonadicConceptLiteral> modifiers, bool shouldExist, string succeedMessage, string failMessage) { Noun = noun; ShouldExist = shouldExist; SucceedMessage = succeedMessage; FailMessage = failMessage; Modifiers = modifiers.ToArray(); }
public void OptionalAlternativeSetTest() { Ontology.EraseConcepts(); ParseAndExecute("cats can be big or small"); var cat = CommonNoun.Find("cat"); Assert.AreEqual(1, cat.AlternativeSets.Count); }
/// <summary> /// Ensure super is an immediate super-kind of this kind. /// Does nothing if it is already a super-kind. /// </summary> public void DeclareSuperclass(CommonNoun super) { if (!Superkinds.Contains(super)) { Superkinds.Add(super); super.Subkinds.Add(this); } }
public void RequiredAlternativeSetTest() { Ontology.EraseConcepts(); ParseAndExecute("cats are long haired or short haired"); var cat = CommonNoun.Find("cat"); Assert.AreEqual(1, cat.AlternativeSets.Count); }
/// <summary> /// True if this is an adjective that can apply to an individual of the specified kind. /// </summary> /// <param name="noun">Noun representing a kind of object</param> /// <returns>True if this adjective is allowed to apply to objects of the specified kind.</returns> public bool RelevantTo(CommonNoun noun) { if (noun.RelevantAdjectives.Contains(this)) { return(true); } return(noun.Superkinds.Any(RelevantTo)); }
private IEnumerable <PossibleIndividual> Generate(CommonNoun noun) { var g = noun.MakeGenerator(); for (var i = 0; i < 100; i++) { yield return(g.Generate()[0]); } }
public void ImpliedAdjectiveTest() { Ontology.EraseConcepts(); ParseAndExecute("cats are fuzzy"); var cat = CommonNoun.Find("cat"); var fuzzy = Adjective.Find("fuzzy"); var g = new Generator(cat); for (var n = 0; n < 100; n++) { var i = g.Solve(); Assert.IsTrue(i.IsA(i.Individuals[0], fuzzy)); } }
/// <summary> /// Individual i is known not to be of kind k. Initialize to also not /// be one of its subkinds /// </summary> private void DeselectSubkinds(Individual i, CommonNoun k) { if (k.Subkinds.Count == 0) { // Nothing to do return; } foreach (var sub in k.Subkinds) { SetIsA(i, sub, false); DeselectSubkinds(i, sub); } }
private void AddParts(Individual i, CommonNoun k) { foreach (var part in k.Parts) { var p = Individual.Ephemeral(part.MonadicConcepts, part.Name.Prepend("'s").ToArray(), i); i.Parts[part] = p; EphemeralIndividuals.Add(p); AddParts(p); } foreach (var super in k.Superkinds) { AddParts(i, super); } }
public void Symmetric() { Ontology.EraseConcepts(); ParseAndExecute("people can love each other"); var v = Verb.Find("loves"); var g = new Generator(CommonNoun.Find("person"), new MonadicConceptLiteral[0], 10); foreach (var i1 in g.Individuals) { foreach (var i2 in g.Individuals) { Assert.IsTrue(ReferenceEquals(g.Holds(v, i1, i2), g.Holds(v, i2, i1))); } } }
private CommonNoun FindKindOrSuperKind(CommonNoun k, Func <CommonNoun, bool> templateTest) { if (templateTest(k)) { return(k); } foreach (var super in k.Superkinds) { var s = FindKindOrSuperKind(super, templateTest); if (s != null) { return(s); } } return(null); }
public void Reflexive() { Ontology.EraseConcepts(); ParseAndExecute("people must love themselves"); var v = Verb.Find("loves"); var g = new Generator(CommonNoun.Find("person"), new MonadicConceptLiteral[0], 10); for (int n = 0; n < 100; n++) { var s = g.Solve(); foreach (var i in s.Individuals) { Assert.IsTrue(s.Holds(v, i, i)); } } }
public void NumericPropertyTest() { Ontology.EraseConcepts(); ParseAndExecute("cats have an age between 1 and 20"); var cat = CommonNoun.Find("cat"); var age = cat.Properties[0]; var g = new Generator(cat); for (var n = 0; n < 100; n++) { var i = g.Solve(); var ageVar = i.Individuals[0].Properties[age]; var ageValue = (float)i.Model[ageVar]; Assert.IsTrue(ageValue >= 1 && ageValue <= 20); } }
private Invention TestExistence(CommonNoun noun, IEnumerable <MonadicConceptLiteral> modifiers) { var g = new Generator(Noun, Modifiers, 1); try { return(g.Solve()); } catch (CatSAT.ContradictionException) { return(null); } catch (CatSAT.TimeoutException) { return(null); } }
public void TotalFunction() { Ontology.EraseConcepts(); ParseAndExecute("people must love one person"); var v = Verb.Find("loves"); var g = new Generator(CommonNoun.Find("person"), new MonadicConceptLiteral[0], 10); for (var n = 0; n < 100; n++) { var s = g.Solve(); foreach (var i in s.Individuals) { var count = s.Individuals.Count(i2 => s.Holds(v, i, i2)); Assert.IsTrue(count == 1); } } }
private Noun GetCommonNoun(string[] text) { var noun = (CommonNoun)Noun.Find(text); if (noun != null) { var singular = noun.SingularForm.SameAs(text); if (singular && Number == Syntax.Number.Plural && !noun.SingularForm.SameAs(noun.PluralForm)) { throw new GrammaticalError($"The singular noun '{Text.Untokenize()}' was used without 'a' or 'an' before it", $"The singular noun '<i>{Text.Untokenize()}</i>' was used without 'a' or 'an' before it"); } if (!singular && Number == Syntax.Number.Singular) { throw new GrammaticalError($"The plural noun '{Text.Untokenize()}' was used with 'a' or 'an'", $"The plural noun '<i>{Text.Untokenize()}</i>' was used with 'a' or 'an' before it"); } return(noun); } noun = new CommonNoun(); if (!Number.HasValue) { // Don't know syntactically if it's supposed to be singular or plural, so guess. Number = Inflection.NounAppearsPlural(text) ? Syntax.Number.Plural : Syntax.Number.Singular; } if (Number == Syntax.Number.Singular) { noun.SingularForm = text; } else { // Note: this guarantees there is a singular form. noun.PluralForm = text; } Driver.AppendResponseLine($"Learned the new common noun <b><i>{noun.SingularForm.Untokenize()}</i></b>."); MaybeLoadDefinitions(noun); return(noun); }
private void AddParts(Individual i, CommonNoun k) { foreach (var part in k.Parts) { var partSet = Enumerable.Range(1, part.Count).Select(index => Ontology.EphemeralIndividual(part.MonadicConcepts, null, i, part)).ToArray(); i.Parts[part] = partSet; EphemeralIndividuals.AddRange(partSet); foreach (var p in partSet) { AddParts(p); } } foreach (var super in k.Superkinds) { AddParts(i, super); } }
public bool CanBeA(Individual i, CommonNoun kind) { bool SearchUp(CommonNoun k) { if (k == kind) { return(true); } foreach (var super in k.Superkinds) { if (SearchUp(super)) { return(true); } } return(false); } bool SearchDown(CommonNoun k) { if (k == kind) { return(true); } foreach (var sub in k.Subkinds) { if (SearchDown(sub)) { return(true); } } return(false); } foreach (var k in i.Kinds) { if (SearchUp(k) || SearchDown(k)) { return(true); } } return(false); }
/// <summary> /// Individual i is of kind k; randomly choose a subkind, if k has subkinds. /// </summary> private void SelectInitialSubkind(Individual i, CommonNoun k) { if (k.Subkinds.Count == 0) { // nothing to do return; } var sub = k.RandomSubkind; //Console.Write(sub); Console.Write(' '); foreach (var s in k.Subkinds) { SetIsA(i, s, s == sub); if (s == sub) { // This is the chosen subkind, so choose sub-sub-kinds SelectInitialSubkind(i, s); } else { // This one wasn't chosen, so set it and all its children to false DeselectSubkinds(i, s); } } foreach (var set in k.AlternativeSets) { if (set.AllowPreInitialization && set.AllSingleReferenceAdjectives) { var chosen = set.RandomAlternative; //Console.Write(chosen); //Console.Write(' '); if (set.MinCount == 1 && set.MaxCount == 1) { foreach (var alt in set.Alternatives) { SetLiteral(i, alt, alt == chosen); } } } } }
public void PartialFunction() { Ontology.EraseConcepts(); ParseAndExecute("people can love one person"); var v = Verb.Find("loves"); var g = new Generator(CommonNoun.Find("person"), new MonadicConceptLiteral[0], 3); bool sawNonTotal = false; for (var n = 0; n < 300; n++) { var s = g.Solve(); foreach (var i in s.Individuals) { var count = s.Individuals.Count(i2 => s.Holds(v, i, i2)); Assert.IsFalse(count > 1); sawNonTotal |= count == 0; } } Assert.IsTrue(sawNonTotal); }
private string FormatNameFromTemplate(Individual i, List <Property> suppressedProperties, CommonNoun kind) { var b = new StringBuilder(); var t = kind.NameTemplate; var firstOne = true; for (var n = 0; n < t.Length; n++) { if (firstOne) { firstOne = false; } else { b.Append(' '); } var token = t[n]; if (token == "[") { // Get a property name var start = n + 1; var end = Array.IndexOf(t, "]", n); if (end < 0) { end = t.Length; } var propertyName = new string[end - start]; Array.Copy(t, start, propertyName, 0, end - start); // Find the property var property = kind.PropertyNamed(propertyName); if (property == null) { b.Append($"<unknown property {propertyName.Untokenize()}>"); } else { // Print its value b.Append(Model[i.Properties[property]]); suppressedProperties?.Add(property); } n = end; } else { b.Append(token); } } return(b.ToString()); }
private void AppendPropertyValue(StringBuilder b, Individual i, string[] propertyName, CommonNoun templateKind, List <Property> suppressedProperties) { // Find the property var property = templateKind.PropertyNamed(propertyName); if (property != null) { // Print its value b.Append(Model[i.Properties[property]]); suppressedProperties?.Add(property); } else { var part = templateKind.PartNamed(propertyName); if (part != null) { b.Append(Description(i.Parts[part])); } else { b.Append($"<unknown property {propertyName.Untokenize()}>"); } } }
private void AppendPropertyOrMetaPropertyValue(StringBuilder b, Individual i, string[] propertyName, List <Property> suppressedProperties, CommonNoun templateKind, string startEmphasis, string endEmphasis) { switch (propertyName[0]) { case "NameString": b.Append(NameString(i, suppressedProperties)); break; case "Modifiers": b.Append(AllModifiersOf(i)); break; case "Noun": b.Append(NounsDescribing(i, startEmphasis, endEmphasis)); break; case "AllProperties": DescribeAllProperties(i, suppressedProperties, b); break; default: AppendPropertyValue(b, i, propertyName, templateKind, suppressedProperties); break; } }
private string FormatNameFromTemplate(Individual i, List <Property> suppressedProperties, CommonNoun kind) { var b = new StringBuilder(); var t = kind.NameTemplate; var firstOne = true; for (var n = 0; n < t.Length; n++) { if (firstOne) { firstOne = false; } else { b.Append(' '); } var token = t[n]; if (token == "[") { // Get a property name var start = n + 1; var end = Array.IndexOf(t, "]", n); if (end < 0) { end = t.Length; } var propertyName = new string[end - start]; Array.Copy(t, start, propertyName, 0, end - start); AppendPropertyOrMetaPropertyValue(b, i, propertyName, suppressedProperties, kind); n = end; } else { b.Append(token); } } return(b.ToString()); }
public static void AddTest(CommonNoun noun, IEnumerable <MonadicConceptLiteral> modifiers, bool shouldExist, string succeedMessage, string failMessage) { Tests.Add(new Test(noun, modifiers, shouldExist, succeedMessage, failMessage)); }
/// <summary> /// Creates a generator for objects of the specified types /// </summary> /// <param name="noun">Base common noun for the object</param> /// <param name="concepts">Other monadic concepts that must be true of the object</param> public Generator(CommonNoun noun, params MonadicConceptLiteral[] concepts) : this(noun, (IEnumerable <MonadicConceptLiteral>)concepts) { }