!752 concepts. // a named concept concept NConcept { S name; *() {} *(S *name) { change(); } } concept HasA { new Ref a; new Ref b; *() {} *(NConcept a, NConcept b) { this.a.set(a); this.b.set(b); } } concept IsA { new Ref a; new Ref b; *() {} *(NConcept a, NConcept b) { this.a.set(a); this.b.set(b); } } concept IsCollectionOf { new Ref a; new Ref b; *() {} *(NConcept a, NConcept b) { this.a.set(a); this.b.set(b); } } concept SizeOfCollection extends IsCollectionOf { int n; *() {} *(NConcept a, int n, NConcept b) { super(a, b); this.n = n; change(); } } sS text = [[ What is a FUNCTION? A function has a NAME. A name is a STRING. A STRING is a COLLECTION of CHARACTERS. "The ALPHABET" is a COLLECTION of CHARACTERS. "The ALPHABET" contains 26 CHARACTERS. "The DIGITS" is a COLLECTION of CHARACTERS. "The DIGITS" contains 26 CHARACTERS. "SPACE" is a CHARACTER. ]]; p { loadAndAutoSaveConcepts(); new Matches m; for (S s : toLinesFullTrim(text)) { if "What is a *" getConcept(m, 0); if "A * has a *" hasA(getConcept(m, 0), getConcept(m, 1)); if "A * is a collection of *" isCollectionOf(getConcept(m, 0), getConcept(m, 1)); if (match("A * contains * *", s, m) && isInteger(m.unq(1))) sizeOfCollection(getConcept(m, 0), m.psi(1), getConcept(m, 2)); if "* is a *" isA(getConcept(m, 0), getConcept(m, 1)); } } static NConcept getConcept(Matches m, int i) { S conceptName = singular(toLowerCase(m.unq(0))); ret uniqueConcept(NConcept.class, "name", conceptName); } svoid hasA(NConcept a, NConcept b) { uniqueConcept(HasA.class, "a", a, "b", b); } svoid isCollectionOf(NConcept a, NConcept b) { uniqueConcept(IsCollectionOf.class, "a", a, "b", b); } svoid sizeOfCollection(NConcept a, int n, NConcept b) { uniqueConcept(SizeOfCollection.class, "a", a, "n", n, "b", b); } svoid isA(NConcept a, NConcept b) { uniqueConcept(IsA.class, "a", a, "b", b); }