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

1276
LINES

< > BotCompany Repo | #1030833 // BEACalculations [Include]

JavaX fragment (include) [tags: use-pretranspiled]

1  
sclass BEACalculations {
2  
  GazelleBEA mod;  
3  
  *(GazelleBEA *mod) {}
4  
5  
  transient int liveOutputDelay = 1000;
6  
  transient double algoTimeout = 30.0;
7  
  
8  
  void reactAllInputsWithSomePatterns() {
9  
    for (BEAObject input : mod.beaObjectsOfType("input")) {
10  
      new ReactInputWithSomePatterns r;
11  
      r.input = input;
12  
      r.ccOut = db_mainConcepts();
13  
      r.max = 10;
14  
      r.start();
15  
      stepAllWithTimeout(10.0, r);
16  
    }
17  
  }
18  
19  
  void reactAllInputsWithAllSyntacticPatterns() {
20  
    for ping (BEA input : mod.beaList("input")) {
21  
      for ping (BEA pattern : mod.beaList("Syntactic Pattern")) {
22  
        continue if patternAlwaysMatches(pattern);
23  
        reactInputWithPattern(input, pattern);
24  
      }
25  
    }
26  
  }
27  
28  
  void reactAllInputsWithPattern(BEA pattern) {
29  
    for ping (BEA input : mod.beaList("input"))
30  
      reactInputWithPattern(input, pattern);
31  
  }
32  
33  
  bool patternAlwaysMatches(BEA pat) {
34  
    ret isTrue_getOpt alwaysMatches(pat);
35  
  }
36  
  
37  
  class ReactInputWithSomePatterns implements Steppable {
38  
    BEAObject input;
39  
    Concepts ccOut;
40  
    int max = 3, n;
41  
    Iterator<BEAObject> patterns;
42  
43  
    void start {
44  
      n = countConceptsWhereIC(ccOut, BEAObject, +input, type := "match");
45  
      patterns = iterator(sortByConceptID(conceptsWhereIC BEAObject(type := "Pattern")));
46  
    }
47  
    
48  
    public bool step() {
49  
      if (n >= max) false;
50  
      if (!patterns.hasNext()) false;
51  
      if (reactInputWithPattern(input, patterns.next(), ccOut) != null)
52  
        ++n;
53  
      true;
54  
    }
55  
  }
56  
57  
  // (patern, mapping)
58  
  Pair<BEA, SS> matchInputWithPatternList(S text, BEA patternList) {
59  
    L<BEA> patterns = cast cget patterns(patternList);
60  
    fOr (BEA pattern : patterns) {
61  
      SS mapping = matchInputWithPattern(text, pattern);
62  
      if (mapping != null) ret pair(pattern, mapping);
63  
    }
64  
    null;
65  
  }
66  
67  
  // we don't do this anymore
68  
  new ThreadLocal<Bool> matchInput_droppedPunctuation;
69  
70  
  SS matchInputWithPattern(BEAObject input, BEAObject pattern) {
71  
    S text = getString text(input);
72  
    ret matchInputWithPattern(text, pattern);
73  
  }
74  
    
75  
  SS matchInputWithPattern(S text, BEAObject pattern) {
76  
    S pat = getString text(pattern);
77  
    bool punctuationOnly = isTrue_getOpt punctuationOnly(pattern);
78  
79  
    if (pattern.typeIs("Syntactic Pattern"))
80  
      ret matchInputWithSyntacticPattern(text, pat, punctuationOnly);
81  
    else if (eqic_gen(pattern~.subType, "PhraseCache"))
82  
      ret phraseCache(pat, text) ? litmap() : null;
83  
    else
84  
      ret matchInputWithPattern(text, pat, punctuationOnly);
85  
  }
86  
87  
  SS matchInputWithSyntacticPattern(S text, S pat, bool punctuationOnly default false) {
88  
    pat = starsToAngleBracketedNumbers(pat);
89  
    ret matchInputWithPattern(text, pat, punctuationOnly);
90  
  }
91  
      
92  
  SS matchInputWithPattern(S text, S pat, bool punctuationOnly default false) {
93  
    SS mapping = flexMatchAngleBracketVarsIC_honorPunctuation_noBrackets_first(pat, text);
94  
    if (mapping != null || punctuationOnly) ret mapping;
95  
    /*matchInput_droppedPunctuation.set(true);
96  
    ret flexMatchAngleBracketVarsIC_first(pat, text);*/
97  
    null; // not doing the implicit punctuation drop anymore (it's now an explicit pattern)
98  
  }
99  
  
100  
  BEAObject reactInputWithPattern(BEAObject input, BEAObject pattern, Concepts ccOut default db_mainConcepts()) {
101  
    if (input == null || pattern == null) null;
102  
    matchInput_droppedPunctuation.set(false);
103  
    SS mapping = matchInputWithPattern(input, pattern);
104  
    //printVars_str("reactInputWithPattern", +input, +pattern, +mapping);
105  
    if (mapping == null) null;
106  
    BEA match = uniqCI(ccOut, BEA,
107  
      type := "Match",
108  
      +input,
109  
      +pattern);
110  
    cset(match,
111  
      +mapping,
112  
      droppedPunctuation := trueOrNull(matchInput_droppedPunctuation!),
113  
    );
114  
    ret match;
115  
  }
116  
  
117  
  O serveAnalyzeInput(GazelleBEA.Req req) {
118  
    new Concepts ccOut;
119  
    BEAObject input = getConcept BEAObject(parseLong(req.get("id")));
120  
    if (input == null)
121  
      input = cnew(ccOut, BEAObject, type := "Input", text := req.get("q"));
122  
    S text = getString text(input);
123  
    new ReactInputWithSomePatterns r;
124  
    r.input = input;
125  
    r.ccOut = ccOut;
126  
    r.max = 1000;
127  
    r.start();
128  
    stepAllWithTimeout(10.0, r);
129  
    Cl matches = conceptsWhereIC(ccOut, BEAObject, type := "Match");
130  
    ret h1_title("Analyze Input")
131  
      + p("Input: " + b(htmlEncode_nlToBr_withIndents(text)))
132  
      + p(empty(matches) ? "No matches" : "Matches")
133  
      + ul_htmlEncode(matches);
134  
  }
135  
  
136  
  O serveQueryPage(GazelleBEA.Req req, bool withFrame default false) {
137  
    S q = req.get("q"), algorithm = req.get("algorithm");
138  
    bool dontRun = eq(req.get("dontRun"), "1");
139  
    bool liveOutput = eq(req.get("liveOutput"), "1");
140  
    if (liveOutput) req.noSpam();
141  
142  
    if (eqic(algorithm, "process input"))
143  
      algorithm = "Process new input v3";
144  
145  
    //if (liveOutput) ret jsonEncode(litmap(answer := "Live output demo: " + htmlEncode2(q)));
146  
147  
    Map<S, IF0<Algorithm>> algorithms = algorithms();
148  
149  
    S output = empty(algorithm) || dontRun ? null : doAlgorithm(algorithms, algorithm, q, liveOutput);
150  
151  
    if (liveOutput)
152  
      ret jsonEncode(litorderedmap(answer := output));
153  
    
154  
    S right = withFrame ? "" : mod.html_loggedIn();
155  
    
156  
    Algorithm alg = callF(lookupPossiblyCI(algorithms, algorithm));
157  
    if (alg != null) {
158  
      alg.q = q;
159  
      alg.req = mod.currentReq();
160  
    }
161  
    
162  
    S centered = 
163  
        (withFrame ? "" : htitle_h2(ahref(mod.baseLink + "/", "Gazelle") + " Query"
164  
        + htmlEncode2((empty(q) ? "" : ": " + q)
165  
        + appendSquareBracketed(algorithm))))
166  
      + hscript(replaceVars([[
167  
          var sugLoading = false, sugTriggerAgain = false;
168  
169  
          function sugTrigger() {
170  
            console.log("sugTrigger");
171  
            if (sugLoading) { sugTriggerAgain = true; return; }
172  
173  
            // get form data as JSON
174  
            
175  
            var data = {
176  
              "liveOutput" : "1",
177  
              "q": $("textarea[name=q]").val(),
178  
              "algorithm": $("select[name=algorithm]").val(),
179  
              "algorithmID": $("select[name=algorithmID]").val(), // XXX: do this for all additional alg parameters
180  
            };
181  
            
182  
            const url = "/query";
183  
            console.log("Loading " + url + " with " + data);
184  
            sugLoading = true;
185  
            $.post(url, data,
186  
              function(result) {
187  
                console.log("Suggestor result: " + result);
188  
                const answer = !result ? "" : JSON.parse(result).answer;
189  
                if (answer) {
190  
                  $("#liveResult .sectionContents").html(answer);
191  
                  $("#liveResult").show();
192  
                } else
193  
                  $("#liveResult").hide();
194  
                //$("#suggestorResult").html(answer ? "Suggestor says: " + answer : "");
195  
              }
196  
            ).always(function() {
197  
              console.log("sug loading done");
198  
              setTimeout(function() {
199  
                sugLoading = false;
200  
                if (sugTriggerAgain) { sugTriggerAgain = false; sugTrigger(); }
201  
              }, liveOutputDelay);
202  
            });
203  
          }
204  
205  
          $(document).ready(function() {
206  
            $("textarea[name=q], input[name=q], select[name=algorithm]").on('input propertychange change', sugTrigger);
207  
            sugTrigger();
208  
          });
209  
        ]], +liveOutputDelay))
210  
      + hform(p("Query (Ctrl+Enter): "
211  
          + htextarea(q,
212  
              id := "mainInput", 
213  
              name := "q", 
214  
              class := "auto-expand",
215  
              style := "width: 300px",
216  
              onkeydown := jquery_submitFormOnCtrlEnter(),
217  
              autofocus := dontRun || empty(q) ? true : null // autofocus for live output mode
218  
            ) + " "
219  
          /*+ hjs([[$(document).ready(function() {
220  
              autoExpandTextArea(document.getElementById("mainInput"));
221  
          });]])*/
222  
        //+ htextfield(+q, style := "width: 300px; text-align: center", autofocus := true)
223  
        + (alg == null ? "" : alg.additionalInputs())
224  
        + " &nbsp; Algorithm: " 
225  
        + hselect_list(keys(algorithms), algorithm, name := "algorithm") + " &nbsp; " + hbutton("Go")));
226  
    
227  
    S content = (empty(right) ? "" : div_alignRight(right))
228  
      + div_center(centered)
229  
      + htitledSectionWithDiv("Live Result", "",
230  
         id := "liveResult", style := "display: none",
231  
         innerDivStyle := "max-height: 150px; overflow: auto")
232  
      + (output == null ? "" : h3(algorithm) + output);
233  
      
234  
    if (withFrame) {
235  
      req.framer.addInHead(hjs_handleScrollToAnchor());
236  
      req.framer.add(content);
237  
      ret mod.completeFrame(req);
238  
    } else
239  
      ret hhtml(hhead(
240  
          hmobilefix() + hsansserif() + 
241  
          loadJQuery2() + 
242  
          hjs_handleScrollToAnchor() +
243  
          hjs_autoExpandingTextAreas() +
244  
          mod.webSocketHeadStuff(req) +
245  
          hNotificationPopups())
246  
        + hbody(content));
247  
  }
248  
  
249  
  S doAlgorithm(Map<S, IF0<Algorithm>> algorithms, S algorithm, S q, bool liveMode) {
250  
    GazelleBEA.Req req = mod.currentReq();
251  
    StringBufferWithMaxSize out = new(1000000); // TODO: make sure HTML tags are closed properly
252  
    
253  
    IF0<Algorithm> algo = lookupPossiblyCI(algorithms, algorithm);
254  
    if (algo == null)
255  
      out.append("Algorithm not found: " + algorithm);
256  
    else {
257  
      if (isB(evalWithTimeout(algoTimeout, r {
258  
        temp mod.enter();
259  
        temp tempSetTL(mod.currentReq, req);
260  
        Algorithm alg = algo!;
261  
        alg.liveMode = liveMode;
262  
        alg.out = out;
263  
        alg.q = q;
264  
        alg.req = mod.currentReq();
265  
        alg.runIt();
266  
      })))
267  
        out.append("\n[algorithm timeout]");
268  
    }
269  
    
270  
    ret str(out);
271  
  }
272  
  
273  
  class Algorithm implements Runnable {
274  
    S q;
275  
    GazelleBEA.Req req;
276  
    Appendable out;
277  
    //Appendable outPrio = new StringBufferWithMaxSize(10000);
278  
    bool liveMode;
279  
    Concepts localConcepts = db_mainConcepts(); //= childConcepts(db_mainConcepts());
280  
    L<Runnable> nonMatches; // null so not filled by default
281  
282  
    // override for normal mode
283  
    run {}
284  
285  
    // override for live mode
286  
    void runLiveMode {}
287  
288  
    /*void cleanForStorage {
289  
      out = outPrio = null;
290  
    }*/
291  
292  
    // overridable
293  
    S additionalInputs() { ret ""; }
294  
    
295  
    void appendHTML(Appendable out default this.out, S html) ctex {
296  
      if (empty(html)) ret;
297  
      html = wrapInDiv(html, style := "margin-top: 0.5em");
298  
      out.append(html).append("\n");
299  
    }
300  
301  
    void appendHTML_raw(S html) ctex { out.append(html).append("\n"); }
302  
    
303  
    void appendText(Appendable out default this.out, S text) ctex {
304  
      if (empty(text)) ret;
305  
      out.append(hpre_htmlencode(rtrim(text)));
306  
    }
307  
    
308  
    void appendTextBold(Appendable out default this.out, S text) ctex {
309  
      if (empty(text)) ret;
310  
      out.append(b(hpre_htmlencode(rtrim(text))));
311  
    }
312  
    
313  
    void allowSuggestingAnswer(BEAObject input) {
314  
      if (input == null) ret;
315  
      S text = input.text();
316  
        
317  
      S url = mod.baseLink + "/saveAnswer";
318  
      appendHTML(
319  
        hpostform("Suggest an answer to " + htmlEncode_quote(text) + ": "
320  
          //+ hinputfield(+text, style := "width: 300px")
321  
          + htextarea(text, id := "suggestAnswer", name := "text", class := "auto-expand",
322  
            style := "width: 300px")
323  
          + hhidden(inputID := input.id)
324  
          + hhidden(redirect := "")
325  
          + " " + hsubmit("Save answer")
326  
          + " [Optional rewrite type: " + hinputfield("rewriteType", style := "width: 100px") + " ]",
327  
          action := url,
328  
          onsubmit := js_setRedirect()));
329  
    }
330  
331  
    void allowSuggestingPattern(BEAObject input) {
332  
      if (input == null) ret;
333  
      S text = input.text();
334  
335  
      S url = mod.baseLink + "/savePattern";
336  
      appendHTML(
337  
        hpostform("Suggest a pattern (with angle bracket vars): "
338  
          + htextarea(text, name := "text", class := "auto-expand",
339  
            style := "width: 300px")
340  
          + hhidden(fromInput := conceptIDOrNull(input))
341  
          + hhidden(userTyped := true)
342  
          + hhidden(redirect := "")
343  
          + " " + hsubmit("Save pattern"),
344  
          action := url,
345  
          onsubmit := js_setRedirect()));
346  
    }
347  
348  
    void allowSuggestingSyntacticPattern(BEAObject input) {
349  
      if (input == null) ret;
350  
      S text = input.text();
351  
352  
      S url = mod.baseLink + "/saveSyntacticPattern";
353  
      appendHTML(
354  
        hpostform("Suggest a syntactic pattern (with * vars): "
355  
          + htextarea(text, name := "text", class := "auto-expand",
356  
            style := "width: 300px")
357  
          + hhidden(fromInput := conceptIDOrNull(input))
358  
          + hhidden(userTyped := true)
359  
          + hhidden(redirect := "")
360  
          + " " + hsubmit("Save syntactic pattern"),
361  
          action := url,
362  
          onsubmit := js_setRedirect()));
363  
    }
364  
365  
    BEA saveInput(S q) {
366  
      if (userAgentIsBot(beaMod().currentUserAgent())) null;
367  
      Pair<BEA, Bool> p = uniqCI2 BEA(type := "Input", text := q);
368  
      BEA input = p.a;
369  
      mod.saveUserAgent(input);
370  
      
371  
      if (p.b) {
372  
        csetIfUnset(input, createdBy := mod.user(mod.currentReq()));
373  
        appendHTML("Input saved");
374  
      }
375  
      ret input;
376  
    }  
377  
378  
    void runNonMatches {
379  
      if (nempty(nonMatches)) { appendHTML(hr()); callFAll(nonMatches); }
380  
    }
381  
382  
    void addNonMatch(Runnable r) { add(nonMatches, r); }
383  
384  
    void runIt {
385  
      if (liveMode) runLiveMode(); else run();
386  
      runNonMatches();
387  
    }
388  
  } // end of Algorithm
389  
    
390  
  class ReverseInput extends Algorithm {
391  
    run { appendText(reversed(q)); }
392  
    void runLiveMode { run(); }
393  
  }
394  
  
395  
  class TimeoutTest extends Algorithm {
396  
    run { sleepSeconds(120); }
397  
  }
398  
  
399  
  class RunPattern extends Algorithm {
400  
    run {
401  
      BEAObject pattern = mod.beaGet(parseFirstLong(q));
402  
      if (pattern == null) ret with appendText("Pattern not found");
403  
      appendText("Pattern: " + pattern);
404  
      for (BEAObject input : mod.beaList("Input")) {
405  
        S text = input.text();
406  
        SS mapping = matchInputWithPattern(input, pattern);
407  
        if (mapping == null)
408  
          addNonMatch(r {
409  
            appendText("Checking Input: " + input + " - No match");
410  
          });
411  
        else {
412  
          S result = "\n" + renderMappingAsText(mapping);
413  
          appendText("Checking Input: " + input + result);
414  
          allowStoringMatch(this, input, pattern, mapping);
415  
        }
416  
      }
417  
    }
418  
  }
419  
420  
  S renderMappingAsText(SS mapping) {
421  
    ret indent(formatDoubleArrowMap_horizontallyAligned(mapping));
422  
  }
423  
424  
  class FindRewrites extends Algorithm {
425  
    run {
426  
      // argument is ID of a match
427  
      BEAObject match = mod.beaGet(parseFirstLong(q));
428  
      if (match == null || !match.typeIs("Match")) ret with appendText("Match not found");
429  
      BEAObject pattern = cast cget pattern(match);
430  
      BEAObject input = cast cget input(match);
431  
      SS mapping = cast get mapping(match);
432  
      appendText("Match: " + match);
433  
      appendText("Input: " + input);
434  
      appendText("Pattern: " + pattern);
435  
      appendText("Mapping:\n"
436  
        + renderMappingAsText(mapping));
437  
        
438  
      appendRewrites(this, input, input.text(), pattern, match, mapping);
439  
    }
440  
  }
441  
  
442  
  // match and input can be null, pattern has to be set
443  
  LS appendRewrites(Algorithm algo, BEAObject input, S inputText, BEAObject pattern, BEAObject match, SS mapping) {
444  
    Cl<BEAObject> rewrites = mod.beaBackRefs(pattern, "Rewrite");
445  
    new LS texts;
446  
    for (BEAObject r : rewrites) {
447  
      S text = r.text();
448  
      S textWithVars = text;
449  
      if (pattern.typeIs("Syntactic pattern"))
450  
        textWithVars = starsToAngleBracketedNumbers(text);
451  
        
452  
      S text2 = replaceAngleBracketVars_curly(textWithVars, mapping);
453  
      algo.appendText(" Using pattern rewrite: " + text);
454  
      algo.appendTextBold(
455  
          "    " + inputText + "\n"
456  
        + " => " + text2);
457  
      texts.add(text2);
458  
459  
      // look for existing rewrite
460  
      BEAObject existing = match == null || input == null ?: conceptWhereIC BEAObject(
461  
        type := "Rewrite", +input, text := text2,
462  
          +match, patternRewrite := r, label := "good"
463  
      );
464  
      
465  
      if (existing != null)
466  
        algo.appendHTML("Rewrite exists: " + mod.beaLinkHTML(existing));
467  
      else if (match == null)
468  
        algo.appendText("[Can't save, no match]");
469  
      else if (input == null)
470  
        algo.appendText("[Can't save, no input object]");
471  
      else
472  
        algo.appendHTML(
473  
          hinlinepostform(
474  
            hhiddenMulti(
475  
              action := "create",
476  
              f_type := "Rewrite",
477  
              f_text := text2,
478  
              f_input := input.id, metaInfo_input := "concept",
479  
              f_match := match.id, metaInfo_match := "concept",
480  
              f_patternRewrite := r.id, metaInfo_patternRewrite := "concept",
481  
              f_label := "good")
482  
            + hbutton("Good rewrite"),
483  
            target := "_blank",
484  
            action := mod.crudLink(BEAObject)));
485  
    }
486  
    ret texts;
487  
  }
488  
  
489  
  class ProcessNewInput extends Algorithm {
490  
    run {
491  
      BEAObject input = handleInput(this, q = trim(q), false);
492  
493  
      for (BEAObject pattern : mod.beaListAny("Pattern", "Syntactic Pattern")) {
494  
        checkPattern(this, input, q, pattern);
495  
      }
496  
    }
497  
  }
498  
499  
  void checkPattern(Algorithm algo, BEA input, S q, BEA pattern) {
500  
    SS mapping = matchInputWithPattern(q, pattern);
501  
    if (mapping == null)
502  
      algo.addNonMatch(r {
503  
        algo.appendText("Checking Pattern: " + pattern + " - No match");
504  
      });
505  
    else {
506  
      S result = "\n" + renderMappingAsText(mapping);
507  
      algo.appendText("Checking Pattern: " + pattern + result);
508  
      if (input == null) {
509  
        //appendHTML("Click \"Save input\" first to store this match");
510  
      } else
511  
        allowStoringMatch(algo, input, pattern, mapping);
512  
        
513  
      appendRewrites(algo, input, q, pattern, null, mapping);
514  
    }
515  
  }
516  
  
517  
  class ProcessNewInput_v2 extends Algorithm {
518  
    run {
519  
      q = trim(q);
520  
      saveInput(q);
521  
      BEAObject input = handleInput(this, q, false);
522  
523  
      if (input != null) {
524  
        Cl<BEAObject> rewrites = mod.beaBackRefs(input, "Rewrite");
525  
        BEAObject rewrite = random(rewrites);
526  
        if (rewrite != null)
527  
          appendHTML("My answer: " + b(htmlEncode2(rewrite.text())) + " " + ahref(mod.beaShortURL(rewrite), "[source]"));
528  
      }
529  
530  
      allowSuggestingAnswer(input);
531  
      allowSuggestingPattern(input);
532  
      allowSuggestingSyntacticPattern(input);
533  
534  
      for (BEAObject pattern : syntacticPatternsSortedBySpecificityDesc()) {
535  
        continue if patternAlwaysMatches(pattern);
536  
        SS mapping = matchInputWithPattern(q, pattern);
537  
        if (mapping == null)
538  
          addNonMatch(r {
539  
            appendHTML("Checking Syntactic Pattern: " + mod.beaLinkHTML(pattern) + " - No match");
540  
          });
541  
        else {
542  
          S result = "Grouped as: " + replaceAngleBracketVars_curly(starsToAngleBracketedNumbers(pattern.text()), mapping) + "\n"
543  
            + renderMappingAsText(mapping);
544  
          appendHTML(hr());
545  
          appendHTML("Checking Syntactic Pattern: " + mod.beaLinkHTML(pattern));
546  
          appendText(result);
547  
          BEAObject match = null;
548  
          if (input == null) {
549  
            //appendHTML("Click \"Save input\" first to store this match");
550  
          } else
551  
            match = allowStoringMatch(this, input, pattern, mapping);
552  
            
553  
          MultiMap<S, BEAObject> subInputRewrites = ciMultiMap();
554  
          
555  
          for (S subInput : uniquifyCI(values(mapping)))
556  
            if (!eqic(subInput, q)) {
557  
              BEAObject subInputObj = handleInput(this, subInput, "Sub-Input", true);
558  
              
559  
              // find rewrites for sub-input
560  
              if (subInputObj != null) {
561  
                L<BEAObject> subRewrites = concatLists(
562  
                  conceptsWhereCI(BEAObject, type := "Rewrite", input := subInputObj),
563  
                  conceptsWhereCI(BEAObject, type := "Rewrite", isRewriteOf := subInputObj));
564  
                for (BEAObject r : subRewrites)
565  
                  appendHTML("&nbsp; Sub-Rewrite found: " + r);
566  
                subInputRewrites.putAll(subInput, subRewrites);
567  
              }
568  
            }
569  
          
570  
          // show all rewrites for the pattern  
571  
          appendRewrites(this, input, q, pattern, match, mapping);
572  
          
573  
          // apply some sub-rewrites randomly
574  
          SS rewrittenMapping = mapValues(mapping,
575  
            s -> {
576  
              BEAObject rewrite = random(subInputRewrites.get(s));
577  
              ret rewrite == null ? s : uncurly(rewrite.text());
578  
            });
579  
            
580  
          S randomRewrite = replaceAngleBracketVars_curly(starsToAngleBracketedNumbers(pattern.text()), rewrittenMapping);
581  
          if (neq(randomRewrite, q))
582  
            appendText("Random rewrite from sub-inputs: " + randomRewrite);
583  
        }
584  
      } // for pattern
585  
    }
586  
  }
587  
  
588  
  class ProcessNewInput_v3 extends Algorithm {
589  
    run {
590  
      q = trim(q);
591  
      saveInput(q);
592  
      BEAObject input = handleInput(this, q, false);
593  
594  
      new HTMLTabs tabs;
595  
596  
      {
597  
        new StringBuffer toTab;
598  
        Algorithm alg = new ProcessNewInput_v2;
599  
        alg.q = q;
600  
        alg.out = toTab;
601  
        alg.runIt();
602  
        tabs.add("Match input with patterns", toTab);
603  
      }
604  
      
605  
      {
606  
        new StringBuffer toTab;
607  
        Algorithm alg = new SyntacticPatternFromInput;
608  
        alg.q = q;
609  
        alg.out = toTab;
610  
        alg.runIt();
611  
        tabs.add("Make syntactic pattern", toTab);
612  
      }
613  
      
614  
      appendHTML(tabs.html());
615  
    }
616  
  }
617  
618  
  BEAObject allowStoringMatch(Algorithm algo, BEAObject input, BEAObject pattern, SS mapping) {
619  
    BEAObject match = conceptWhereCI(BEAObject, type := "Match",
620  
      +pattern, +input, +mapping);
621  
    if (match != null)
622  
      ret match with algo.appendHTML("Match exists: " + mod.beaLinkHTML(match));
623  
      
624  
    /*S url = appendParamsToURL(mod.baseLink + "/storeMatch", pattern := pattern.id, input := input.id);
625  
    algo.appendHTML(
626  
      hbuttonLink(appendParamsToURL(url, label := "good"), "Good match") + " "
627  
      + hbuttonLink(appendParamsToURL(url, label := "bad"), "Bad match"));*/
628  
629  
    algo.appendHTML(joinWithSpace(
630  
      storeMatchForm(input, pattern, "good"),
631  
      storeMatchForm(input, pattern, "bad")));
632  
      
633  
    null;
634  
  }
635  
636  
  S storeMatchForm(BEAObject input, BEAObject pattern, S label) {
637  
    ret hinlinepostform(
638  
      hhiddenMulti(
639  
        pattern := pattern.id,
640  
        input := input.id,
641  
        +label,
642  
        redirect := "")
643  
        + hbutton(firstToUpper(label) + " match"),
644  
      action := mod.baseLink + "/storeMatch",
645  
      onsubmit := js_redirectAutoScroll2());
646  
  }
647  
  
648  
  runnable class MakeSyntacticPatterns extends Algorithm {
649  
    for (BEAObject p : mod.beaList("Pattern")) {
650  
      appendText(p + " => " + makeSyntacticPattern(p));
651  
    }
652  
  }
653  
654  
  S syntacticPatternText(BEAObject p) {  
655  
    ret simpleSpacesTrim_javaTok(angleBracketVarsToStars(p.text()));
656  
  }
657  
  
658  
  // convert angle bracket var pattern to syntactic pattern
659  
  BEAObject makeSyntacticPattern(BEAObject p) {
660  
    if (p == null || !p.typeIs("Pattern") || empty(p.text())) null;
661  
    //print("makeSyntacticPattern", p);
662  
    S text = syntacticPatternText(p);
663  
    BEAObject sp = uniqCI BEAObject(type := "Syntactic Pattern", +text);
664  
    cset(p, syntacticPattern := sp);
665  
    ret sp;
666  
  }
667  
668  
  S processInputURL(S q) {
669  
    ret addParamsToURL(mod.baseLink + "/query", +q, algorithm := "process input");
670  
  }
671  
  
672  
  BEAObject handleInput(Algorithm algo, S q, S desc default "Input", bool showProcessLink) {
673  
    algo.appendHTML(hSingleRowTable_withSpacing(
674  
      "\*desc*/:",
675  
      tt(htmlEncode_nlToBr_withIndents(q)),
676  
      !showProcessLink ? "" : targetBlank_noFollow(processInputURL(q), "Process")));
677  
      
678  
    BEAObject input = mod.findInput(q);
679  
    algo.appendHTML(inputHTML(input, desc, q));
680  
    ret input;
681  
  }
682  
683  
  // Link to or allow to save input object
684  
  S inputHTML(BEAObject input, S desc default "Input", S q) {
685  
    ret input != null
686  
      ? "\*desc*/ exists: " + mod.beaLinkHTML(input)
687  
      : !mod.requestAuthed() && !mod.allowAnonymousInputUpload ? null : hinlinepostform(
688  
          hhiddenMulti(
689  
            text := q,
690  
            redirect := "")
691  
          + hbutton("Save \*desc*/"),
692  
          action := mod.baseLink + "/saveInput",
693  
          onsubmit := js_setRedirect());
694  
  }
695  
696  
  // Link to or allow to save syntactic pattern
697  
  S syntacticPatternLinkHTML(BEAObject obj, S text, BEAObject fromInput default null) {
698  
    S desc = "Syntactic pattern";
699  
    ret obj != null
700  
      ? mod.beaLinkHTML(obj)
701  
      : !mod.requestAuthed() ? null : hinlinepostform(
702  
          hhiddenMulti(
703  
            +text,
704  
            fromInput := conceptIDOrNull(fromInput),
705  
            redirect := "")
706  
          + hbutton("Save \*firstToLower(desc)*/"),
707  
          action := mod.baseLink + "/saveSyntacticPattern",
708  
          onsubmit := js_setRedirect());
709  
  }
710  
711  
  runnable class SyntacticPatternFromInput extends Algorithm {
712  
    //appendHTML(inputHTML(mod.findInput(q), q));
713  
    BEAObject input = handleInput(this, q, false);
714  
715  
    if (countTokens(q) > 10) ret with appendText("Input too long to extract syntactic patterns");
716  
    S q2 = dropPunctuation(q);
717  
    new L<Map> data;
718  
    for (S pat : sortedIC(gazelle_allSyntacticPatternsFromInput(q))) {
719  
      SS mapping = matchInputWithSyntacticPattern(q2, pat);
720  
      BEAObject obj = conceptWhereIC(BEAObject, type := "Syntactic Pattern", text := pat);
721  
722  
      /*appendHTML(htmlEncode2(pat) + " " + syntacticPatternLinkHTML(obj, pat)
723  
        + (empty(mapping) ? "" : 
724  
        hpre_htmlencode(indent(formatDoubleArrowMap_horizontallyAligned(mapping)))));*/
725  
726  
      Map row = litorderedmap(
727  
        "Syntactic Pattern" := htmlEncode2(pat),
728  
        "In database" := syntacticPatternLinkHTML(obj, pat, input));
729  
      for (S key, S val : mapping)
730  
        row.put("Argument " + key, htmlEncode2(val));
731  
      data.add(row);
732  
    }
733  
    appendHTML(htmlTable2_noHtmlEncode(data));
734  
  }
735  
736  
  class ApplyTextFunctions extends Algorithm {
737  
    run {
738  
      q = trim(q);
739  
      saveInput(q);
740  
      BEAObject input = handleInput(this, q, false);
741  
742  
      new LinkedHashSet<BEAObject> objectsMade;
743  
      
744  
      for (BEAObject f : mod.beaList("JavaX Standard Function")) pcall {
745  
        addIfNotNull(objectsMade, reactFunctionWithInput(this, f, input));
746  
      }
747  
      
748  
      appendHTML(h3("Results of function calls"));
749  
        
750  
      //appendHTML(ul_htmlencode(allToString(list(localConcepts, BEAObject))));
751  
752  
      /*HCRUD_Concepts<BEAObject> crudData = new(localConcepts, BEAObject);
753  
      HCRUD crud = new(null, crudData);
754  
      crud.unshownFields = litset("globalID", "mirrorPost");
755  
756  
      crudData.massageItemMapForList = (item, map) -> {
757  
        BEAObject o = item/BEAObject;
758  
        O value = o~.result;
759  
        map.put("result", HTML(javaValueToHTML(value, identityHashSet())));
760  
        //map.put("Save", HTML(hbutton()));
761  
      };*/
762  
763  
      HCRUD crud = mod.makeCRUD(BEAObject, mod.currentReq());
764  
      HCRUD_Concepts crudData = cast crud.data;
765  
      crudData.listConcepts_firstStep = () -> objectsMade;
766  
    
767  
      appendHTML(crud.renderTable(true));
768  
    }
769  
  }
770  
771  
  class FindPath extends Algorithm {
772  
    new BreadthFirstPathFinder_withLinkType<BEAObject, FieldIndicator> pathFinder;
773  
    BEAObject start, dest;
774  
      
775  
    run {
776  
      start = mod.beaGet(parseFirstLong(q));
777  
      dest = mod.beaGet(parseSecondLong(q));
778  
      if (start == null || dest == null)
779  
        ret with appendText("Please supply object IDs of start and end");
780  
781  
      appendHTML("Looking for path from " + mod.beaToHTML(start) + " to " + mod.beaToHTML(dest));
782  
783  
      pathFinder.getChildren = o -> cForwardAndBackRefsWithFieldIndicator BEAObject(o);
784  
      pathFinder.add(start);
785  
786  
      while (!pathFinder.nodeReached(dest) && pathFinder.step()) {}
787  
788  
      //appendHTML(hcomment(struct(pathFinder)));
789  
      LPair<BEAObject, FieldIndicator> path = pathFinder.examplePathWithTypes(start, dest);
790  
      
791  
      if (path == null)
792  
        appendText("No path found!");
793  
      else {
794  
        appendHTML(b("Path found!"));
795  
        appendHTML(ol(map(path, p -> {
796  
          S html = mod.beaHTML(p.a);
797  
          if (p.b == null) ret html;
798  
          S arrow = ifThenElse(p.b.forward, ">>", "<<");
799  
          ret html + " " + htmlEncode2(
800  
            joinNemptiesWithSpace(arrow, p.b.field, arrow));
801  
        })));
802  
      }
803  
    }
804  
  }
805  
806  
  class ExecuteTextQuery extends Algorithm {
807  
    run {
808  
      saveInput(q = trim(q));
809  
      appendHTML(h3("Result"));
810  
      appendHTML(htmlEncode2(strOrEmpty(executeTextQuery(q))));
811  
    }
812  
  }
813  
814  
  class InputSummary extends Algorithm {
815  
    run {
816  
      BEA mainInput = saveInput(q = trim(q));
817  
818  
      Cl<BEA> inputs = conceptsWhere BEAObject(type := "Input", text := q);
819  
      if (l(inputs) > 1)
820  
        appendHTML("Note: Input appears " + l(inputs) + " times in the database: "
821  
          + joinWithSpace(map(o -> mod.beaToHTML(o), inputs)));
822  
823  
      for (BEA input : inputs) {
824  
        if (input != mainInput) {
825  
          appendHTML(hr());
826  
          appendHTML("Input: " + input);
827  
        }
828  
829  
        // rewrites
830  
831  
        Cl<BEA> rewrites = mod.beaBackRefs(input, "Rewrite");
832  
833  
        if (empty(rewrites)) appendHTML(h3("No rewrites"));
834  
        else
835  
          for (int i, BEA r : unpair iterateWithIndex1(rewrites))
836  
            appendHTML("Rewrite " + i + ": " + ahref(mod.beaURL(r), tok_dropCurlyBrackets(r.text())));
837  
838  
        // matches
839  
840  
        //beaBackRefs("Match
841  
      }
842  
    }
843  
  }
844  
845  
  class ApplyPatternList extends Algorithm {
846  
    S additionalInputs() {
847  
      ret hselect("patternListID", mapToKey conceptID(mod.beaList("Pattern List")),
848  
        req.get("patternListID"));
849  
    }
850  
851  
    run {
852  
      BEAObject input = handleInput(this, q = trim(q), false);
853  
      
854  
      BEA patternList = mod.beaGet patternListID(req);
855  
      if (patternList == null) ret;
856  
      L<BEA> patterns = cast cget patterns(patternList);
857  
      appendHTML("Pattern list: " + mod.beaHTML(patternList));
858  
859  
      fOr (BEA pattern : patterns) {
860  
        appendText("Trying pattern " + pattern);
861  
        checkPattern(this, input, q, pattern);
862  
      }
863  
    }
864  
  }
865  
866  
  class ApplyAlgorithmObject extends Algorithm {
867  
    S additionalInputs() {
868  
      ret hselect("algorithmID", mapToKey conceptID(
869  
          concatLists(
870  
            wideningListCast Concept(list BEARegExpReplacement()),
871  
            wideningListCast Concept(conceptsWhereIC UserPost(type := "JavaX Code (HTML Bot)"))
872  
          )),
873  
        req.get("algorithmID"));
874  
    }
875  
876  
    void runLiveMode() {
877  
      //BEAObject input = handleInput(this, q = trim(q), false);
878  
879  
      Concept algo = getConcept(parseLongOpt(req.get("algorithmID")));
880  
      //appendText("Test test. Algorithm: " + algo);
881  
882  
      appendHTML("Algorithm object: " + htmlEncode2_nlToBr(str(algo)));
883  
      
884  
      if (algo cast UserPost) {
885  
        //O result = algObject.apply(q);
886  
        O result = mod.callHtmlBot_dropMadeByComment(algo.id, req.params());
887  
        appendText("Result: " + result);
888  
      } else if (algo cast BEARegExpReplacement) {
889  
        //appendHTML("Algorithm object: " + mod.beaHTML(algObject));
890  
        O result = algo.apply(q);
891  
        appendText("Result: " + result);
892  
      } else if (algo == null)
893  
        appendText("Algorithm object not found");
894  
      else
895  
        appendText("Unknown algorithm object type: " + _className(algo));
896  
    }
897  
  }
898  
899  
  class ApplyRegExpReplacement > Algorithm {
900  
    run {
901  
      BEARegExpReplacement regExpReplacement = cast mod.beaGet(q);
902  
      if (regExpReplacement == null) ret with appendText("Please enter reg exp replacement ID");
903  
904  
      appendHTML("Applying " + beaHTML(regExpReplacement));
905  
      
906  
      for (BEA input : sortedByConceptIDDesc(mod.beaList("Input"))) {
907  
        S text = input.text();
908  
        S replaced = regExpReplacement.apply(text);
909  
        if (neq(text, replaced)) {
910  
          appendHTML(hr());
911  
          appendText("   " + text + "\n=> " + replaced);
912  
          appendPossibleRewrite(this, input, replaced, litmap(
913  
            f_regularExpression := regExpReplacement.id,
914  
            metaInfo_regularExpression := "concept"));
915  
        }
916  
      }
917  
    }
918  
  }
919  
920  
  // prints instead of rendering to page
921  
  class BackEndAlgorithm > Algorithm {
922  
    S prefix() { ret shortClassName(this) + ": "; }
923  
    @Override void appendText(S s) { printWithIndent(prefix(), s); }
924  
    @Override void appendHTML(S s) { appendText(htmlDecode_dropTags(s)); }
925  
    @Override void addNonMatch(Runnable r) { r.run(); }
926  
  }
927  
928  
  class MatchInputWithAllPatternLists > Algorithm {
929  
    run {
930  
      BEAObject input = saveInput(q);
931  
      
932  
      for (BEA patternList : sortedByConceptIDDesc(beaList("Pattern List")))
933  
        reactInputWithPatternList(this, input, q, patternList, 1, 2);
934  
    }
935  
  }
936  
  
937  
  class RunTestCasesOnCodePost extends Algorithm {
938  
    S additionalInputs() {
939  
      MultiSet<S> ms = distinctCIFieldValuesOfConcepts_multiSet(BEAObject, "type");
940  
      LS types = filter(pairsA(multiSetToPairsByPopularity(ms)), 
941  
        type -> cic(type, "test case"));
942  
943  
      ret "Test case type: " + hselect_list("testCaseType", types, req.get("testCaseType"))
944  
        + " " + hselect("algorithmID", mapToKey conceptID(
945  
          conceptsWhereIC UserPost(type := "JavaX Code (HTML Bot)")),
946  
        req.get("algorithmID"));
947  
    }
948  
949  
    run {
950  
      //BEAObject input = handleInput(this, q = trim(q), false);
951  
952  
      S testCaseType = req.get("testCaseType");
953  
      Concept algo = getConcept(parseLongOpt(req.get("algorithmID")));
954  
      //appendText("Test test. Algorithm: " + algo);
955  
956  
      Cl<BEA> testCases = beaList(testCaseType);
957  
958  
      appendText(n2(testCases, "test case") + " found for type " + quote(testCaseType));
959  
      appendHTML("Algorithm object: " + htmlEncode2_nlToBr(str(algo)));
960  
961  
      if (!algo instanceof UserPost) ret;
962  
963  
      new Scorer scorer;
964  
965  
      for ping (BEA testCase : testCases) {
966  
        MapSO fields = toCIMap(objectToMap(testCase));
967  
        S input = str(getAny(fields, "input"));
968  
        S expected = str(getAny(fields, "output", "result"));
969  
        S result = str(mod.callHtmlBot_dropMadeByComment(algo.id, litmap(q := input)));
970  
        bool ok = eq(result, expected);
971  
        appendText((ok ? "OK" : "BAD") + ": Input: " + quote(input) + ", expected output: " + quote(expected)
972  
          + ", result: " + quote(result));
973  
        scorer.add(ok);
974  
      }
975  
976  
      appendText(str(scorer));
977  
    }
978  
  }
979  
980  
  // add algorithms here
981  
982  
  void reactInputWithPatternList(Algorithm algo, BEA input, S text, BEA patternList, int level, int recursionLevels) {
983  
    Pair<BEA, SS> match = matchInputWithPatternList(text, patternList);
984  
    algo.appendHTML(hr());
985  
    algo.appendHTML(joinNemptiesWithColon(
986  
      level == 1 ? beaHTML(patternList) : null,
987  
      stringIf(match == null, "No match")));
988  
      
989  
    if (match != null) {
990  
      BEA pattern = match.a;
991  
      SS mapping = match.b;
992  
      algo.appendHTML("Matched as " + beaHTML(pattern));
993  
      algo.appendText(renderMappingAsText(mapping));
994  
995  
      if (input != null) {
996  
        BEA matchObj = uniqCI(algo.localConcepts, BEA,
997  
          type := "Match",
998  
          +input,
999  
          +patternList,
1000  
          winningPattern := pattern,
1001  
          +mapping);
1002  
        algo.appendHTML("Match saved as: " + beaHTML(matchObj));
1003  
      }
1004  
1005  
      if (level < recursionLevels) {
1006  
        algo.appendHTML_raw("<ul>");
1007  
        for (S key, subInput : mapping) {
1008  
          if (!eqic(key, text)) {
1009  
            algo.appendHTML_raw("<li>");
1010  
            algo.appendText("Processing sub-Input: " + subInput);
1011  
            reactInputWithPatternList(algo, null, subInput, patternList, level+1, recursionLevels);
1012  
            algo.appendHTML_raw("</li>");
1013  
          }
1014  
        }
1015  
        algo.appendHTML_raw("</ul>");
1016  
      }
1017  
    }
1018  
  }
1019  
1020  
  int patternSpecificity(BEAObject pattern) {
1021  
    ret countWordsWithoutAngleBracketedAndStars(pattern.text());
1022  
  }
1023  
1024  
  L<BEAObject> syntacticPatternsSortedBySpecificityDesc() {
1025  
    ret sortedByCalculatedFieldDesc patternSpecificity(mod.beaList("Syntactic Pattern"));
1026  
  }
1027  
1028  
  O executeTextQuery(S s) {
1029  
    new Matches m;
1030  
    if (match3_withIntsAndIDs("all references in field <id> of object <int>", s, m)) {
1031  
      O value = cget(mod.beaGet($2), $1);
1032  
      ret value instanceof Cl ? instancesOf BEAObject((Cl) value)
1033  
        : value instanceof BEAObject ? ll((BEAObject) value)
1034  
        : ll();
1035  
    }
1036  
1037  
    ret new QueryNotUnderstood(s);
1038  
  }
1039  
1040  
  srecord QueryNotUnderstood(S s) {}
1041  
1042  
  S beaToHTML(BEA o) { ret mod.beaToHTML(o); }
1043  
  S beaHTML(BEA o) { ret mod.beaHTML(o); }
1044  
  S beaURL(BEA o) { ret mod.beaURL(o); }
1045  
1046  
  bool isSyntacticPattern(BEA pat) {
1047  
    ret pat != null && pat.typeIs("Syntactic pattern");
1048  
  }
1049  
1050  
  S patternTextWithAngleBracketVars(BEA pat) {
1051  
    S text = pat.text();
1052  
    ret isSyntacticPattern(pat) ? starsToAngleBracketedNumbers(text) : text;
1053  
  }
1054  
1055  
  bool isCommentOrFeedback(BEA o) {
1056  
    ret o != null && o.typeIsOneOf("Comment", "Useful", "Feedback");
1057  
  }
1058  
1059  
  S feedbackHTML(BEA o) {
1060  
    Cl<BEA> l = filter isCommentOrFeedback(mod.beaBackRefs(o));
1061  
    ret joinWithBR(map(l, c -> c.typeIs("Comment")
1062  
      ? ahref(beaURL(c), htmlEncode2(c.text()))
1063  
      : beaHTML(c)));
1064  
  }
1065  
1066  
  S bestInputURL(S text) {
1067  
    text = trim(text);
1068  
    BEA input = mod.findInput(text);
1069  
    ret input != null ? beaURL(input) : processInputURL(text);
1070  
  }
1071  
1072  
  // also shaded
1073  
  S bestInputHTML(S text) {
1074  
    if (empty(text)) ret "";
1075  
    ret ahref(bestInputURL(text), span(htmlEncode2(text),
1076  
      style := "background-color: #ccc"));
1077  
  }
1078  
1079  
  S performRewrite(BEA rewrite, SS mapping) {
1080  
    S rewriteText = starsToAngleBracketedNumbers(rewrite.text());
1081  
    ret replaceAngleBracketVars(rewriteText, mapping);
1082  
  }
1083  
1084  
  PairS exampleForPatternRewrite(BEA pattern, BEA rewrite) {
1085  
    S patText = patternTextWithAngleBracketVars(pattern);
1086  
    Set<S> vars = collectAngleBracketVars(patText);
1087  
    SS mapping = mapToValues_ciMap(vars, var -> "$" + var);
1088  
1089  
    ret pair(replaceAngleBracketVars(patText, mapping),
1090  
      performRewrite(rewrite, mapping));
1091  
  }
1092  
1093  
  /* if there is a regular expression
1094  
   * and an input
1095  
   * and the regular expression matches the input
1096  
   * generate a sub-input with the matched part
1097  
   */
1098  
  record RegExpToPossibleSubInputs(BEA input, BEA regExp) extends Algorithm {
1099  
    run {
1100  
      S text = input.text();
1101  
      S pat = regExp.text();
1102  
      for (IntRange r : regexpFindRangesIC(pat, text))
1103  
        appendHTML(beaHTML(csetAndReturn(uniq(localConcepts, BEA,
1104  
          type := "Possible Sub-Input",
1105  
          +input,
1106  
          characterRange := r,
1107  
          text := substring(text, r)),
1108  
          +regExp,
1109  
          byAlgorithm := shortName(this))));
1110  
    }
1111  
  }
1112  
1113  
  void appendPossibleRewrite(Algorithm algo, BEA input, S text, Map moreInfo default null) {
1114  
    // look for existing rewrite
1115  
    BEAObject existing = input == null ?: conceptWhereIC BEAObject(
1116  
      type := "Rewrite", +input, +text,
1117  
      label := "good"
1118  
    );
1119  
      
1120  
    if (existing != null)
1121  
      algo.appendHTML("Rewrite exists: " + mod.beaLinkHTML(existing));
1122  
    else if (input != null)
1123  
      algo.appendHTML(
1124  
        joinWithSpace(map(ll("good", "bad"), label ->
1125  
          hinlinepostform(
1126  
            hhiddenMulti(
1127  
              action := "create",
1128  
              f_type := "Rewrite",
1129  
              f_text := text,
1130  
              f_input := input.id, metaInfo_input := "concept",
1131  
              f_label := label,
1132  
              redirectAfterSave := ""/*algo.req.uriWithParams()*/)
1133  
            + hhiddenMulti(moreInfo)
1134  
            + hbutton(firstToUpper(label) + " rewrite",
1135  
              onclick := js_redirectAutoScroll2()),
1136  
            action := mod.crudLink(BEA)))));
1137  
  }
1138  
1139  
  BEA reactFunctionWithInput(Algorithm algo, BEA f, BEA input) {
1140  
    S fName = getString name(f);
1141  
    if (!isIdentifier(fName)) null;
1142  
    if (!isSafeStandardFunction(fName))
1143  
      ret null with algo?.addNonMatch(r { algo.appendText("Function " + fName + " not safe"); });
1144  
1145  
    BEAObject o = cnew(algo.localConcepts, BEAObject,
1146  
      type := "Function Result",
1147  
      function := f,
1148  
      functionCalled := fName,
1149  
      +input,
1150  
      calculating := true);
1151  
    print("Function result: " + o);
1152  
1153  
    try {
1154  
      O holder = getStandardFunctionHolder(fName);
1155  
      O result = evalWithTimeoutOrFail(10.0, () -> call(holder, fName, input.text()));
1156  
1157  
      // convert string collections to list
1158  
      if (!result instanceof L && isStringCollection(result)) result = asList((Cl) result);
1159  
1160  
      if (result == null)
1161  
        cset(o, resultType := "null");
1162  
      else if (result instanceof S)
1163  
        cset(o, resultType := "string", +result);
1164  
      else if (isStringList(result))
1165  
        cset(o, resultType := "list of strings", +result);
1166  
      else
1167  
        cset(o, result := "other" + appendRoundBracketed(className(result)),
1168  
          result := shorten(1000, str(result)));
1169  
    } catch e {
1170  
      cset(o, resultType := "error", error := getStackTrace(e));
1171  
    }
1172  
    cset(o, calculating := null);
1173  
    ret o;
1174  
  }
1175  
1176  
  BEA convertSyntacticToSemanticMatch(BEA match, BEA semanticPattern) {
1177  
    BEA syntacticPattern = beaGet pattern(match);
1178  
    BEA input = beaGet input(match);
1179  
    S pat2 = syntacticPattern.text();
1180  
    S pat1 = semanticPattern.text();
1181  
    new LS vars;
1182  
    S pat2b = angleBracketVarsToStars(pat1, vars);
1183  
    S warning = eq(pat2, pat2b) ? null
1184  
      : "Patterns don't match: " + quote(pat2) + " / " + quote(pat2b);
1185  
    SS mapping = cast cget mapping(match);
1186  
    SS mapping2 = mapKeys(mapping, key -> or(_get(vars, parseInt(key)-1), key));
1187  
    mapping2 = putKeysFirst(vars, mapping2); // reorder variables in order of appearance in input
1188  
    BEA match2 = uniqCI BEA(
1189  
      type := "Match",
1190  
      +input,
1191  
      pattern := semanticPattern,
1192  
      fromSyntacticMatch := match);
1193  
    cset(match2,
1194  
      mapping := mapping2);
1195  
    ret match2;  
1196  
  }
1197  
1198  
  Cl<BEA> convertSyntacticToSemanticMatches(BEA match) {
1199  
    new L<BEA> out;
1200  
    BEA syntacticPattern = beaGet pattern(match);
1201  
    for (BEA semanticPattern : mod.beaList("Pattern", +syntacticPattern)) pcall {
1202  
      out.add(convertSyntacticToSemanticMatch(match, semanticPattern));
1203  
    }
1204  
    ret out;
1205  
  }
1206  
1207  
  Cl<BEA> convertSyntacticToSemanticMatchesForWholePattern(BEA pattern) {
1208  
    if (pattern.typeIs("Syntactic Pattern"))
1209  
      // This is huge - uses all semantic patterns
1210  
      ret concatMap_lists convertSyntacticToSemanticMatches(mod.beaList("Match", +pattern));
1211  
    else {
1212  
      new L<BEA> out;
1213  
      BEA syntacticPattern = beaGet syntacticPattern(pattern);
1214  
      if (syntacticPattern != null)
1215  
        for (BEA match : mod.beaList("Match", pattern := syntacticPattern))
1216  
          out.add(convertSyntacticToSemanticMatch(match, pattern));
1217  
      ret out;
1218  
    }
1219  
      
1220  
  }
1221  
1222  
  BEA mapMethodLike beaGet(S field, BEA o) { ret mod.beaGet(field, o); }
1223  
  Cl<BEA> beaList(S type, O... params) { ret mod.beaList(type, params); }
1224  
1225  
  int simpleObjectScore(BEA o) {
1226  
    int score = 0;
1227  
    if (eqic_gen(o~.label, "good")) ++score;
1228  
    else if (eqic_gen(o~.label, "bad")) --score;
1229  
    Cl<BEA> l = findBackRefsWithField BEA(object := o);
1230  
    score += countWhereCI(l, type := "Useful");
1231  
    score -= countWhereCI(l, type := "Bad");
1232  
    ret score;
1233  
  }
1234  
1235  
  L<BEA> sortedBySimpleObjectScore(int minScore, Cl<BEA> l) {
1236  
    ret sortedByCalculatedFieldDesc simpleObjectScore(filter(l, o -> simpleObjectScore(o) >= minScore));
1237  
  }
1238  
1239  
  BEA createPatternListFromUsefulSyntacticPatterns() {
1240  
    L<BEA> patterns = sortedBySimpleObjectScore(0, beaList("Syntactic Pattern"));
1241  
    ret mod.autoMigrateToCustomClass(uniqCI BEA(type := "Pattern List",
1242  
      byFunction := "createPatternListFromUsefulSyntacticPatterns",
1243  
      +patterns));
1244  
  }
1245  
1246  
  Map<S, IF0<Algorithm>> algorithms() {  
1247  
    ret litorderedmap(
1248  
      "Process new input v3" := (IF0) () -> new ProcessNewInput_v3,
1249  
      "Process new input v2" := (IF0) () -> new ProcessNewInput_v2,
1250  
      "Process new input" := (IF0) () -> new ProcessNewInput,
1251  
      "Run pattern" := (IF0) () -> new RunPattern,
1252  
      "Find rewrites for match" := (IF0) () -> new FindRewrites,
1253  
      "Reverse input (test algorithm)" := (IF0) () -> new ReverseInput,
1254  
      "Timeout test" := (IF0) () -> new TimeoutTest,
1255  
      "Syntactic pattern from input" := (IF0) () -> new SyntacticPatternFromInput,
1256  
      "Apply all text functions" := (IF0) () -> new ApplyTextFunctions,
1257  
      "Find Path" := (IF0) () -> new FindPath,
1258  
      "Execute text query" := (IF0) () -> new ExecuteTextQuery,
1259  
      "Make syntactic patterns for all patterns in DB" := (IF0) () -> new MakeSyntacticPatterns,
1260  
      "Input summary" := (IF0) () -> new InputSummary,
1261  
      "Apply pattern list" := (IF0) () -> new ApplyPatternList,
1262  
      "Apply regular expression replacement to all inputs" := (IF0) () -> new ApplyRegExpReplacement,
1263  
      "Match input with all pattern lists" := (IF0) () -> new MatchInputWithAllPatternLists,
1264  
      "Apply algorithm object" := (IF0) () -> new ApplyAlgorithmObject,
1265  
      "Run test cases on code post" := (IF0) () -> new RunTestCasesOnCodePost,
1266  
      
1267  
      // add algorithms here
1268  
    );
1269  
  }
1270  
  
1271  
  void putAlgorithmsInDatabase {
1272  
    for (S name : keys(algorithms()))
1273  
      uniq BEA(type := "Classic Query Algorithm", +name);
1274  
  }
1275  
1276  
} // end of Calculations

download  show line numbers  debug dex  old transpilations   

Travelled to 6 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030833
Snippet name: BEACalculations [Include]
Eternal ID of this version: #1030833/449
Text MD5: 0af89ca0adca659c085100c1cd05d4c4
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-08-11 01:36:38
Source code size: 46018 bytes / 1276 lines
Pitched / IR pitched: No / No
Views / Downloads: 350 / 4035
Version history: 448 change(s)
Referenced in: [show references]