sclass BEACalculations { GazelleBEA mod; *(GazelleBEA *mod) {} void reactAllInputsWithSomePatterns() { for (BEAObject input : mod.beaObjectsOfType("input")) { new ReactInputWithSomePatterns r; r.input = input; r.ccOut = db_mainConcepts(); r.max = 10; r.start(); stepAllWithTimeout(10.0, r); } } class ReactInputWithSomePatterns implements Steppable { BEAObject input; Concepts ccOut; int max = 3, n; Iterator patterns; void start { n = countConceptsWhereIC(ccOut, BEAObject, +input, type := "match"); patterns = iterator(sortByConceptID(conceptsWhereIC BEAObject(type := "Pattern"))); } public bool step() { if (n >= max) false; if (!patterns.hasNext()) false; if (reactInputWithPattern(input, patterns.next(), ccOut) != null) ++n; true; } } SS matchInputWithPattern(BEAObject input, BEAObject pattern) { S text = getString text(input); ret matchInputWithPattern(text, pattern); } SS matchInputWithPattern(S text, BEAObject pattern) { S pat = getString text(pattern); SS mapping = flexMatchAngleBracketVarsIC_honorPunctuation_first(pat, text); if (mapping != null) ret mapping; ret flexMatchAngleBracketVarsIC_first(pat, text); } BEAObject reactInputWithPattern(BEAObject input, BEAObject pattern, Concepts ccOut default db_mainConcepts()) { if (input == null || pattern == null) null; SS mapping = matchInputWithPattern(input, pattern); //printVars_str("reactInputWithPattern", +input, +pattern, +mapping); if (mapping == null) null; ret cnew(ccOut, BEAObject, type := "Match", +input, +pattern, +mapping); } O serveAnalyzeInput(GazelleBEA.Req req) { new Concepts ccOut; BEAObject input = getConcept BEAObject(parseLong(req.get("id"))); if (input == null) input = cnew(ccOut, BEAObject, type := "Input", text := req.get("q")); S text = getString text(input); new ReactInputWithSomePatterns r; r.input = input; r.ccOut = ccOut; r.max = 1000; r.start(); stepAllWithTimeout(10.0, r); L matches = conceptsWhereIC(ccOut, BEAObject, type := "Match"); ret h1_title("Analyze Input") + p("Input: " + b(htmlEncode(text))) + p(empty(matches) ? "No matches" : "Matches") + ul_htmlEncode(matches); } O serveQueryPage(GazelleBEA.Req req) { S q = req.get("q"), algorithm = req.get("algorithm"); bool dontRun = eq(req.get("dontRun"), "1"); Map> algorithms = litorderedmap( "Reverse input (test algorithm)" := (IF0) () -> new ReverseInput, "Timeout test" := (IF0) () -> new TimeoutTest, "Run pattern" := (IF0) () -> new RunPattern, "Find rewrites for match" := (IF0) () -> new FindRewrites, "Process new input" := (IF0) () -> new ProcessNewInput, ); S output = empty(algorithm) || dontRun ? null : doAlgorithm(algorithms, algorithm, q); ret hcenter3( htitle_h2("Gazelle BEA Query") + hform(p("Query: " + htextfield(+q, style := "width: 300px; text-align: center") + "   Algorithm: " + hselect_list(keys(algorithms), algorithm, name := "algorithm") + "   " + hbutton("Go")))) + (output == null ? "" : h3(algorithm) + output); } S doAlgorithm(Map> algorithms, S algorithm, S q) { StringBufferWithMaxSize out = new(100000); IF0 algo = lookupPossiblyCI(algorithms, algorithm); if (algo == null) out.append("Algorithm not found: " + algorithm); else { if (isB(evalWithTimeout(10.0, r { Algorithm alg = algo!; alg.q = q; alg.out = out; alg.run(); }))) out.append("\n[algorithm timeout]"); } ret str(out); } abstract sclass Algorithm implements Runnable { S q; Appendable out; void appendHTML(S html) ctex { out.append(html).append("\n"); } void appendText(S text) ctex { out.append(hpre_htmlencode(rtrim(text))); } void appendTextBold(S text) ctex { out.append(b(hpre_htmlencode(rtrim(text)))); } } class ReverseInput extends Algorithm { run { appendText(reversed(q)); } } class TimeoutTest extends Algorithm { run { sleepSeconds(120); } } class RunPattern extends Algorithm { new L nonMatches; run { BEAObject pattern = mod.beaGet(parseFirstLong(q)); if (pattern == null) ret with appendText("Pattern not found"); appendText("Pattern: " + pattern); for (BEAObject input : mod.beaList("Input")) { S text = input.text(); SS mapping = matchInputWithPattern(input, pattern); if (mapping == null) nonMatches.add(r { appendText("Checking Input: " + input + " - No match"); }); else { S result = "\n" + indent(formatDoubleArrowMap_horizontallyAligned(mapping)); appendText("Checking Input: " + input + result); allowStoringMatch(this, input, pattern); } } callFAll(nonMatches); } } class FindRewrites extends Algorithm { run { // argument is ID of a match BEAObject match = mod.beaGet(parseFirstLong(q)); if (match == null || !match.typeIs("Match")) ret with appendText("Match not found"); BEAObject pattern = cast cget pattern(match); BEAObject input = cast cget input(match); SS mapping = cast get mapping(match); appendText("Match: " + match); appendText("Input: " + input); appendText("Pattern: " + pattern); appendText("Mapping:\n" + indent(formatDoubleArrowMap_horizontallyAligned(mapping))); Cl rewrites = mod.findBEABackRefs(pattern, "Rewrite"); for (BEAObject r : rewrites) { S text = r.text(); S text2 = replaceAngleBracketVars(text, mapValues curly(mapping)); appendText(" Using pattern rewrite: " + text); appendTextBold( " " + input.text() + "\n" + " => " + text2); // look for existing rewrite BEAObject existing = conceptWhereIC BEAObject( type := "Rewrite", +input, text := text2, +match, patternRewrite := r, label := "good" ); if (existing != null) appendHTML("Rewrite exists: " + mod.beaLinkHTML(existing)); else appendHTML( hinlinepostform( hhiddenMulti( action := "create", f_type := "Rewrite", f_text := text2, f_input := input.id, metaInfo_input := "concept", f_match := match.id, metaInfo_match := "concept", f_patternRewrite := r.id, metaInfo_patternRewrite := "concept", f_label := "good") + hbutton("Good rewrite"), target := "_blank", action := mod.crudLink(BEAObject))); } } } class ProcessNewInput extends Algorithm { new L nonMatches; run { q = trim(q); appendText("Input: " + q); BEAObject input = conceptWhereIC(BEAObject, type := "Input", text := q); appendHTML(input != null ? "Input exists: " + mod.beaLinkHTML(input) : hinlinepostform( hhiddenMulti( action := "create", f_type := "Input", f_text := q) + hbutton("Save input"), target := "_blank", action := mod.crudLink(BEAObject))); for (BEAObject pattern : mod.beaList("Pattern")) { SS mapping = matchInputWithPattern(q, pattern); if (mapping == null) nonMatches.add(r { appendText("Checking Pattern: " + pattern + " - No match"); }); else { S result = "\n" + indent(formatDoubleArrowMap_horizontallyAligned(mapping)); appendText("Checking Pattern: " + pattern + result); /*S url = appendParamsToURL(mod.baseLink + "/storeMatch", pattern := pattern.id, input := input.id); appendHTML( hbuttonLink(appendParamsToURL(url, label := "good"), "Good match") + " " + hbuttonLink(appendParamsToURL(url, label := "bad"), "Bad match"));*/ } } callFAll(nonMatches); } } void allowStoringMatch(Algorithm algo, BEAObject input, BEAObject pattern) { S url = appendParamsToURL(mod.baseLink + "/storeMatch", pattern := pattern.id, input := input.id); algo.appendHTML( hbuttonLink(appendParamsToURL(url, label := "good"), "Good match") + " " + hbuttonLink(appendParamsToURL(url, label := "bad"), "Bad match")); } } // end of Calculations