Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

335
LINES

< > BotCompany Repo | #1005254 // Logic 3 [Include, with synonyms]

JavaX fragment (include)

concepts.

!include #1005279 // Str, concept, mergeStrs

concept AThing {
  new Ref thing;
  
  *() {}
  *(Concept thing) { this.thing.set(thing); }
}

concept DefiniteThing {}

static AThing aThing(S name) {
  ret uniqueConcept(AThing.class, "thing", concept(name));
}

// "main" has a number of "part"s.
concept HasMulti {
  new Ref main;
  new Ref part;
}

// "main" has exactly "count" "part"s.
concept MultiCount {
  new Ref main;
  new Ref part;
  int count;
}

// "main" has a "part".
concept HasA {
  new Ref main;
  new Ref part;
}

// "main" has "part".
concept Has {
  new Ref main;
  new Ref part;
}

concept IsA {
  new Ref thing;
  new Ref type;
}

concept TheXOfY {
  new Ref x;
  new Ref y;
}

concept Question {
  S originalText;
}

concept OpenQuestion {
  new Ref<Question> question;
}

concept AnsweredQuestion {
  new Ref<Question> question;
  new Ref answer;
}

concept ConceptList {
  new RefL<Concept> list;
  
  *() {}
  *(L l) { list.addAll_(l); }
  
  void addAll(L l) {
    list.addAll(l);
  }
}

concept HowManyAreIn extends Question {
  new Ref main;
  new Ref part;
}

concept DoesXHaveAY extends Question {
  new Ref x;
  new Ref y;
}

concept WhatDoesXHave extends Question {
  new Ref thing;
}

concept Yes {}
concept No {}

svoid processRulesMulti {
  for (int i = 0; i < 1000; i++) {
    long n = changes;
    processRules();
    long n2 = changes;
    if (n2 > n)
      print(n(n2-n, "change") + " (concepts: " + countConcepts() + ")");
    else
      ret;
  }
  print("safety limit reached (1000 iterations)");
}

svoid answerQuestion(Question question, Concept answer) {
  cdelete(OpenQuestion.class, "question", question);
  uniqueConcept(AnsweredQuestion.class, "question", question, "answer", answer);
}

svoid answerQuestion(Question question, bool answer) {
  answerQuestion(question, uniqueConcept(answer ? Yes.class : No.class));
}

svoid printConcepts {
  print();
  for (Concept c : allConcepts())
    printConcept(c);
}

svoid printConcept(Concept c) {
  print(renderConcept(c));
}

static S renderConcept(Concept.Ref ref) {
  ret renderConcept(ref.get());
}

static S renderConcept(Concept c) {
  new StringBuilder buf;
  if (c == null) buf.append("null");
  /*else if (c instanceof ConceptList) {
    for (Concept c2 : ((ConceptList) c).list)
      buf.append(renderConcept(c2) + "\n");
  }*/ else {
    buf.append(c.id + " " + shortDynamicClassName(c));
    for (S field : listFields(c)) {
      O val = cget(c, field);
      if (val != null) {
        buf.append(" " + field + "=");
        buf.append(renderConceptShort(val));
      }
    }
  }
  ret str(buf);
}

static S renderConceptShort(O val) {
  if (val instanceof Str)
    ret quote(((Str) val).name);
  else if (val instanceof AThing)
    ret "a " + renderConceptShort(((AThing) val).thing.get());
  else if (val instanceof Concept)
    ret shortDynamicClassName(val) + ((Concept) val).id;
  else
    ret struct(val);
}

static S renderQuestion(Concept.Ref<Question> q) {
  ret renderQuestion(q.get());
}

static S renderQuestion(Question q) {
  ret q.originalText + " (" + shortDynamicClassName(q) + ")";
}

svoid printQuestionsAndAnswers {
  L<OpenQuestion> open = list(OpenQuestion.class);
  if (nempty(open)) {
    printAsciiHeading("Open questions");
    for (OpenQuestion oq : open)
      printIndent(renderQuestion(oq.question));
  }
  
  L<AnsweredQuestion> answered = list(AnsweredQuestion.class);
  if (nempty(answered)) {
    printAsciiHeading("Answered questions");
    for (AnsweredQuestion aq : answered) {
      printIndent(2, renderQuestion(aq.question));
      Concept a = aq.answer.get();
      if (a instanceof ConceptList)
        for (Concept c2 : ((ConceptList) a).list)
          printIndent(4, renderConcept(c2));
      else
        printIndent(4, renderConcept(a));
    }
  }
}

static bool logic_parse(S s) {
  new Matches m;
  if "the plural of * is *" {
    assertEqic(m.unq(1), plural(m.unq(0)));
    assertEqic(m.unq(0), singular(m.unq(1)));
    true;
  }
  
  if "a * has *" {
    Concept main = aThing(m.unq(0));
    Concept part = concept(singularFromPlural(m.unq(1)));
    uniqueConcept(HasMulti.class, "main", main, "part", part);
    true;
  }
  
  if "a * has a *" {
    Concept main = aThing(m.unq(0));
    Concept part = concept(m.unq(1));
    uniqueConcept(HasA.class, "main", main, "part", part);
    true;
  }
  
  if "the number of * in a * is *" {
    Concept main = aThing(m.unq(1));
    Concept part = concept(singularFromPlural(m.unq(0)));
    int n = parseInt(m.unq(2));
    uniqueConcept(MultiCount.class, "main", main, "part", part, "count", n);
    true;
  }
  
  if "let's assume * is a *" || "* is a *" {
    Concept thing = concept(m.unq(0));
    Concept type = aThing(m.unq(1));
    uniqueConcept(IsA.class, "thing", thing, "type", type);
    true;
  }
  
  if "how many * are in *" {
    Concept main = concept(m.unq(1));
    Concept part = concept(singularFromPlural(m.unq(0)));
    uniqueConcept(OpenQuestion.class, "question",
      uniqueConcept(HowManyAreIn.class, "originalText", s, "main", main, "part", part));
    true;
  }
  
  if "what does * have" {
    Concept thing = concept(m.unq(0));
    newQ(uniqueConcept(WhatDoesXHave.class, "originalText", s, "thing", thing));
    true;
  }
  
  if "does * have a *" {
    Concept x = concept(m.unq(0));
    Concept y = concept(m.unq(1));
    newQ(uniqueConcept(DoesXHaveAY.class, "originalText", s, "x", x, "y", y));
    true;
  }
  
  if "* is a synonym of *" {
    mergeStrs(concept(m.unq(0)), concept(m.unq(1)));
    true;
  }
  
  if (trim(s).endsWith("?")) {
    uniqueConcept(OpenQuestion.class, "question",
      uniqueConcept(Question.class, "originalText", s));
    true;
  }
  
  false;
}

static void newQ(Question q) {
  uniqueConcept(OpenQuestion.class, "question", q);
}

static void logic_processRules {
  // Infer statements.
  
  // x is a y && a y has n z => x has n z
  
  for (IsA isA : list(IsA.class)) {
    Concept x = isA.thing.get(), y = isA.type.get();
    for (MultiCount mc : conceptsWhere(MultiCount.class, "main", y))
      uniqueConcept(MultiCount.class, "main", x, "part", mc.part, "count", mc.count); // todo: automate the copying
  }
  
  // x is a y && a y has a z => x has a z
  for (IsA isA : list(IsA.class)) {
    Concept x = isA.thing.get(), y = isA.type.get();
    for (HasA h : conceptsWhere(HasA.class, "main", y))
      uniqueConcept(HasA.class, "main", x, "part", h.part);
  }
  
  // x has a y => x has "the y of x"
  for (HasA h : list(HasA.class))
    if (h.main.get() instanceof DefiniteThing)
      uniqueConcept(Has.class, "main", h.main, "part",
        uniqueConcept(TheXOfY.class, "x", h.part, "y", h.main));

  // Answer questions.
  
  for (OpenQuestion oq : list(OpenQuestion.class)) {
    Question _q = oq.question.get();
    
    if (_q instanceof HowManyAreIn) {
      HowManyAreIn q = cast _q;
      MultiCount mc = conceptWhere(MultiCount.class, "main", q.main, "part", q.part);
      if (mc != null)
        answerQuestion(q, mc);
    }
    
    if (_q instanceof WhatDoesXHave) {
      WhatDoesXHave q = cast _q;
      new ConceptList l;
      l.addAll(conceptsWhere(HasA.class, "main", q.thing));
      l.addAll(conceptsWhere(Has.class, "main", q.thing));
      answerQuestion(q, l);
    }
    
    if (_q instanceof DoesXHaveAY) {
      DoesXHaveAY q = cast _q;
      if (hasConcept(HasA.class, "main", q.x, "part", q.y))
        answerQuestion(q, true);
    }
 }
}

svoid logic_main {
  L<S> sentences = sentencesFromHTML(input);
  print(numberLines(sentences));
  
  for (S s : sentences) {
    if (!logic_parse(s))
      print("? " + s);
  }
  
  processRulesMulti();
  printConcepts();
  printQuestionsAndAnswers();
  if (countConcepts(OpenQuestion.class) == 0)
    print("\nAll questions answered!");
  else
    print("\nOpen questions remaining.");
}

Author comment

Began life as a copy of #1005253

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1005254
Snippet name: Logic 3 [Include, with synonyms]
Eternal ID of this version: #1005254/1
Text MD5: 2d63ecffbf9446f20f48106c6c223707
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-10-29 02:37:32
Source code size: 8181 bytes / 335 lines
Pitched / IR pitched: No / No
Views / Downloads: 551 / 503
Referenced in: #1005325 - Logic 4 [Include, dev.]