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

199
LINES

< > BotCompany Repo | #1003526 // LooseBot v6 (with modified isCommand)

JavaX fragment (include)

// adapters are immutable! (plus returns a modified clone)
abstract sclass Adapter {
  abstract bool canMatch(S in, S out);
  Adapter plus(S in, S out) { ret this; }
  S get(S in) { ret in; }
  abstract double size();
}

// node in flight (+ optional adapter)
sclass InFlight {
  OccTree2 node;
  Adapter adapter;
  
  *(OccTree2 *node) {}
  *(OccTree2 *node, Adapter *adapter) {}
  
  E adapted() {
    // TODO: security when rewriting states
    ret adapter == null ? node.e : new E(adapter.get(node.e.text()), node.e.type());
  }
}

sclass LooseBot {
  sbool debug, repeat = true;
  OccTree2 tree;
  new L<InFlight> nodes;
  new L<L> rewindStack;
  O newAdapter;
  O grabber; // func(S -> E)

  // WordAdapter now default
  *(OccTree2 tree) { this(tree, func { new WordAdapter }); }
  *(OccTree2 *tree, O *newAdapter) {}
  *(S theme) { this(makeOccTree(theme)); }
  *(S theme, O newAdapter) { this(makeOccTree(theme), newAdapter); }
  
  Adapter makeAdapter() {
    ret newAdapter == null ? null : (Adapter) call(newAdapter);
  }
  
  void take(E in) {
    remember();
    
    // try starting over from beginning of tree too
    if (repeat) setAdd(nodes, new InFlight(tree, makeAdapter()));
    
    new L<InFlight> l;
    
    // try grabber
    if (grabber != null && in.q()) try {
      E grabbed = cast callFunction(grabber, in.text());
      if (grabbed != null) {
        if (debug)
          print("Grabber worked! " + in.text() + " => " + grabbed);
          
        // make a mini tree with Q + A so it is matched in
        // next call to getSingleOutput()
        OccTree2 node = new OccTree2(in);
        node.next.add(new OccTree2(grabbed));
        
        l.add(new InFlight(node));
      } else
        if (debug)
          print("Grabber didnt't return anything. " + in.text());
    } catch e {
      if (debug) printStackTrace(e);
    }
    
    for (InFlight flight : nodes)
      for (OccTree2 n : flight.node.next)
        if (eq(n.e.type(), in.type()) && (flight.adapter != null
          ? flight.adapter.canMatch(n.e.text(), in.text())
          : matchE(n.e, in))) {
          l.add(new InFlight(n, flight.adapter == null ? null
            : flight.adapter.plus(n.e.text(), in.text())));
        }
    nodes = l;
  }
  
  void remember() {
    if (rewindStack != null)
      rewindStack.add(cloneList(nodes));
  }
  
  E getSingleOutput() {
    remember();
    new L<InFlight> l;
    for (InFlight flight : nodes)
      for (OccTree2 n : flight.node.next)
        if (n.e.a() || isCommand(n.e))
          l.add(new InFlight(n, flight.adapter));
    if (empty(l)) { rewind(); null; }
    nodes = l;
    ret first(nodes).adapted();
  }
  
  void rewind() {
    nodes = popLast(rewindStack);
  }
  
  bool isCommand(E e) {
    ret !isInput(e);
  }
    
  // see Dialog Optimizer
  bool isInput(E e) {
    ret e.q()
      || e.state() && matchStart("result is ", e.text());
  }

  void noRewind() {
    rewindStack = null;
  }
  
  bool matchE(E a, E b) {
    // standard NL matching
    ret eq(a.type(), b.type()) && match(a.text(), b.text());
  }
  
  S nodesToString(L<InFlight> nodes) {
    new L<S> l;
    l.add(n(l(nodes), "node") + "\n");
    for (InFlight flight : nodes) {
      l.add(str(flight.node.e));
      if (flight.adapter != null)
        l.add("  " + flight.adapter);
    }
    ret rtrim(fromLines(l));
  }
  
  S thoughts() {
    new L<S> l;
    l.add(nodesToString(nodes));
    if (rewindStack != null) {
      l.add("\nHistory\n");
      for (L<InFlight> nodes : reversedList(rewindStack))
        l.add(indent(nodesToString(nodes)));
    }
    ret fromLines(l);
  }
}

sclass WordAdapter extends Adapter {
  new Map<S, S> wordMap;
  
  L<S> tok(S s) {
    ret nlTok2(dropPunctuation2(s));
  }
  
  bool canMatch(S in, S out) {
    L<S> t1 = tok(in), t2 = tok(out);
    ret l(t1) == l(t2);
  }
  
  Adapter plus(S in, S out) {
    L<S> t1 = tok(in), t2 = tok(out);
    if (l(t1) != l(t2)) ret this;
    
    WordAdapter a = cast nuObject(getClass());
    a.wordMap = cloneMap(wordMap);
    for (int i = 1; i < l(t1); i += 2) {
      S w1 = t1.get(i), w2 = t2.get(i);
      if (!eqic(w1, w2))
        // just overwrite - be flexible!
        a.wordMap.put(w1.toLowerCase(), w2.toLowerCase());
    }
    ret a;
  }
  
  S get(S s) {
    L<S> tok = nlTok2(s);
    for (int i = 1; i < l(tok); i += 2) {
      S w = lookupToken(tok.get(i));
      if (nempty(w))
        tok.set(i, w);
    }
    ret join(tok);
  }
  
  S lookupToken(S s) {
    ret wordMap.get(s.toLowerCase());
  }
  
  double size() {
    ret l(wordMap);
  }
  
  public S toString() {
    ret structure(wordMap);
  }
}

sclass WordAdapter2 extends WordAdapter {
  new Map<S, S> wordMap;
  
  L<S> tok(S s) {
    ret nlTok2(s);
  }
}

Author comment

Began life as a copy of #1003413

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: #1003526
Snippet name: LooseBot v6 (with modified isCommand)
Eternal ID of this version: #1003526/1
Text MD5: d15b197a4ac77ba95829a13c049b3a4f
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-07-11 01:46:56
Source code size: 4945 bytes / 199 lines
Pitched / IR pitched: No / No
Views / Downloads: 530 / 909
Referenced in: #1003508 - Engine / Sag mir das Datum
#1003527 - Generic Bot Chat