From fded62869e11487d2ca0b20e0cc09ccd5ad5c898 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Tue, 8 Feb 2022 17:36:12 -0500 Subject: [PATCH 01/12] Flag outputs probabilities in charm --- harmony_model_checker/charm/charm.c | 46 +++++++++++++++++++++++++++++ harmony_model_checker/charm/graph.h | 3 ++ 2 files changed, 49 insertions(+) diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 6bbb4756..93e3dd66 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -237,6 +237,7 @@ static bool onestep( int as_instrcnt = 0; bool rollback = false, failure = false, stopped = false; bool terminated = false; + int choice_size = 1; // Number of choices to make. It is 1 for (;;) { int pc = step->ctx->pc; @@ -376,6 +377,7 @@ static bool onestep( } else { choosing = true; + choice_size = size; break; } } @@ -475,6 +477,10 @@ static bool onestep( edge->ai = step->ai; edge->log = step->log; edge->nlog = step->nlog; + // Assume uniform distribution for now + edge->probability_numerator = 1; + // TODO: Is this right? + edge->probability_denominator = choice_size; // See if this state has been computed before struct keynode *k = dict_find_lock(w->visited, &w->allocator, @@ -490,6 +496,7 @@ static bool onestep( next->before = ctx; next->after = after; next->choice = choice_copy; + next->choice_size = choice_size; next->interrupt = interrupt; } } @@ -503,6 +510,7 @@ static bool onestep( next->after = after; next->len = node->len + weight; next->steps = node->steps + instrcnt; + next->choice_size = choice_size; *w->last = next; w->last = &next->next; k->value = next; @@ -1776,6 +1784,7 @@ static void usage(char *prog){ int main(int argc, char **argv){ bool cflag = false; + bool probabilistic = false; int i, maxtime = 300000000 /* about 10 years */; char *outfile = NULL, *dfafile = NULL; for (i = 1; i < argc; i++) { @@ -1802,6 +1811,9 @@ int main(int argc, char **argv){ case 'x': printf("Charm model checker working\n"); return 0; + case 'p': + probabilistic = true; + break; default: usage(argv[0]); } @@ -1925,6 +1937,7 @@ int main(int argc, char **argv){ struct node *node = node_alloc(NULL); node->state = *state; node->after = ictx; + node->choice_size = 1; graph_add(&global->graph, node); void **p = dict_insert(visited, NULL, state, sizeof(*state)); assert(*p == NULL); @@ -2216,6 +2229,38 @@ int main(int argc, char **argv){ if (no_issues) { fprintf(out, " \"issue\": \"No issues\",\n"); + if (probabilistic) { + fprintf(out, " \"probabilities\": [\n"); + + bool first = true; + for (int i = 0; i < global->graph.size; i++) { + struct node *node = global->graph.nodes[i]; + assert(node->id == i); + + for (struct edge *edge = node->fwd; edge != NULL; edge = edge->fwdnext) { + if (first) { + first = false; + } else { + fprintf(out, ",\n"); + } + + fprintf( + out, + " {\"from\": %d, \"to\": %d, \"probability\": {\"numerator\": %d, \"denominator\": %d}}", + i, + edge->dst->id, + edge->probability_numerator, + edge->probability_denominator + ); + } + } + + fprintf(out, "\n"); + fprintf(out, " ],\n"); + } + + + // We delay destutter since we need the full graph for probabilities destutter1(&global->graph); // Output the symbols; @@ -2226,6 +2271,7 @@ int main(int argc, char **argv){ fprintf(out, "\n"); fprintf(out, " },\n"); + fprintf(out, " \"nodes\": [\n"); bool first = true; for (unsigned int i = 0; i < global->graph.size; i++) { diff --git a/harmony_model_checker/charm/graph.h b/harmony_model_checker/charm/graph.h index 09c3851a..bc51aaa3 100644 --- a/harmony_model_checker/charm/graph.h +++ b/harmony_model_checker/charm/graph.h @@ -35,6 +35,8 @@ struct edge { struct access_info *ai; // to detect data races hvalue_t *log; // print history unsigned int nlog; // size of print history + int probability_numerator; // Probability to node as rational number + int probability_denominator; }; enum fail_type { @@ -63,6 +65,7 @@ struct node { hvalue_t before; // context before state change hvalue_t after; // context after state change (current context) hvalue_t choice; // choice made if any + int choice_size; // Helper to get size of choice bool interrupt; // set if gotten here by interrupt bool final; // only eternal threads left From 85db876cfe826f1dac7a7c694c6e0c5c789c1f49 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Tue, 8 Feb 2022 20:36:05 -0500 Subject: [PATCH 02/12] primitive version of probabilistic model checking implemented, saves to a hardcoded csv file --- harmony_model_checker/charm/charm.c | 1 + harmony_model_checker/harmony/brief.py | 5 +- .../harmony/probabilities.py | 53 +++++++++++++++++++ harmony_model_checker/main.py | 15 ++++-- requirements.txt | 1 + 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 harmony_model_checker/harmony/probabilities.py diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 93e3dd66..3f5f9619 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -2257,6 +2257,7 @@ int main(int argc, char **argv){ fprintf(out, "\n"); fprintf(out, " ],\n"); + fprintf(out, " \"total_states\": %d,\n", global->graph.size); } diff --git a/harmony_model_checker/harmony/brief.py b/harmony_model_checker/harmony/brief.py index 93d8cf07..fc2b16de 100644 --- a/harmony_model_checker/harmony/brief.py +++ b/harmony_model_checker/harmony/brief.py @@ -1,6 +1,8 @@ import json +import numpy from harmony_model_checker.harmony.behavior import behavior_parse +from harmony_model_checker.harmony.probabilities import find_probabilities def brief_kv(js): @@ -129,13 +131,14 @@ def print_macrostep(self, mas): self.failure = self.lastmis["failure"] self.interrupted = "interrupt" in self.lastmis and self.lastmis["interrupt"] == "True" - def run(self, outputfiles, behavior): + def run(self, outputfiles, behavior, probability_states): with open(outputfiles["hco"], encoding='utf-8') as f: print("Phase 5: loading", outputfiles["hco"]) top = json.load(f) assert isinstance(top, dict) if top["issue"] == "No issues": behavior_parse(top, True, outputfiles, behavior) + find_probabilities(top, probability_states, outputfiles) return True # print("Issue:", top["issue"]) diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py new file mode 100644 index 00000000..0435730e --- /dev/null +++ b/harmony_model_checker/harmony/probabilities.py @@ -0,0 +1,53 @@ +from collections import defaultdict +import numpy as np + +# TODO: This is just a simple port of charmpp. We probably want extended +# functionality here. +def find_probabilities(top, states, outputfiles): + transitions = defaultdict(list) + total_states = top['total_states'] + matrix = np.zeros((total_states, total_states)) + for p in top['probabilities']: + assert p['probability']['denominator'] != 0 + assert p['probability']['numerator'] != 0 + matrix[p['from']][p['to']] = p['probability']['numerator'] / p['probability']['denominator'] + transitions[p['from']].append(p['to']) + + states = set(int(s.strip()) for s in states.split(",")) + + reachable_states = [] + list_b = [] + for i in range(total_states): + if i in states: + continue + if is_reachable(i, transitions, states): + reachable_states.append(i) + list_b.append(np.sum(matrix[i][list(states)])) + + reachable_states = np.array(reachable_states) + matrix_a = np.identity(len(reachable_states)) - matrix[np.ix_(reachable_states, reachable_states)] + probabilities = np.linalg.solve(matrix_a, list_b) + + if outputfiles['hpo'] is not None: + np.savetxt(outputfiles['hpo'], np.stack((reachable_states, probabilities), axis=1), delimiter=",") + + +""" +Try to reach states in `goal` from state +""" +def is_reachable(state, transitions, goals): + # TODO: There might be more efficient ways to search this, I just ported + # this since this was in the original implementation + visited = set() + + def search(s): + if s in goals: + return True + if s in visited: + return False + for i in transitions[s]: + if (search(i)): + return True + return False + + return search(state) diff --git a/harmony_model_checker/main.py b/harmony_model_checker/main.py index b2485001..7cde0e2a 100644 --- a/harmony_model_checker/main.py +++ b/harmony_model_checker/main.py @@ -40,7 +40,7 @@ args.add_argument("-v", "--version", action="store_true", help="print version number") args.add_argument("-o", action='append', type=pathlib.Path, - help="specify output file (.hvm, .hco, .hfa, .htm. .tla, .png, .gv)") + help="specify output file (.hvm, .hco, .hfa, .htm. .tla, .png, .gv, .hpo)") args.add_argument("-j", action="store_true", help="list machine code in JSON format") args.add_argument("--noweb", action="store_true", default=False, @@ -51,6 +51,8 @@ help="get or set configuration value. " "Use --config to get the value of a setting. " "Use --config to set the value of a setting") +args.add_argument("--probabilistic", type=str, + help="use probabilistic model checking") # Internal flags args.add_argument("--cf", action="append", type=str, help=argparse.SUPPRESS) @@ -96,6 +98,8 @@ def handle_hvm(ns, output_files, parse_code_only, code, scope): charm_options = ns.cf or [] if ns.B: charm_options.append("-B" + ns.B) + if ns.probabilistic: + charm_options.append("-p") # see if there is a configuration file if code is not None: @@ -129,13 +133,17 @@ def handle_hco(ns, output_files): suppress_output = ns.suppress behavior = None + # TODO: These probably should be refactored somewhere else + probability_states = None if ns.B: behavior = ns.B + if ns.probabilistic: + probability_states = ns.probabilistic disable_browser = settings.values.disable_web or ns.noweb b = Brief() - b.run(output_files, behavior) + b.run(output_files, behavior, probabilistic) gh = GenHTML() gh.run(output_files) if not suppress_output: @@ -198,7 +206,8 @@ def main(): "hvm": None, "png": None, "tla": None, - "gv": None + "gv": None, + "hpo": None, } for p in (ns.o or []): # The suffix includes the dot if it exists. diff --git a/requirements.txt b/requirements.txt index 5af3be68..18c45f5e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ automata-lib==5.0.0 pydot==1.4.2 requests==2.27.1 twine==3.7.1 +numpy==1.22.0 From 07c4a627b9742ceede15d94ec5b9e7a247ec63d8 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Mon, 21 Feb 2022 13:02:02 -0500 Subject: [PATCH 03/12] fixed infinite recursion call --- harmony_model_checker/harmony/probabilities.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py index 0435730e..82fb3040 100644 --- a/harmony_model_checker/harmony/probabilities.py +++ b/harmony_model_checker/harmony/probabilities.py @@ -12,6 +12,7 @@ def find_probabilities(top, states, outputfiles): assert p['probability']['numerator'] != 0 matrix[p['from']][p['to']] = p['probability']['numerator'] / p['probability']['denominator'] transitions[p['from']].append(p['to']) + print(transitions) states = set(int(s.strip()) for s in states.split(",")) @@ -41,10 +42,12 @@ def is_reachable(state, transitions, goals): visited = set() def search(s): + print(s) if s in goals: return True if s in visited: return False + visited.add(s) for i in transitions[s]: if (search(i)): return True From f7e49f6b57f023acb18908a2c37178d5cb0b3e55 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Mon, 14 Mar 2022 09:00:56 -0400 Subject: [PATCH 04/12] parse for hyper assertws --- Harmony.g4 | 6 + .../harmony/probabilities.py | 6 +- harmony_model_checker/parser/HarmonyLexer.py | 754 ++++----- harmony_model_checker/parser/HarmonyParser.py | 1388 +++++++++-------- .../parser/HarmonyVisitor.py | 10 + .../parser/antlr_rule_visitor.py | 11 + 6 files changed, 1169 insertions(+), 1006 deletions(-) diff --git a/Harmony.g4 b/Harmony.g4 index 487240a7..0638fcc9 100644 --- a/Harmony.g4 +++ b/Harmony.g4 @@ -220,6 +220,10 @@ else_block: ELSE COLON block; if_block: IF expr COLON block elif_block* else_block?; +// TODO: atLabel is duplicated. Is this a problem? +hyper_condition: 'atLabel' NAME; +hyperassert_stmt: HYPER OPEN_PAREN hyper_condition CLOSE_PAREN comp_op expr; + block_stmts: stmt+; block @@ -270,6 +274,7 @@ stmt: (((label? | COLON) ( | one_line_stmt | compound_stmt | import_stmt + | hyperassert_stmt )) | ((label | COLON) normal_block) ); @@ -325,6 +330,7 @@ NONE : 'None'; ATOMICALLY: 'atomically'; BOOL : 'False' | 'True'; ETERNAL: 'eternal'; +HYPER : 'hyper_assert'; // STRING : '"' .*? '"' | '\'' .*? '\''; INT : [0-9]+ | 'inf'; diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py index 82fb3040..e95210a5 100644 --- a/harmony_model_checker/harmony/probabilities.py +++ b/harmony_model_checker/harmony/probabilities.py @@ -4,6 +4,9 @@ # TODO: This is just a simple port of charmpp. We probably want extended # functionality here. def find_probabilities(top, states, outputfiles): + if outputfiles['hpo'] is None: + return + transitions = defaultdict(list) total_states = top['total_states'] matrix = np.zeros((total_states, total_states)) @@ -29,8 +32,7 @@ def find_probabilities(top, states, outputfiles): matrix_a = np.identity(len(reachable_states)) - matrix[np.ix_(reachable_states, reachable_states)] probabilities = np.linalg.solve(matrix_a, list_b) - if outputfiles['hpo'] is not None: - np.savetxt(outputfiles['hpo'], np.stack((reachable_states, probabilities), axis=1), delimiter=",") + np.savetxt(outputfiles['hpo'], np.stack((reachable_states, probabilities), axis=1), delimiter=",") """ diff --git a/harmony_model_checker/parser/HarmonyLexer.py b/harmony_model_checker/parser/HarmonyLexer.py index 29280466..3fb668d9 100644 --- a/harmony_model_checker/parser/HarmonyLexer.py +++ b/harmony_model_checker/parser/HarmonyLexer.py @@ -15,8 +15,8 @@ def serializedATN(): with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2v") - buf.write("\u036c\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7") + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2w") + buf.write("\u037b\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7") buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r") buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23") buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30") @@ -32,29 +32,29 @@ def serializedATN(): buf.write("^\t^\4_\t_\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4") buf.write("g\tg\4h\th\4i\ti\4j\tj\4k\tk\4l\tl\4m\tm\4n\tn\4o\to\4") buf.write("p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv\4w\tw\4x\tx\4") - buf.write("y\ty\4z\tz\4{\t{\4|\t|\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\4") - buf.write("\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3") - buf.write("\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3\16\3\16") - buf.write("\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3\22\3\22") - buf.write("\3\22\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26\3\26\3\26") - buf.write("\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31") - buf.write("\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32") - buf.write("\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33") - buf.write("\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34") - buf.write("\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\36") - buf.write("\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!") - buf.write("\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3$\3$\3$\3$\3%\3") - buf.write("%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3\'") - buf.write("\3(\3(\3(\3(\3)\3)\3)\3)\3)\3*\3*\3*\3*\3+\3+\3+\3+\3") - buf.write(",\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\61") - buf.write("\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\64\3\64") - buf.write("\3\64\3\65\3\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\67") - buf.write("\3\67\3\67\3\67\38\58\u01d1\n8\38\38\78\u01d5\n8\f8\16") - buf.write("8\u01d8\138\38\78\u01db\n8\f8\168\u01de\138\58\u01e0\n") - buf.write("8\38\38\39\69\u01e5\n9\r9\169\u01e6\39\69\u01ea\n9\r9") - buf.write("\169\u01eb\39\39\39\59\u01f1\n9\39\39\3:\3:\7:\u01f7\n") - buf.write(":\f:\16:\u01fa\13:\3:\3:\3:\3:\7:\u0200\n:\f:\16:\u0203") - buf.write("\13:\5:\u0205\n:\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3?\3?\3") + buf.write("y\ty\4z\tz\4{\t{\4|\t|\4}\t}\3\2\3\2\3\2\3\2\3\3\3\3\3") + buf.write("\3\3\4\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t") + buf.write("\3\n\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3") + buf.write("\16\3\16\3\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21") + buf.write("\3\22\3\22\3\22\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26") + buf.write("\3\26\3\26\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31") + buf.write("\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32") + buf.write("\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33") + buf.write("\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34") + buf.write("\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35") + buf.write("\3\35\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 \3") + buf.write(" \3 \3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3$\3$") + buf.write("\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3") + buf.write("\'\3\'\3\'\3(\3(\3(\3(\3)\3)\3)\3)\3)\3*\3*\3*\3*\3+\3") + buf.write("+\3+\3+\3,\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60") + buf.write("\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\63") + buf.write("\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\65\3\66\3\66\3\66") + buf.write("\3\66\3\67\3\67\3\67\3\67\38\58\u01d3\n8\38\38\78\u01d7") + buf.write("\n8\f8\168\u01da\138\38\78\u01dd\n8\f8\168\u01e0\138\5") + buf.write("8\u01e2\n8\38\38\39\69\u01e7\n9\r9\169\u01e8\39\69\u01ec") + buf.write("\n9\r9\169\u01ed\39\39\39\59\u01f3\n9\39\39\3:\3:\7:\u01f9") + buf.write("\n:\f:\16:\u01fc\13:\3:\3:\3:\3:\7:\u0202\n:\f:\16:\u0205") + buf.write("\13:\5:\u0207\n:\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3?\3?\3") buf.write("@\3@\3@\3A\3A\3B\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C\3C\3") buf.write("D\3D\3D\3D\3D\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3") buf.write("F\3F\3G\3G\3G\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3") @@ -67,329 +67,335 @@ def serializedATN(): buf.write("_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3a\3a\3a\3b\3b\3b\3b\3") buf.write("b\3b\3c\3c\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3f\3f\3g\3") buf.write("g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h\3h\3h\3h\3h\3i\3i\3i\3") - buf.write("i\3i\3i\3i\3i\3i\5i\u02ef\ni\3j\3j\3j\3j\3j\3j\3j\3j\3") - buf.write("k\6k\u02fa\nk\rk\16k\u02fb\3k\3k\3k\5k\u0301\nk\3l\3l") - buf.write("\7l\u0305\nl\fl\16l\u0308\13l\3m\3m\3m\5m\u030d\nm\3n") - buf.write("\3n\3n\3n\6n\u0313\nn\rn\16n\u0314\3o\3o\3p\3p\3p\3q\3") - buf.write("q\3q\3r\3r\3r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3w\3w\5") - buf.write("w\u032f\nw\3x\3x\3x\7x\u0334\nx\fx\16x\u0337\13x\3x\3") - buf.write("x\3x\3x\7x\u033d\nx\fx\16x\u0340\13x\3x\5x\u0343\nx\3") - buf.write("y\3y\3y\3y\3y\7y\u034a\ny\fy\16y\u034d\13y\3y\3y\3y\3") - buf.write("y\3y\3y\3y\3y\7y\u0357\ny\fy\16y\u035a\13y\3y\3y\3y\5") - buf.write("y\u035f\ny\3z\3z\5z\u0363\nz\3{\3{\3|\3|\3|\3|\5|\u036b") - buf.write("\n|\5\u01f8\u034b\u0358\2}\3\3\5\4\7\5\t\6\13\7\r\b\17") - buf.write("\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23") - buf.write("%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36") - buf.write(";\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63") - buf.write("e\64g\65i\66k\67m8o9q:s\2u;w}?\177@\u0081A\u0083") - buf.write("B\u0085C\u0087D\u0089E\u008bF\u008dG\u008fH\u0091I\u0093") - buf.write("J\u0095K\u0097L\u0099M\u009bN\u009dO\u009fP\u00a1Q\u00a3") - buf.write("R\u00a5S\u00a7T\u00a9U\u00abV\u00adW\u00afX\u00b1Y\u00b3") - buf.write("Z\u00b5[\u00b7\\\u00b9]\u00bb^\u00bd_\u00bf`\u00c1a\u00c3") - buf.write("b\u00c5c\u00c7d\u00c9e\u00cbf\u00cdg\u00cfh\u00d1i\u00d3") - buf.write("j\u00d5k\u00d7l\u00d9m\u00dbn\u00dd\2\u00dfo\u00e1p\u00e3") - buf.write("q\u00e5r\u00e7s\u00e9t\u00ebu\u00edv\u00ef\2\u00f1\2\u00f3") - buf.write("\2\u00f5\2\u00f7\2\3\2\13\4\2\f\f\16\17\3\2\62;\5\2C\\") - buf.write("aac|\6\2\62;C\\aac|\3\2\60\60\5\2\62;CHch\6\2\f\f\16\17") - buf.write("))^^\6\2\f\f\16\17$$^^\3\2^^\2\u0381\2\3\3\2\2\2\2\5\3") - buf.write("\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2") - buf.write("\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2") - buf.write("\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2") - buf.write("\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2") - buf.write("\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3") - buf.write("\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2") - buf.write("\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2") - buf.write("\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3") - buf.write("\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W") - buf.write("\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2") - buf.write("a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2") - buf.write("\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2u\3\2\2") - buf.write("\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3") - buf.write("\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2") - buf.write("\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d") - buf.write("\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2") - buf.write("\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b") - buf.write("\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2") - buf.write("\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9") - buf.write("\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2") - buf.write("\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7") - buf.write("\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2") - buf.write("\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5") - buf.write("\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2") - buf.write("\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3") - buf.write("\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2") - buf.write("\2\2\u00db\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3") - buf.write("\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2") - buf.write("\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\3\u00f9\3\2\2\2\5\u00fd") - buf.write("\3\2\2\2\7\u0100\3\2\2\2\t\u0103\3\2\2\2\13\u0105\3\2") - buf.write("\2\2\r\u0107\3\2\2\2\17\u0109\3\2\2\2\21\u010b\3\2\2\2") - buf.write("\23\u010d\3\2\2\2\25\u0110\3\2\2\2\27\u0112\3\2\2\2\31") - buf.write("\u0114\3\2\2\2\33\u0118\3\2\2\2\35\u011b\3\2\2\2\37\u011e") - buf.write("\3\2\2\2!\u0121\3\2\2\2#\u0124\3\2\2\2%\u0127\3\2\2\2") - buf.write("\'\u0129\3\2\2\2)\u012c\3\2\2\2+\u012e\3\2\2\2-\u0131") - buf.write("\3\2\2\2/\u0133\3\2\2\2\61\u0137\3\2\2\2\63\u013f\3\2") - buf.write("\2\2\65\u014a\3\2\2\2\67\u0156\3\2\2\29\u015f\3\2\2\2") - buf.write(";\u0167\3\2\2\2=\u016b\3\2\2\2?\u016f\3\2\2\2A\u0173\3") - buf.write("\2\2\2C\u0178\3\2\2\2E\u017c\3\2\2\2G\u0180\3\2\2\2I\u0184") - buf.write("\3\2\2\2K\u0189\3\2\2\2M\u018e\3\2\2\2O\u0195\3\2\2\2") - buf.write("Q\u0199\3\2\2\2S\u019e\3\2\2\2U\u01a2\3\2\2\2W\u01a6\3") - buf.write("\2\2\2Y\u01a9\3\2\2\2[\u01ac\3\2\2\2]\u01af\3\2\2\2_\u01b2") - buf.write("\3\2\2\2a\u01b5\3\2\2\2c\u01b8\3\2\2\2e\u01bb\3\2\2\2") - buf.write("g\u01bf\3\2\2\2i\u01c2\3\2\2\2k\u01c7\3\2\2\2m\u01cb\3") - buf.write("\2\2\2o\u01d0\3\2\2\2q\u01f0\3\2\2\2s\u0204\3\2\2\2u\u0206") - buf.write("\3\2\2\2w\u0208\3\2\2\2y\u020b\3\2\2\2{\u020e\3\2\2\2") - buf.write("}\u0210\3\2\2\2\177\u0212\3\2\2\2\u0081\u0215\3\2\2\2") - buf.write("\u0083\u0217\3\2\2\2\u0085\u021e\3\2\2\2\u0087\u0224\3") - buf.write("\2\2\2\u0089\u0229\3\2\2\2\u008b\u022c\3\2\2\2\u008d\u0238") - buf.write("\3\2\2\2\u008f\u023b\3\2\2\2\u0091\u0240\3\2\2\2\u0093") - buf.write("\u0245\3\2\2\2\u0095\u024c\3\2\2\2\u0097\u024e\3\2\2\2") - buf.write("\u0099\u0252\3\2\2\2\u009b\u0254\3\2\2\2\u009d\u025a\3") - buf.write("\2\2\2\u009f\u0260\3\2\2\2\u00a1\u0267\3\2\2\2\u00a3\u026b") - buf.write("\3\2\2\2\u00a5\u0270\3\2\2\2\u00a7\u0275\3\2\2\2\u00a9") - buf.write("\u0279\3\2\2\2\u00ab\u027f\3\2\2\2\u00ad\u0289\3\2\2\2") - buf.write("\u00af\u028c\3\2\2\2\u00b1\u0297\3\2\2\2\u00b3\u029c\3") - buf.write("\2\2\2\u00b5\u02a0\3\2\2\2\u00b7\u02a3\3\2\2\2\u00b9\u02a8") - buf.write("\3\2\2\2\u00bb\u02ad\3\2\2\2\u00bd\u02af\3\2\2\2\u00bf") - buf.write("\u02b5\3\2\2\2\u00c1\u02b9\3\2\2\2\u00c3\u02c0\3\2\2\2") - buf.write("\u00c5\u02c6\3\2\2\2\u00c7\u02c8\3\2\2\2\u00c9\u02ce\3") - buf.write("\2\2\2\u00cb\u02d3\3\2\2\2\u00cd\u02d5\3\2\2\2\u00cf\u02da") - buf.write("\3\2\2\2\u00d1\u02ee\3\2\2\2\u00d3\u02f0\3\2\2\2\u00d5") - buf.write("\u0300\3\2\2\2\u00d7\u0302\3\2\2\2\u00d9\u0309\3\2\2\2") - buf.write("\u00db\u030e\3\2\2\2\u00dd\u0316\3\2\2\2\u00df\u0318\3") - buf.write("\2\2\2\u00e1\u031b\3\2\2\2\u00e3\u031e\3\2\2\2\u00e5\u0321") - buf.write("\3\2\2\2\u00e7\u0324\3\2\2\2\u00e9\u0327\3\2\2\2\u00eb") - buf.write("\u032a\3\2\2\2\u00ed\u032e\3\2\2\2\u00ef\u0342\3\2\2\2") - buf.write("\u00f1\u035e\3\2\2\2\u00f3\u0362\3\2\2\2\u00f5\u0364\3") - buf.write("\2\2\2\u00f7\u036a\3\2\2\2\u00f9\u00fa\7c\2\2\u00fa\u00fb") - buf.write("\7p\2\2\u00fb\u00fc\7f\2\2\u00fc\4\3\2\2\2\u00fd\u00fe") - buf.write("\7q\2\2\u00fe\u00ff\7t\2\2\u00ff\6\3\2\2\2\u0100\u0101") - buf.write("\7?\2\2\u0101\u0102\7@\2\2\u0102\b\3\2\2\2\u0103\u0104") - buf.write("\7(\2\2\u0104\n\3\2\2\2\u0105\u0106\7~\2\2\u0106\f\3\2") - buf.write("\2\2\u0107\u0108\7`\2\2\u0108\16\3\2\2\2\u0109\u010a\7") - buf.write("/\2\2\u010a\20\3\2\2\2\u010b\u010c\7-\2\2\u010c\22\3\2") - buf.write("\2\2\u010d\u010e\7\61\2\2\u010e\u010f\7\61\2\2\u010f\24") - buf.write("\3\2\2\2\u0110\u0111\7\61\2\2\u0111\26\3\2\2\2\u0112\u0113") - buf.write("\7\'\2\2\u0113\30\3\2\2\2\u0114\u0115\7o\2\2\u0115\u0116") - buf.write("\7q\2\2\u0116\u0117\7f\2\2\u0117\32\3\2\2\2\u0118\u0119") - buf.write("\7,\2\2\u0119\u011a\7,\2\2\u011a\34\3\2\2\2\u011b\u011c") - buf.write("\7>\2\2\u011c\u011d\7>\2\2\u011d\36\3\2\2\2\u011e\u011f") - buf.write("\7@\2\2\u011f\u0120\7@\2\2\u0120 \3\2\2\2\u0121\u0122") - buf.write("\7?\2\2\u0122\u0123\7?\2\2\u0123\"\3\2\2\2\u0124\u0125") - buf.write("\7#\2\2\u0125\u0126\7?\2\2\u0126$\3\2\2\2\u0127\u0128") - buf.write("\7>\2\2\u0128&\3\2\2\2\u0129\u012a\7>\2\2\u012a\u012b") - buf.write("\7?\2\2\u012b(\3\2\2\2\u012c\u012d\7@\2\2\u012d*\3\2\2") - buf.write("\2\u012e\u012f\7@\2\2\u012f\u0130\7?\2\2\u0130,\3\2\2") - buf.write("\2\u0131\u0132\7\u0080\2\2\u0132.\3\2\2\2\u0133\u0134") - buf.write("\7c\2\2\u0134\u0135\7d\2\2\u0135\u0136\7u\2\2\u0136\60") - buf.write("\3\2\2\2\u0137\u0138\7c\2\2\u0138\u0139\7v\2\2\u0139\u013a") - buf.write("\7N\2\2\u013a\u013b\7c\2\2\u013b\u013c\7d\2\2\u013c\u013d") - buf.write("\7g\2\2\u013d\u013e\7n\2\2\u013e\62\3\2\2\2\u013f\u0140") - buf.write("\7e\2\2\u0140\u0141\7q\2\2\u0141\u0142\7w\2\2\u0142\u0143") - buf.write("\7p\2\2\u0143\u0144\7v\2\2\u0144\u0145\7N\2\2\u0145\u0146") - buf.write("\7c\2\2\u0146\u0147\7d\2\2\u0147\u0148\7g\2\2\u0148\u0149") - buf.write("\7n\2\2\u0149\64\3\2\2\2\u014a\u014b\7i\2\2\u014b\u014c") - buf.write("\7g\2\2\u014c\u014d\7v\2\2\u014d\u014e\7a\2\2\u014e\u014f") - buf.write("\7e\2\2\u014f\u0150\7q\2\2\u0150\u0151\7p\2\2\u0151\u0152") - buf.write("\7v\2\2\u0152\u0153\7g\2\2\u0153\u0154\7z\2\2\u0154\u0155") - buf.write("\7v\2\2\u0155\66\3\2\2\2\u0156\u0157\7e\2\2\u0157\u0158") - buf.write("\7q\2\2\u0158\u0159\7p\2\2\u0159\u015a\7v\2\2\u015a\u015b") - buf.write("\7g\2\2\u015b\u015c\7z\2\2\u015c\u015d\7v\2\2\u015d\u015e") - buf.write("\7u\2\2\u015e8\3\2\2\2\u015f\u0160\7k\2\2\u0160\u0161") - buf.write("\7u\2\2\u0161\u0162\7G\2\2\u0162\u0163\7o\2\2\u0163\u0164") - buf.write("\7r\2\2\u0164\u0165\7v\2\2\u0165\u0166\7{\2\2\u0166:\3") - buf.write("\2\2\2\u0167\u0168\7o\2\2\u0168\u0169\7k\2\2\u0169\u016a") - buf.write("\7p\2\2\u016a<\3\2\2\2\u016b\u016c\7o\2\2\u016c\u016d") - buf.write("\7c\2\2\u016d\u016e\7z\2\2\u016e>\3\2\2\2\u016f\u0170") - buf.write("\7n\2\2\u0170\u0171\7g\2\2\u0171\u0172\7p\2\2\u0172@\3") - buf.write("\2\2\2\u0173\u0174\7v\2\2\u0174\u0175\7{\2\2\u0175\u0176") - buf.write("\7r\2\2\u0176\u0177\7g\2\2\u0177B\3\2\2\2\u0178\u0179") - buf.write("\7u\2\2\u0179\u017a\7v\2\2\u017a\u017b\7t\2\2\u017bD\3") - buf.write("\2\2\2\u017c\u017d\7c\2\2\u017d\u017e\7p\2\2\u017e\u017f") - buf.write("\7{\2\2\u017fF\3\2\2\2\u0180\u0181\7c\2\2\u0181\u0182") - buf.write("\7n\2\2\u0182\u0183\7n\2\2\u0183H\3\2\2\2\u0184\u0185") - buf.write("\7m\2\2\u0185\u0186\7g\2\2\u0186\u0187\7{\2\2\u0187\u0188") - buf.write("\7u\2\2\u0188J\3\2\2\2\u0189\u018a\7j\2\2\u018a\u018b") - buf.write("\7c\2\2\u018b\u018c\7u\2\2\u018c\u018d\7j\2\2\u018dL\3") - buf.write("\2\2\2\u018e\u018f\7e\2\2\u018f\u0190\7j\2\2\u0190\u0191") - buf.write("\7q\2\2\u0191\u0192\7q\2\2\u0192\u0193\7u\2\2\u0193\u0194") - buf.write("\7g\2\2\u0194N\3\2\2\2\u0195\u0196\7g\2\2\u0196\u0197") - buf.write("\7p\2\2\u0197\u0198\7f\2\2\u0198P\3\2\2\2\u0199\u019a") - buf.write("\7c\2\2\u019a\u019b\7p\2\2\u019b\u019c\7f\2\2\u019c\u019d") - buf.write("\7?\2\2\u019dR\3\2\2\2\u019e\u019f\7q\2\2\u019f\u01a0") - buf.write("\7t\2\2\u01a0\u01a1\7?\2\2\u01a1T\3\2\2\2\u01a2\u01a3") - buf.write("\7?\2\2\u01a3\u01a4\7@\2\2\u01a4\u01a5\7?\2\2\u01a5V\3") - buf.write("\2\2\2\u01a6\u01a7\7(\2\2\u01a7\u01a8\7?\2\2\u01a8X\3") - buf.write("\2\2\2\u01a9\u01aa\7~\2\2\u01aa\u01ab\7?\2\2\u01abZ\3") - buf.write("\2\2\2\u01ac\u01ad\7`\2\2\u01ad\u01ae\7?\2\2\u01ae\\\3") - buf.write("\2\2\2\u01af\u01b0\7/\2\2\u01b0\u01b1\7?\2\2\u01b1^\3") - buf.write("\2\2\2\u01b2\u01b3\7-\2\2\u01b3\u01b4\7?\2\2\u01b4`\3") - buf.write("\2\2\2\u01b5\u01b6\7,\2\2\u01b6\u01b7\7?\2\2\u01b7b\3") - buf.write("\2\2\2\u01b8\u01b9\7\61\2\2\u01b9\u01ba\7?\2\2\u01bad") - buf.write("\3\2\2\2\u01bb\u01bc\7\61\2\2\u01bc\u01bd\7\61\2\2\u01bd") - buf.write("\u01be\7?\2\2\u01bef\3\2\2\2\u01bf\u01c0\7\'\2\2\u01c0") - buf.write("\u01c1\7?\2\2\u01c1h\3\2\2\2\u01c2\u01c3\7o\2\2\u01c3") - buf.write("\u01c4\7q\2\2\u01c4\u01c5\7f\2\2\u01c5\u01c6\7?\2\2\u01c6") - buf.write("j\3\2\2\2\u01c7\u01c8\7,\2\2\u01c8\u01c9\7,\2\2\u01c9") - buf.write("\u01ca\7?\2\2\u01cal\3\2\2\2\u01cb\u01cc\7@\2\2\u01cc") - buf.write("\u01cd\7@\2\2\u01cd\u01ce\7?\2\2\u01cen\3\2\2\2\u01cf") - buf.write("\u01d1\7\17\2\2\u01d0\u01cf\3\2\2\2\u01d0\u01d1\3\2\2") - buf.write("\2\u01d1\u01d2\3\2\2\2\u01d2\u01df\7\f\2\2\u01d3\u01d5") - buf.write("\7\"\2\2\u01d4\u01d3\3\2\2\2\u01d5\u01d8\3\2\2\2\u01d6") - buf.write("\u01d4\3\2\2\2\u01d6\u01d7\3\2\2\2\u01d7\u01e0\3\2\2\2") - buf.write("\u01d8\u01d6\3\2\2\2\u01d9\u01db\7\13\2\2\u01da\u01d9") - buf.write("\3\2\2\2\u01db\u01de\3\2\2\2\u01dc\u01da\3\2\2\2\u01dc") - buf.write("\u01dd\3\2\2\2\u01dd\u01e0\3\2\2\2\u01de\u01dc\3\2\2\2") - buf.write("\u01df\u01d6\3\2\2\2\u01df\u01dc\3\2\2\2\u01e0\u01e1\3") - buf.write("\2\2\2\u01e1\u01e2\b8\2\2\u01e2p\3\2\2\2\u01e3\u01e5\7") - buf.write("\"\2\2\u01e4\u01e3\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6\u01e4") - buf.write("\3\2\2\2\u01e6\u01e7\3\2\2\2\u01e7\u01f1\3\2\2\2\u01e8") - buf.write("\u01ea\7\13\2\2\u01e9\u01e8\3\2\2\2\u01ea\u01eb\3\2\2") - buf.write("\2\u01eb\u01e9\3\2\2\2\u01eb\u01ec\3\2\2\2\u01ec\u01f1") - buf.write("\3\2\2\2\u01ed\u01ee\7^\2\2\u01ee\u01f1\5o8\2\u01ef\u01f1") - buf.write("\5s:\2\u01f0\u01e4\3\2\2\2\u01f0\u01e9\3\2\2\2\u01f0\u01ed") - buf.write("\3\2\2\2\u01f0\u01ef\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2") - buf.write("\u01f3\b9\3\2\u01f3r\3\2\2\2\u01f4\u01f8\5w<\2\u01f5\u01f7") - buf.write("\13\2\2\2\u01f6\u01f5\3\2\2\2\u01f7\u01fa\3\2\2\2\u01f8") - buf.write("\u01f9\3\2\2\2\u01f8\u01f6\3\2\2\2\u01f9\u01fb\3\2\2\2") - buf.write("\u01fa\u01f8\3\2\2\2\u01fb\u01fc\5y=\2\u01fc\u0205\3\2") - buf.write("\2\2\u01fd\u0201\5u;\2\u01fe\u0200\n\2\2\2\u01ff\u01fe") - buf.write("\3\2\2\2\u0200\u0203\3\2\2\2\u0201\u01ff\3\2\2\2\u0201") - buf.write("\u0202\3\2\2\2\u0202\u0205\3\2\2\2\u0203\u0201\3\2\2\2") - buf.write("\u0204\u01f4\3\2\2\2\u0204\u01fd\3\2\2\2\u0205t\3\2\2") - buf.write("\2\u0206\u0207\7%\2\2\u0207v\3\2\2\2\u0208\u0209\7*\2") - buf.write("\2\u0209\u020a\7,\2\2\u020ax\3\2\2\2\u020b\u020c\7,\2") - buf.write("\2\u020c\u020d\7+\2\2\u020dz\3\2\2\2\u020e\u020f\7#\2") - buf.write("\2\u020f|\3\2\2\2\u0210\u0211\7,\2\2\u0211~\3\2\2\2\u0212") - buf.write("\u0213\7c\2\2\u0213\u0214\7u\2\2\u0214\u0080\3\2\2\2\u0215") - buf.write("\u0216\7\60\2\2\u0216\u0082\3\2\2\2\u0217\u0218\7k\2\2") - buf.write("\u0218\u0219\7o\2\2\u0219\u021a\7r\2\2\u021a\u021b\7q") - buf.write("\2\2\u021b\u021c\7t\2\2\u021c\u021d\7v\2\2\u021d\u0084") - buf.write("\3\2\2\2\u021e\u021f\7r\2\2\u021f\u0220\7t\2\2\u0220\u0221") - buf.write("\7k\2\2\u0221\u0222\7p\2\2\u0222\u0223\7v\2\2\u0223\u0086") - buf.write("\3\2\2\2\u0224\u0225\7h\2\2\u0225\u0226\7t\2\2\u0226\u0227") - buf.write("\7q\2\2\u0227\u0228\7o\2\2\u0228\u0088\3\2\2\2\u0229\u022a") - buf.write("\7\60\2\2\u022a\u022b\7\60\2\2\u022b\u008a\3\2\2\2\u022c") - buf.write("\u022d\7u\2\2\u022d\u022e\7g\2\2\u022e\u022f\7v\2\2\u022f") - buf.write("\u0230\7k\2\2\u0230\u0231\7p\2\2\u0231\u0232\7v\2\2\u0232") - buf.write("\u0233\7n\2\2\u0233\u0234\7g\2\2\u0234\u0235\7x\2\2\u0235") - buf.write("\u0236\7g\2\2\u0236\u0237\7n\2\2\u0237\u008c\3\2\2\2\u0238") - buf.write("\u0239\7/\2\2\u0239\u023a\7@\2\2\u023a\u008e\3\2\2\2\u023b") - buf.write("\u023c\7u\2\2\u023c\u023d\7c\2\2\u023d\u023e\7x\2\2\u023e") - buf.write("\u023f\7g\2\2\u023f\u0090\3\2\2\2\u0240\u0241\7u\2\2\u0241") - buf.write("\u0242\7v\2\2\u0242\u0243\7q\2\2\u0243\u0244\7r\2\2\u0244") - buf.write("\u0092\3\2\2\2\u0245\u0246\7n\2\2\u0246\u0247\7c\2\2\u0247") - buf.write("\u0248\7o\2\2\u0248\u0249\7d\2\2\u0249\u024a\7f\2\2\u024a") - buf.write("\u024b\7c\2\2\u024b\u0094\3\2\2\2\u024c\u024d\7A\2\2\u024d") - buf.write("\u0096\3\2\2\2\u024e\u024f\7p\2\2\u024f\u0250\7q\2\2\u0250") - buf.write("\u0251\7v\2\2\u0251\u0098\3\2\2\2\u0252\u0253\7.\2\2\u0253") - buf.write("\u009a\3\2\2\2\u0254\u0255\7e\2\2\u0255\u0256\7q\2\2\u0256") - buf.write("\u0257\7p\2\2\u0257\u0258\7u\2\2\u0258\u0259\7v\2\2\u0259") - buf.write("\u009c\3\2\2\2\u025a\u025b\7c\2\2\u025b\u025c\7y\2\2\u025c") - buf.write("\u025d\7c\2\2\u025d\u025e\7k\2\2\u025e\u025f\7v\2\2\u025f") - buf.write("\u009e\3\2\2\2\u0260\u0261\7c\2\2\u0261\u0262\7u\2\2\u0262") - buf.write("\u0263\7u\2\2\u0263\u0264\7g\2\2\u0264\u0265\7t\2\2\u0265") - buf.write("\u0266\7v\2\2\u0266\u00a0\3\2\2\2\u0267\u0268\7x\2\2\u0268") - buf.write("\u0269\7c\2\2\u0269\u026a\7t\2\2\u026a\u00a2\3\2\2\2\u026b") - buf.write("\u026c\7v\2\2\u026c\u026d\7t\2\2\u026d\u026e\7c\2\2\u026e") - buf.write("\u026f\7r\2\2\u026f\u00a4\3\2\2\2\u0270\u0271\7r\2\2\u0271") - buf.write("\u0272\7c\2\2\u0272\u0273\7u\2\2\u0273\u0274\7u\2\2\u0274") - buf.write("\u00a6\3\2\2\2\u0275\u0276\7f\2\2\u0276\u0277\7g\2\2\u0277") - buf.write("\u0278\7n\2\2\u0278\u00a8\3\2\2\2\u0279\u027a\7u\2\2\u027a") - buf.write("\u027b\7r\2\2\u027b\u027c\7c\2\2\u027c\u027d\7y\2\2\u027d") - buf.write("\u027e\7p\2\2\u027e\u00aa\3\2\2\2\u027f\u0280\7k\2\2\u0280") - buf.write("\u0281\7p\2\2\u0281\u0282\7x\2\2\u0282\u0283\7c\2\2\u0283") - buf.write("\u0284\7t\2\2\u0284\u0285\7k\2\2\u0285\u0286\7c\2\2\u0286") - buf.write("\u0287\7p\2\2\u0287\u0288\7v\2\2\u0288\u00ac\3\2\2\2\u0289") - buf.write("\u028a\7i\2\2\u028a\u028b\7q\2\2\u028b\u00ae\3\2\2\2\u028c") - buf.write("\u028d\7u\2\2\u028d\u028e\7g\2\2\u028e\u028f\7s\2\2\u028f") - buf.write("\u0290\7w\2\2\u0290\u0291\7g\2\2\u0291\u0292\7p\2\2\u0292") - buf.write("\u0293\7v\2\2\u0293\u0294\7k\2\2\u0294\u0295\7c\2\2\u0295") - buf.write("\u0296\7n\2\2\u0296\u00b0\3\2\2\2\u0297\u0298\7y\2\2\u0298") - buf.write("\u0299\7j\2\2\u0299\u029a\7g\2\2\u029a\u029b\7p\2\2\u029b") - buf.write("\u00b2\3\2\2\2\u029c\u029d\7n\2\2\u029d\u029e\7g\2\2\u029e") - buf.write("\u029f\7v\2\2\u029f\u00b4\3\2\2\2\u02a0\u02a1\7k\2\2\u02a1") - buf.write("\u02a2\7h\2\2\u02a2\u00b6\3\2\2\2\u02a3\u02a4\7g\2\2\u02a4") - buf.write("\u02a5\7n\2\2\u02a5\u02a6\7k\2\2\u02a6\u02a7\7h\2\2\u02a7") - buf.write("\u00b8\3\2\2\2\u02a8\u02a9\7g\2\2\u02a9\u02aa\7n\2\2\u02aa") - buf.write("\u02ab\7u\2\2\u02ab\u02ac\7g\2\2\u02ac\u00ba\3\2\2\2\u02ad") - buf.write("\u02ae\7B\2\2\u02ae\u00bc\3\2\2\2\u02af\u02b0\7y\2\2\u02b0") - buf.write("\u02b1\7j\2\2\u02b1\u02b2\7k\2\2\u02b2\u02b3\7n\2\2\u02b3") - buf.write("\u02b4\7g\2\2\u02b4\u00be\3\2\2\2\u02b5\u02b6\7f\2\2\u02b6") - buf.write("\u02b7\7g\2\2\u02b7\u02b8\7h\2\2\u02b8\u00c0\3\2\2\2\u02b9") - buf.write("\u02ba\7g\2\2\u02ba\u02bb\7z\2\2\u02bb\u02bc\7k\2\2\u02bc") - buf.write("\u02bd\7u\2\2\u02bd\u02be\7v\2\2\u02be\u02bf\7u\2\2\u02bf") - buf.write("\u00c2\3\2\2\2\u02c0\u02c1\7y\2\2\u02c1\u02c2\7j\2\2\u02c2") - buf.write("\u02c3\7g\2\2\u02c3\u02c4\7t\2\2\u02c4\u02c5\7g\2\2\u02c5") - buf.write("\u00c4\3\2\2\2\u02c6\u02c7\7?\2\2\u02c7\u00c6\3\2\2\2") - buf.write("\u02c8\u02c9\7h\2\2\u02c9\u02ca\7q\2\2\u02ca\u02cb\7t") - buf.write("\2\2\u02cb\u02cc\3\2\2\2\u02cc\u02cd\bd\4\2\u02cd\u00c8") - buf.write("\3\2\2\2\u02ce\u02cf\7k\2\2\u02cf\u02d0\7p\2\2\u02d0\u02d1") - buf.write("\3\2\2\2\u02d1\u02d2\be\5\2\u02d2\u00ca\3\2\2\2\u02d3") - buf.write("\u02d4\7<\2\2\u02d4\u00cc\3\2\2\2\u02d5\u02d6\7P\2\2\u02d6") - buf.write("\u02d7\7q\2\2\u02d7\u02d8\7p\2\2\u02d8\u02d9\7g\2\2\u02d9") - buf.write("\u00ce\3\2\2\2\u02da\u02db\7c\2\2\u02db\u02dc\7v\2\2\u02dc") - buf.write("\u02dd\7q\2\2\u02dd\u02de\7o\2\2\u02de\u02df\7k\2\2\u02df") - buf.write("\u02e0\7e\2\2\u02e0\u02e1\7c\2\2\u02e1\u02e2\7n\2\2\u02e2") - buf.write("\u02e3\7n\2\2\u02e3\u02e4\7{\2\2\u02e4\u00d0\3\2\2\2\u02e5") - buf.write("\u02e6\7H\2\2\u02e6\u02e7\7c\2\2\u02e7\u02e8\7n\2\2\u02e8") - buf.write("\u02e9\7u\2\2\u02e9\u02ef\7g\2\2\u02ea\u02eb\7V\2\2\u02eb") - buf.write("\u02ec\7t\2\2\u02ec\u02ed\7w\2\2\u02ed\u02ef\7g\2\2\u02ee") - buf.write("\u02e5\3\2\2\2\u02ee\u02ea\3\2\2\2\u02ef\u00d2\3\2\2\2") - buf.write("\u02f0\u02f1\7g\2\2\u02f1\u02f2\7v\2\2\u02f2\u02f3\7g") - buf.write("\2\2\u02f3\u02f4\7t\2\2\u02f4\u02f5\7p\2\2\u02f5\u02f6") - buf.write("\7c\2\2\u02f6\u02f7\7n\2\2\u02f7\u00d4\3\2\2\2\u02f8\u02fa") - buf.write("\t\3\2\2\u02f9\u02f8\3\2\2\2\u02fa\u02fb\3\2\2\2\u02fb") - buf.write("\u02f9\3\2\2\2\u02fb\u02fc\3\2\2\2\u02fc\u0301\3\2\2\2") - buf.write("\u02fd\u02fe\7k\2\2\u02fe\u02ff\7p\2\2\u02ff\u0301\7h") - buf.write("\2\2\u0300\u02f9\3\2\2\2\u0300\u02fd\3\2\2\2\u0301\u00d6") - buf.write("\3\2\2\2\u0302\u0306\t\4\2\2\u0303\u0305\t\5\2\2\u0304") - buf.write("\u0303\3\2\2\2\u0305\u0308\3\2\2\2\u0306\u0304\3\2\2\2") - buf.write("\u0306\u0307\3\2\2\2\u0307\u00d8\3\2\2\2\u0308\u0306\3") - buf.write("\2\2\2\u0309\u030c\t\6\2\2\u030a\u030d\5\u00dbn\2\u030b") - buf.write("\u030d\5\u00d7l\2\u030c\u030a\3\2\2\2\u030c\u030b\3\2") - buf.write("\2\2\u030d\u00da\3\2\2\2\u030e\u030f\7\62\2\2\u030f\u0310") - buf.write("\7Z\2\2\u0310\u0312\3\2\2\2\u0311\u0313\5\u00ddo\2\u0312") - buf.write("\u0311\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0312\3\2\2\2") - buf.write("\u0314\u0315\3\2\2\2\u0315\u00dc\3\2\2\2\u0316\u0317\t") - buf.write("\7\2\2\u0317\u00de\3\2\2\2\u0318\u0319\7]\2\2\u0319\u031a") - buf.write("\bp\6\2\u031a\u00e0\3\2\2\2\u031b\u031c\7_\2\2\u031c\u031d") - buf.write("\bq\7\2\u031d\u00e2\3\2\2\2\u031e\u031f\7}\2\2\u031f\u0320") - buf.write("\br\b\2\u0320\u00e4\3\2\2\2\u0321\u0322\7\177\2\2\u0322") - buf.write("\u0323\bs\t\2\u0323\u00e6\3\2\2\2\u0324\u0325\7*\2\2\u0325") - buf.write("\u0326\bt\n\2\u0326\u00e8\3\2\2\2\u0327\u0328\7+\2\2\u0328") - buf.write("\u0329\bu\13\2\u0329\u00ea\3\2\2\2\u032a\u032b\7=\2\2") - buf.write("\u032b\u00ec\3\2\2\2\u032c\u032f\5\u00efx\2\u032d\u032f") - buf.write("\5\u00f1y\2\u032e\u032c\3\2\2\2\u032e\u032d\3\2\2\2\u032f") - buf.write("\u00ee\3\2\2\2\u0330\u0335\7)\2\2\u0331\u0334\5\u00f7") - buf.write("|\2\u0332\u0334\n\b\2\2\u0333\u0331\3\2\2\2\u0333\u0332") - buf.write("\3\2\2\2\u0334\u0337\3\2\2\2\u0335\u0333\3\2\2\2\u0335") - buf.write("\u0336\3\2\2\2\u0336\u0338\3\2\2\2\u0337\u0335\3\2\2\2") - buf.write("\u0338\u0343\7)\2\2\u0339\u033e\7$\2\2\u033a\u033d\5\u00f7") - buf.write("|\2\u033b\u033d\n\t\2\2\u033c\u033a\3\2\2\2\u033c\u033b") - buf.write("\3\2\2\2\u033d\u0340\3\2\2\2\u033e\u033c\3\2\2\2\u033e") - buf.write("\u033f\3\2\2\2\u033f\u0341\3\2\2\2\u0340\u033e\3\2\2\2") - buf.write("\u0341\u0343\7$\2\2\u0342\u0330\3\2\2\2\u0342\u0339\3") - buf.write("\2\2\2\u0343\u00f0\3\2\2\2\u0344\u0345\7)\2\2\u0345\u0346") - buf.write("\7)\2\2\u0346\u0347\7)\2\2\u0347\u034b\3\2\2\2\u0348\u034a") - buf.write("\5\u00f3z\2\u0349\u0348\3\2\2\2\u034a\u034d\3\2\2\2\u034b") - buf.write("\u034c\3\2\2\2\u034b\u0349\3\2\2\2\u034c\u034e\3\2\2\2") - buf.write("\u034d\u034b\3\2\2\2\u034e\u034f\7)\2\2\u034f\u0350\7") - buf.write(")\2\2\u0350\u035f\7)\2\2\u0351\u0352\7$\2\2\u0352\u0353") - buf.write("\7$\2\2\u0353\u0354\7$\2\2\u0354\u0358\3\2\2\2\u0355\u0357") - buf.write("\5\u00f3z\2\u0356\u0355\3\2\2\2\u0357\u035a\3\2\2\2\u0358") - buf.write("\u0359\3\2\2\2\u0358\u0356\3\2\2\2\u0359\u035b\3\2\2\2") - buf.write("\u035a\u0358\3\2\2\2\u035b\u035c\7$\2\2\u035c\u035d\7") - buf.write("$\2\2\u035d\u035f\7$\2\2\u035e\u0344\3\2\2\2\u035e\u0351") - buf.write("\3\2\2\2\u035f\u00f2\3\2\2\2\u0360\u0363\5\u00f5{\2\u0361") - buf.write("\u0363\5\u00f7|\2\u0362\u0360\3\2\2\2\u0362\u0361\3\2") - buf.write("\2\2\u0363\u00f4\3\2\2\2\u0364\u0365\n\n\2\2\u0365\u00f6") - buf.write("\3\2\2\2\u0366\u0367\7^\2\2\u0367\u036b\13\2\2\2\u0368") - buf.write("\u0369\7^\2\2\u0369\u036b\5o8\2\u036a\u0366\3\2\2\2\u036a") - buf.write("\u0368\3\2\2\2\u036b\u00f8\3\2\2\2\36\2\u01d0\u01d6\u01dc") - buf.write("\u01df\u01e6\u01eb\u01f0\u01f8\u0201\u0204\u02ee\u02fb") - buf.write("\u0300\u0306\u030c\u0314\u032e\u0333\u0335\u033c\u033e") - buf.write("\u0342\u034b\u0358\u035e\u0362\u036a\f\38\2\b\2\2\3d\3") - buf.write("\3e\4\3p\5\3q\6\3r\7\3s\b\3t\t\3u\n") + buf.write("i\3i\3i\3i\3i\3i\5i\u02f1\ni\3j\3j\3j\3j\3j\3j\3j\3j\3") + buf.write("k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3l\6l\u0309\nl\r") + buf.write("l\16l\u030a\3l\3l\3l\5l\u0310\nl\3m\3m\7m\u0314\nm\fm") + buf.write("\16m\u0317\13m\3n\3n\3n\5n\u031c\nn\3o\3o\3o\3o\6o\u0322") + buf.write("\no\ro\16o\u0323\3p\3p\3q\3q\3q\3r\3r\3r\3s\3s\3s\3t\3") + buf.write("t\3t\3u\3u\3u\3v\3v\3v\3w\3w\3x\3x\5x\u033e\nx\3y\3y\3") + buf.write("y\7y\u0343\ny\fy\16y\u0346\13y\3y\3y\3y\3y\7y\u034c\n") + buf.write("y\fy\16y\u034f\13y\3y\5y\u0352\ny\3z\3z\3z\3z\3z\7z\u0359") + buf.write("\nz\fz\16z\u035c\13z\3z\3z\3z\3z\3z\3z\3z\3z\7z\u0366") + buf.write("\nz\fz\16z\u0369\13z\3z\3z\3z\5z\u036e\nz\3{\3{\5{\u0372") + buf.write("\n{\3|\3|\3}\3}\3}\3}\5}\u037a\n}\5\u01fa\u035a\u0367") + buf.write("\2~\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r") + buf.write("\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30") + buf.write("/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'") + buf.write("M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q") + buf.write(":s\2u;w}?\177@\u0081A\u0083B\u0085C\u0087D\u0089") + buf.write("E\u008bF\u008dG\u008fH\u0091I\u0093J\u0095K\u0097L\u0099") + buf.write("M\u009bN\u009dO\u009fP\u00a1Q\u00a3R\u00a5S\u00a7T\u00a9") + buf.write("U\u00abV\u00adW\u00afX\u00b1Y\u00b3Z\u00b5[\u00b7\\\u00b9") + buf.write("]\u00bb^\u00bd_\u00bf`\u00c1a\u00c3b\u00c5c\u00c7d\u00c9") + buf.write("e\u00cbf\u00cdg\u00cfh\u00d1i\u00d3j\u00d5k\u00d7l\u00d9") + buf.write("m\u00dbn\u00ddo\u00df\2\u00e1p\u00e3q\u00e5r\u00e7s\u00e9") + buf.write("t\u00ebu\u00edv\u00efw\u00f1\2\u00f3\2\u00f5\2\u00f7\2") + buf.write("\u00f9\2\3\2\13\4\2\f\f\16\17\3\2\62;\5\2C\\aac|\6\2\62") + buf.write(";C\\aac|\3\2\60\60\5\2\62;CHch\6\2\f\f\16\17))^^\6\2\f") + buf.write("\f\16\17$$^^\3\2^^\2\u0390\2\3\3\2\2\2\2\5\3\2\2\2\2\7") + buf.write("\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2") + buf.write("\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2") + buf.write("\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2") + buf.write("\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2") + buf.write("\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63") + buf.write("\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2") + buf.write("\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2") + buf.write("\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3") + buf.write("\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y") + buf.write("\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2") + buf.write("c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2") + buf.write("\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2u\3\2\2\2\2w\3\2\2") + buf.write("\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081") + buf.write("\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2") + buf.write("\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f") + buf.write("\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2") + buf.write("\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d") + buf.write("\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2") + buf.write("\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab") + buf.write("\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2") + buf.write("\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9") + buf.write("\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2") + buf.write("\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7") + buf.write("\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2") + buf.write("\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5") + buf.write("\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2") + buf.write("\2\2\u00dd\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5") + buf.write("\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2") + buf.write("\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\3\u00fb\3\2\2\2\5\u00ff") + buf.write("\3\2\2\2\7\u0102\3\2\2\2\t\u0105\3\2\2\2\13\u0107\3\2") + buf.write("\2\2\r\u0109\3\2\2\2\17\u010b\3\2\2\2\21\u010d\3\2\2\2") + buf.write("\23\u010f\3\2\2\2\25\u0112\3\2\2\2\27\u0114\3\2\2\2\31") + buf.write("\u0116\3\2\2\2\33\u011a\3\2\2\2\35\u011d\3\2\2\2\37\u0120") + buf.write("\3\2\2\2!\u0123\3\2\2\2#\u0126\3\2\2\2%\u0129\3\2\2\2") + buf.write("\'\u012b\3\2\2\2)\u012e\3\2\2\2+\u0130\3\2\2\2-\u0133") + buf.write("\3\2\2\2/\u0135\3\2\2\2\61\u0139\3\2\2\2\63\u0141\3\2") + buf.write("\2\2\65\u014c\3\2\2\2\67\u0158\3\2\2\29\u0161\3\2\2\2") + buf.write(";\u0169\3\2\2\2=\u016d\3\2\2\2?\u0171\3\2\2\2A\u0175\3") + buf.write("\2\2\2C\u017a\3\2\2\2E\u017e\3\2\2\2G\u0182\3\2\2\2I\u0186") + buf.write("\3\2\2\2K\u018b\3\2\2\2M\u0190\3\2\2\2O\u0197\3\2\2\2") + buf.write("Q\u019b\3\2\2\2S\u01a0\3\2\2\2U\u01a4\3\2\2\2W\u01a8\3") + buf.write("\2\2\2Y\u01ab\3\2\2\2[\u01ae\3\2\2\2]\u01b1\3\2\2\2_\u01b4") + buf.write("\3\2\2\2a\u01b7\3\2\2\2c\u01ba\3\2\2\2e\u01bd\3\2\2\2") + buf.write("g\u01c1\3\2\2\2i\u01c4\3\2\2\2k\u01c9\3\2\2\2m\u01cd\3") + buf.write("\2\2\2o\u01d2\3\2\2\2q\u01f2\3\2\2\2s\u0206\3\2\2\2u\u0208") + buf.write("\3\2\2\2w\u020a\3\2\2\2y\u020d\3\2\2\2{\u0210\3\2\2\2") + buf.write("}\u0212\3\2\2\2\177\u0214\3\2\2\2\u0081\u0217\3\2\2\2") + buf.write("\u0083\u0219\3\2\2\2\u0085\u0220\3\2\2\2\u0087\u0226\3") + buf.write("\2\2\2\u0089\u022b\3\2\2\2\u008b\u022e\3\2\2\2\u008d\u023a") + buf.write("\3\2\2\2\u008f\u023d\3\2\2\2\u0091\u0242\3\2\2\2\u0093") + buf.write("\u0247\3\2\2\2\u0095\u024e\3\2\2\2\u0097\u0250\3\2\2\2") + buf.write("\u0099\u0254\3\2\2\2\u009b\u0256\3\2\2\2\u009d\u025c\3") + buf.write("\2\2\2\u009f\u0262\3\2\2\2\u00a1\u0269\3\2\2\2\u00a3\u026d") + buf.write("\3\2\2\2\u00a5\u0272\3\2\2\2\u00a7\u0277\3\2\2\2\u00a9") + buf.write("\u027b\3\2\2\2\u00ab\u0281\3\2\2\2\u00ad\u028b\3\2\2\2") + buf.write("\u00af\u028e\3\2\2\2\u00b1\u0299\3\2\2\2\u00b3\u029e\3") + buf.write("\2\2\2\u00b5\u02a2\3\2\2\2\u00b7\u02a5\3\2\2\2\u00b9\u02aa") + buf.write("\3\2\2\2\u00bb\u02af\3\2\2\2\u00bd\u02b1\3\2\2\2\u00bf") + buf.write("\u02b7\3\2\2\2\u00c1\u02bb\3\2\2\2\u00c3\u02c2\3\2\2\2") + buf.write("\u00c5\u02c8\3\2\2\2\u00c7\u02ca\3\2\2\2\u00c9\u02d0\3") + buf.write("\2\2\2\u00cb\u02d5\3\2\2\2\u00cd\u02d7\3\2\2\2\u00cf\u02dc") + buf.write("\3\2\2\2\u00d1\u02f0\3\2\2\2\u00d3\u02f2\3\2\2\2\u00d5") + buf.write("\u02fa\3\2\2\2\u00d7\u030f\3\2\2\2\u00d9\u0311\3\2\2\2") + buf.write("\u00db\u0318\3\2\2\2\u00dd\u031d\3\2\2\2\u00df\u0325\3") + buf.write("\2\2\2\u00e1\u0327\3\2\2\2\u00e3\u032a\3\2\2\2\u00e5\u032d") + buf.write("\3\2\2\2\u00e7\u0330\3\2\2\2\u00e9\u0333\3\2\2\2\u00eb") + buf.write("\u0336\3\2\2\2\u00ed\u0339\3\2\2\2\u00ef\u033d\3\2\2\2") + buf.write("\u00f1\u0351\3\2\2\2\u00f3\u036d\3\2\2\2\u00f5\u0371\3") + buf.write("\2\2\2\u00f7\u0373\3\2\2\2\u00f9\u0379\3\2\2\2\u00fb\u00fc") + buf.write("\7c\2\2\u00fc\u00fd\7p\2\2\u00fd\u00fe\7f\2\2\u00fe\4") + buf.write("\3\2\2\2\u00ff\u0100\7q\2\2\u0100\u0101\7t\2\2\u0101\6") + buf.write("\3\2\2\2\u0102\u0103\7?\2\2\u0103\u0104\7@\2\2\u0104\b") + buf.write("\3\2\2\2\u0105\u0106\7(\2\2\u0106\n\3\2\2\2\u0107\u0108") + buf.write("\7~\2\2\u0108\f\3\2\2\2\u0109\u010a\7`\2\2\u010a\16\3") + buf.write("\2\2\2\u010b\u010c\7/\2\2\u010c\20\3\2\2\2\u010d\u010e") + buf.write("\7-\2\2\u010e\22\3\2\2\2\u010f\u0110\7\61\2\2\u0110\u0111") + buf.write("\7\61\2\2\u0111\24\3\2\2\2\u0112\u0113\7\61\2\2\u0113") + buf.write("\26\3\2\2\2\u0114\u0115\7\'\2\2\u0115\30\3\2\2\2\u0116") + buf.write("\u0117\7o\2\2\u0117\u0118\7q\2\2\u0118\u0119\7f\2\2\u0119") + buf.write("\32\3\2\2\2\u011a\u011b\7,\2\2\u011b\u011c\7,\2\2\u011c") + buf.write("\34\3\2\2\2\u011d\u011e\7>\2\2\u011e\u011f\7>\2\2\u011f") + buf.write("\36\3\2\2\2\u0120\u0121\7@\2\2\u0121\u0122\7@\2\2\u0122") + buf.write(" \3\2\2\2\u0123\u0124\7?\2\2\u0124\u0125\7?\2\2\u0125") + buf.write("\"\3\2\2\2\u0126\u0127\7#\2\2\u0127\u0128\7?\2\2\u0128") + buf.write("$\3\2\2\2\u0129\u012a\7>\2\2\u012a&\3\2\2\2\u012b\u012c") + buf.write("\7>\2\2\u012c\u012d\7?\2\2\u012d(\3\2\2\2\u012e\u012f") + buf.write("\7@\2\2\u012f*\3\2\2\2\u0130\u0131\7@\2\2\u0131\u0132") + buf.write("\7?\2\2\u0132,\3\2\2\2\u0133\u0134\7\u0080\2\2\u0134.") + buf.write("\3\2\2\2\u0135\u0136\7c\2\2\u0136\u0137\7d\2\2\u0137\u0138") + buf.write("\7u\2\2\u0138\60\3\2\2\2\u0139\u013a\7c\2\2\u013a\u013b") + buf.write("\7v\2\2\u013b\u013c\7N\2\2\u013c\u013d\7c\2\2\u013d\u013e") + buf.write("\7d\2\2\u013e\u013f\7g\2\2\u013f\u0140\7n\2\2\u0140\62") + buf.write("\3\2\2\2\u0141\u0142\7e\2\2\u0142\u0143\7q\2\2\u0143\u0144") + buf.write("\7w\2\2\u0144\u0145\7p\2\2\u0145\u0146\7v\2\2\u0146\u0147") + buf.write("\7N\2\2\u0147\u0148\7c\2\2\u0148\u0149\7d\2\2\u0149\u014a") + buf.write("\7g\2\2\u014a\u014b\7n\2\2\u014b\64\3\2\2\2\u014c\u014d") + buf.write("\7i\2\2\u014d\u014e\7g\2\2\u014e\u014f\7v\2\2\u014f\u0150") + buf.write("\7a\2\2\u0150\u0151\7e\2\2\u0151\u0152\7q\2\2\u0152\u0153") + buf.write("\7p\2\2\u0153\u0154\7v\2\2\u0154\u0155\7g\2\2\u0155\u0156") + buf.write("\7z\2\2\u0156\u0157\7v\2\2\u0157\66\3\2\2\2\u0158\u0159") + buf.write("\7e\2\2\u0159\u015a\7q\2\2\u015a\u015b\7p\2\2\u015b\u015c") + buf.write("\7v\2\2\u015c\u015d\7g\2\2\u015d\u015e\7z\2\2\u015e\u015f") + buf.write("\7v\2\2\u015f\u0160\7u\2\2\u01608\3\2\2\2\u0161\u0162") + buf.write("\7k\2\2\u0162\u0163\7u\2\2\u0163\u0164\7G\2\2\u0164\u0165") + buf.write("\7o\2\2\u0165\u0166\7r\2\2\u0166\u0167\7v\2\2\u0167\u0168") + buf.write("\7{\2\2\u0168:\3\2\2\2\u0169\u016a\7o\2\2\u016a\u016b") + buf.write("\7k\2\2\u016b\u016c\7p\2\2\u016c<\3\2\2\2\u016d\u016e") + buf.write("\7o\2\2\u016e\u016f\7c\2\2\u016f\u0170\7z\2\2\u0170>\3") + buf.write("\2\2\2\u0171\u0172\7n\2\2\u0172\u0173\7g\2\2\u0173\u0174") + buf.write("\7p\2\2\u0174@\3\2\2\2\u0175\u0176\7v\2\2\u0176\u0177") + buf.write("\7{\2\2\u0177\u0178\7r\2\2\u0178\u0179\7g\2\2\u0179B\3") + buf.write("\2\2\2\u017a\u017b\7u\2\2\u017b\u017c\7v\2\2\u017c\u017d") + buf.write("\7t\2\2\u017dD\3\2\2\2\u017e\u017f\7c\2\2\u017f\u0180") + buf.write("\7p\2\2\u0180\u0181\7{\2\2\u0181F\3\2\2\2\u0182\u0183") + buf.write("\7c\2\2\u0183\u0184\7n\2\2\u0184\u0185\7n\2\2\u0185H\3") + buf.write("\2\2\2\u0186\u0187\7m\2\2\u0187\u0188\7g\2\2\u0188\u0189") + buf.write("\7{\2\2\u0189\u018a\7u\2\2\u018aJ\3\2\2\2\u018b\u018c") + buf.write("\7j\2\2\u018c\u018d\7c\2\2\u018d\u018e\7u\2\2\u018e\u018f") + buf.write("\7j\2\2\u018fL\3\2\2\2\u0190\u0191\7e\2\2\u0191\u0192") + buf.write("\7j\2\2\u0192\u0193\7q\2\2\u0193\u0194\7q\2\2\u0194\u0195") + buf.write("\7u\2\2\u0195\u0196\7g\2\2\u0196N\3\2\2\2\u0197\u0198") + buf.write("\7g\2\2\u0198\u0199\7p\2\2\u0199\u019a\7f\2\2\u019aP\3") + buf.write("\2\2\2\u019b\u019c\7c\2\2\u019c\u019d\7p\2\2\u019d\u019e") + buf.write("\7f\2\2\u019e\u019f\7?\2\2\u019fR\3\2\2\2\u01a0\u01a1") + buf.write("\7q\2\2\u01a1\u01a2\7t\2\2\u01a2\u01a3\7?\2\2\u01a3T\3") + buf.write("\2\2\2\u01a4\u01a5\7?\2\2\u01a5\u01a6\7@\2\2\u01a6\u01a7") + buf.write("\7?\2\2\u01a7V\3\2\2\2\u01a8\u01a9\7(\2\2\u01a9\u01aa") + buf.write("\7?\2\2\u01aaX\3\2\2\2\u01ab\u01ac\7~\2\2\u01ac\u01ad") + buf.write("\7?\2\2\u01adZ\3\2\2\2\u01ae\u01af\7`\2\2\u01af\u01b0") + buf.write("\7?\2\2\u01b0\\\3\2\2\2\u01b1\u01b2\7/\2\2\u01b2\u01b3") + buf.write("\7?\2\2\u01b3^\3\2\2\2\u01b4\u01b5\7-\2\2\u01b5\u01b6") + buf.write("\7?\2\2\u01b6`\3\2\2\2\u01b7\u01b8\7,\2\2\u01b8\u01b9") + buf.write("\7?\2\2\u01b9b\3\2\2\2\u01ba\u01bb\7\61\2\2\u01bb\u01bc") + buf.write("\7?\2\2\u01bcd\3\2\2\2\u01bd\u01be\7\61\2\2\u01be\u01bf") + buf.write("\7\61\2\2\u01bf\u01c0\7?\2\2\u01c0f\3\2\2\2\u01c1\u01c2") + buf.write("\7\'\2\2\u01c2\u01c3\7?\2\2\u01c3h\3\2\2\2\u01c4\u01c5") + buf.write("\7o\2\2\u01c5\u01c6\7q\2\2\u01c6\u01c7\7f\2\2\u01c7\u01c8") + buf.write("\7?\2\2\u01c8j\3\2\2\2\u01c9\u01ca\7,\2\2\u01ca\u01cb") + buf.write("\7,\2\2\u01cb\u01cc\7?\2\2\u01ccl\3\2\2\2\u01cd\u01ce") + buf.write("\7@\2\2\u01ce\u01cf\7@\2\2\u01cf\u01d0\7?\2\2\u01d0n\3") + buf.write("\2\2\2\u01d1\u01d3\7\17\2\2\u01d2\u01d1\3\2\2\2\u01d2") + buf.write("\u01d3\3\2\2\2\u01d3\u01d4\3\2\2\2\u01d4\u01e1\7\f\2\2") + buf.write("\u01d5\u01d7\7\"\2\2\u01d6\u01d5\3\2\2\2\u01d7\u01da\3") + buf.write("\2\2\2\u01d8\u01d6\3\2\2\2\u01d8\u01d9\3\2\2\2\u01d9\u01e2") + buf.write("\3\2\2\2\u01da\u01d8\3\2\2\2\u01db\u01dd\7\13\2\2\u01dc") + buf.write("\u01db\3\2\2\2\u01dd\u01e0\3\2\2\2\u01de\u01dc\3\2\2\2") + buf.write("\u01de\u01df\3\2\2\2\u01df\u01e2\3\2\2\2\u01e0\u01de\3") + buf.write("\2\2\2\u01e1\u01d8\3\2\2\2\u01e1\u01de\3\2\2\2\u01e2\u01e3") + buf.write("\3\2\2\2\u01e3\u01e4\b8\2\2\u01e4p\3\2\2\2\u01e5\u01e7") + buf.write("\7\"\2\2\u01e6\u01e5\3\2\2\2\u01e7\u01e8\3\2\2\2\u01e8") + buf.write("\u01e6\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01f3\3\2\2\2") + buf.write("\u01ea\u01ec\7\13\2\2\u01eb\u01ea\3\2\2\2\u01ec\u01ed") + buf.write("\3\2\2\2\u01ed\u01eb\3\2\2\2\u01ed\u01ee\3\2\2\2\u01ee") + buf.write("\u01f3\3\2\2\2\u01ef\u01f0\7^\2\2\u01f0\u01f3\5o8\2\u01f1") + buf.write("\u01f3\5s:\2\u01f2\u01e6\3\2\2\2\u01f2\u01eb\3\2\2\2\u01f2") + buf.write("\u01ef\3\2\2\2\u01f2\u01f1\3\2\2\2\u01f3\u01f4\3\2\2\2") + buf.write("\u01f4\u01f5\b9\3\2\u01f5r\3\2\2\2\u01f6\u01fa\5w<\2\u01f7") + buf.write("\u01f9\13\2\2\2\u01f8\u01f7\3\2\2\2\u01f9\u01fc\3\2\2") + buf.write("\2\u01fa\u01fb\3\2\2\2\u01fa\u01f8\3\2\2\2\u01fb\u01fd") + buf.write("\3\2\2\2\u01fc\u01fa\3\2\2\2\u01fd\u01fe\5y=\2\u01fe\u0207") + buf.write("\3\2\2\2\u01ff\u0203\5u;\2\u0200\u0202\n\2\2\2\u0201\u0200") + buf.write("\3\2\2\2\u0202\u0205\3\2\2\2\u0203\u0201\3\2\2\2\u0203") + buf.write("\u0204\3\2\2\2\u0204\u0207\3\2\2\2\u0205\u0203\3\2\2\2") + buf.write("\u0206\u01f6\3\2\2\2\u0206\u01ff\3\2\2\2\u0207t\3\2\2") + buf.write("\2\u0208\u0209\7%\2\2\u0209v\3\2\2\2\u020a\u020b\7*\2") + buf.write("\2\u020b\u020c\7,\2\2\u020cx\3\2\2\2\u020d\u020e\7,\2") + buf.write("\2\u020e\u020f\7+\2\2\u020fz\3\2\2\2\u0210\u0211\7#\2") + buf.write("\2\u0211|\3\2\2\2\u0212\u0213\7,\2\2\u0213~\3\2\2\2\u0214") + buf.write("\u0215\7c\2\2\u0215\u0216\7u\2\2\u0216\u0080\3\2\2\2\u0217") + buf.write("\u0218\7\60\2\2\u0218\u0082\3\2\2\2\u0219\u021a\7k\2\2") + buf.write("\u021a\u021b\7o\2\2\u021b\u021c\7r\2\2\u021c\u021d\7q") + buf.write("\2\2\u021d\u021e\7t\2\2\u021e\u021f\7v\2\2\u021f\u0084") + buf.write("\3\2\2\2\u0220\u0221\7r\2\2\u0221\u0222\7t\2\2\u0222\u0223") + buf.write("\7k\2\2\u0223\u0224\7p\2\2\u0224\u0225\7v\2\2\u0225\u0086") + buf.write("\3\2\2\2\u0226\u0227\7h\2\2\u0227\u0228\7t\2\2\u0228\u0229") + buf.write("\7q\2\2\u0229\u022a\7o\2\2\u022a\u0088\3\2\2\2\u022b\u022c") + buf.write("\7\60\2\2\u022c\u022d\7\60\2\2\u022d\u008a\3\2\2\2\u022e") + buf.write("\u022f\7u\2\2\u022f\u0230\7g\2\2\u0230\u0231\7v\2\2\u0231") + buf.write("\u0232\7k\2\2\u0232\u0233\7p\2\2\u0233\u0234\7v\2\2\u0234") + buf.write("\u0235\7n\2\2\u0235\u0236\7g\2\2\u0236\u0237\7x\2\2\u0237") + buf.write("\u0238\7g\2\2\u0238\u0239\7n\2\2\u0239\u008c\3\2\2\2\u023a") + buf.write("\u023b\7/\2\2\u023b\u023c\7@\2\2\u023c\u008e\3\2\2\2\u023d") + buf.write("\u023e\7u\2\2\u023e\u023f\7c\2\2\u023f\u0240\7x\2\2\u0240") + buf.write("\u0241\7g\2\2\u0241\u0090\3\2\2\2\u0242\u0243\7u\2\2\u0243") + buf.write("\u0244\7v\2\2\u0244\u0245\7q\2\2\u0245\u0246\7r\2\2\u0246") + buf.write("\u0092\3\2\2\2\u0247\u0248\7n\2\2\u0248\u0249\7c\2\2\u0249") + buf.write("\u024a\7o\2\2\u024a\u024b\7d\2\2\u024b\u024c\7f\2\2\u024c") + buf.write("\u024d\7c\2\2\u024d\u0094\3\2\2\2\u024e\u024f\7A\2\2\u024f") + buf.write("\u0096\3\2\2\2\u0250\u0251\7p\2\2\u0251\u0252\7q\2\2\u0252") + buf.write("\u0253\7v\2\2\u0253\u0098\3\2\2\2\u0254\u0255\7.\2\2\u0255") + buf.write("\u009a\3\2\2\2\u0256\u0257\7e\2\2\u0257\u0258\7q\2\2\u0258") + buf.write("\u0259\7p\2\2\u0259\u025a\7u\2\2\u025a\u025b\7v\2\2\u025b") + buf.write("\u009c\3\2\2\2\u025c\u025d\7c\2\2\u025d\u025e\7y\2\2\u025e") + buf.write("\u025f\7c\2\2\u025f\u0260\7k\2\2\u0260\u0261\7v\2\2\u0261") + buf.write("\u009e\3\2\2\2\u0262\u0263\7c\2\2\u0263\u0264\7u\2\2\u0264") + buf.write("\u0265\7u\2\2\u0265\u0266\7g\2\2\u0266\u0267\7t\2\2\u0267") + buf.write("\u0268\7v\2\2\u0268\u00a0\3\2\2\2\u0269\u026a\7x\2\2\u026a") + buf.write("\u026b\7c\2\2\u026b\u026c\7t\2\2\u026c\u00a2\3\2\2\2\u026d") + buf.write("\u026e\7v\2\2\u026e\u026f\7t\2\2\u026f\u0270\7c\2\2\u0270") + buf.write("\u0271\7r\2\2\u0271\u00a4\3\2\2\2\u0272\u0273\7r\2\2\u0273") + buf.write("\u0274\7c\2\2\u0274\u0275\7u\2\2\u0275\u0276\7u\2\2\u0276") + buf.write("\u00a6\3\2\2\2\u0277\u0278\7f\2\2\u0278\u0279\7g\2\2\u0279") + buf.write("\u027a\7n\2\2\u027a\u00a8\3\2\2\2\u027b\u027c\7u\2\2\u027c") + buf.write("\u027d\7r\2\2\u027d\u027e\7c\2\2\u027e\u027f\7y\2\2\u027f") + buf.write("\u0280\7p\2\2\u0280\u00aa\3\2\2\2\u0281\u0282\7k\2\2\u0282") + buf.write("\u0283\7p\2\2\u0283\u0284\7x\2\2\u0284\u0285\7c\2\2\u0285") + buf.write("\u0286\7t\2\2\u0286\u0287\7k\2\2\u0287\u0288\7c\2\2\u0288") + buf.write("\u0289\7p\2\2\u0289\u028a\7v\2\2\u028a\u00ac\3\2\2\2\u028b") + buf.write("\u028c\7i\2\2\u028c\u028d\7q\2\2\u028d\u00ae\3\2\2\2\u028e") + buf.write("\u028f\7u\2\2\u028f\u0290\7g\2\2\u0290\u0291\7s\2\2\u0291") + buf.write("\u0292\7w\2\2\u0292\u0293\7g\2\2\u0293\u0294\7p\2\2\u0294") + buf.write("\u0295\7v\2\2\u0295\u0296\7k\2\2\u0296\u0297\7c\2\2\u0297") + buf.write("\u0298\7n\2\2\u0298\u00b0\3\2\2\2\u0299\u029a\7y\2\2\u029a") + buf.write("\u029b\7j\2\2\u029b\u029c\7g\2\2\u029c\u029d\7p\2\2\u029d") + buf.write("\u00b2\3\2\2\2\u029e\u029f\7n\2\2\u029f\u02a0\7g\2\2\u02a0") + buf.write("\u02a1\7v\2\2\u02a1\u00b4\3\2\2\2\u02a2\u02a3\7k\2\2\u02a3") + buf.write("\u02a4\7h\2\2\u02a4\u00b6\3\2\2\2\u02a5\u02a6\7g\2\2\u02a6") + buf.write("\u02a7\7n\2\2\u02a7\u02a8\7k\2\2\u02a8\u02a9\7h\2\2\u02a9") + buf.write("\u00b8\3\2\2\2\u02aa\u02ab\7g\2\2\u02ab\u02ac\7n\2\2\u02ac") + buf.write("\u02ad\7u\2\2\u02ad\u02ae\7g\2\2\u02ae\u00ba\3\2\2\2\u02af") + buf.write("\u02b0\7B\2\2\u02b0\u00bc\3\2\2\2\u02b1\u02b2\7y\2\2\u02b2") + buf.write("\u02b3\7j\2\2\u02b3\u02b4\7k\2\2\u02b4\u02b5\7n\2\2\u02b5") + buf.write("\u02b6\7g\2\2\u02b6\u00be\3\2\2\2\u02b7\u02b8\7f\2\2\u02b8") + buf.write("\u02b9\7g\2\2\u02b9\u02ba\7h\2\2\u02ba\u00c0\3\2\2\2\u02bb") + buf.write("\u02bc\7g\2\2\u02bc\u02bd\7z\2\2\u02bd\u02be\7k\2\2\u02be") + buf.write("\u02bf\7u\2\2\u02bf\u02c0\7v\2\2\u02c0\u02c1\7u\2\2\u02c1") + buf.write("\u00c2\3\2\2\2\u02c2\u02c3\7y\2\2\u02c3\u02c4\7j\2\2\u02c4") + buf.write("\u02c5\7g\2\2\u02c5\u02c6\7t\2\2\u02c6\u02c7\7g\2\2\u02c7") + buf.write("\u00c4\3\2\2\2\u02c8\u02c9\7?\2\2\u02c9\u00c6\3\2\2\2") + buf.write("\u02ca\u02cb\7h\2\2\u02cb\u02cc\7q\2\2\u02cc\u02cd\7t") + buf.write("\2\2\u02cd\u02ce\3\2\2\2\u02ce\u02cf\bd\4\2\u02cf\u00c8") + buf.write("\3\2\2\2\u02d0\u02d1\7k\2\2\u02d1\u02d2\7p\2\2\u02d2\u02d3") + buf.write("\3\2\2\2\u02d3\u02d4\be\5\2\u02d4\u00ca\3\2\2\2\u02d5") + buf.write("\u02d6\7<\2\2\u02d6\u00cc\3\2\2\2\u02d7\u02d8\7P\2\2\u02d8") + buf.write("\u02d9\7q\2\2\u02d9\u02da\7p\2\2\u02da\u02db\7g\2\2\u02db") + buf.write("\u00ce\3\2\2\2\u02dc\u02dd\7c\2\2\u02dd\u02de\7v\2\2\u02de") + buf.write("\u02df\7q\2\2\u02df\u02e0\7o\2\2\u02e0\u02e1\7k\2\2\u02e1") + buf.write("\u02e2\7e\2\2\u02e2\u02e3\7c\2\2\u02e3\u02e4\7n\2\2\u02e4") + buf.write("\u02e5\7n\2\2\u02e5\u02e6\7{\2\2\u02e6\u00d0\3\2\2\2\u02e7") + buf.write("\u02e8\7H\2\2\u02e8\u02e9\7c\2\2\u02e9\u02ea\7n\2\2\u02ea") + buf.write("\u02eb\7u\2\2\u02eb\u02f1\7g\2\2\u02ec\u02ed\7V\2\2\u02ed") + buf.write("\u02ee\7t\2\2\u02ee\u02ef\7w\2\2\u02ef\u02f1\7g\2\2\u02f0") + buf.write("\u02e7\3\2\2\2\u02f0\u02ec\3\2\2\2\u02f1\u00d2\3\2\2\2") + buf.write("\u02f2\u02f3\7g\2\2\u02f3\u02f4\7v\2\2\u02f4\u02f5\7g") + buf.write("\2\2\u02f5\u02f6\7t\2\2\u02f6\u02f7\7p\2\2\u02f7\u02f8") + buf.write("\7c\2\2\u02f8\u02f9\7n\2\2\u02f9\u00d4\3\2\2\2\u02fa\u02fb") + buf.write("\7j\2\2\u02fb\u02fc\7{\2\2\u02fc\u02fd\7r\2\2\u02fd\u02fe") + buf.write("\7g\2\2\u02fe\u02ff\7t\2\2\u02ff\u0300\7a\2\2\u0300\u0301") + buf.write("\7c\2\2\u0301\u0302\7u\2\2\u0302\u0303\7u\2\2\u0303\u0304") + buf.write("\7g\2\2\u0304\u0305\7t\2\2\u0305\u0306\7v\2\2\u0306\u00d6") + buf.write("\3\2\2\2\u0307\u0309\t\3\2\2\u0308\u0307\3\2\2\2\u0309") + buf.write("\u030a\3\2\2\2\u030a\u0308\3\2\2\2\u030a\u030b\3\2\2\2") + buf.write("\u030b\u0310\3\2\2\2\u030c\u030d\7k\2\2\u030d\u030e\7") + buf.write("p\2\2\u030e\u0310\7h\2\2\u030f\u0308\3\2\2\2\u030f\u030c") + buf.write("\3\2\2\2\u0310\u00d8\3\2\2\2\u0311\u0315\t\4\2\2\u0312") + buf.write("\u0314\t\5\2\2\u0313\u0312\3\2\2\2\u0314\u0317\3\2\2\2") + buf.write("\u0315\u0313\3\2\2\2\u0315\u0316\3\2\2\2\u0316\u00da\3") + buf.write("\2\2\2\u0317\u0315\3\2\2\2\u0318\u031b\t\6\2\2\u0319\u031c") + buf.write("\5\u00ddo\2\u031a\u031c\5\u00d9m\2\u031b\u0319\3\2\2\2") + buf.write("\u031b\u031a\3\2\2\2\u031c\u00dc\3\2\2\2\u031d\u031e\7") + buf.write("\62\2\2\u031e\u031f\7Z\2\2\u031f\u0321\3\2\2\2\u0320\u0322") + buf.write("\5\u00dfp\2\u0321\u0320\3\2\2\2\u0322\u0323\3\2\2\2\u0323") + buf.write("\u0321\3\2\2\2\u0323\u0324\3\2\2\2\u0324\u00de\3\2\2\2") + buf.write("\u0325\u0326\t\7\2\2\u0326\u00e0\3\2\2\2\u0327\u0328\7") + buf.write("]\2\2\u0328\u0329\bq\6\2\u0329\u00e2\3\2\2\2\u032a\u032b") + buf.write("\7_\2\2\u032b\u032c\br\7\2\u032c\u00e4\3\2\2\2\u032d\u032e") + buf.write("\7}\2\2\u032e\u032f\bs\b\2\u032f\u00e6\3\2\2\2\u0330\u0331") + buf.write("\7\177\2\2\u0331\u0332\bt\t\2\u0332\u00e8\3\2\2\2\u0333") + buf.write("\u0334\7*\2\2\u0334\u0335\bu\n\2\u0335\u00ea\3\2\2\2\u0336") + buf.write("\u0337\7+\2\2\u0337\u0338\bv\13\2\u0338\u00ec\3\2\2\2") + buf.write("\u0339\u033a\7=\2\2\u033a\u00ee\3\2\2\2\u033b\u033e\5") + buf.write("\u00f1y\2\u033c\u033e\5\u00f3z\2\u033d\u033b\3\2\2\2\u033d") + buf.write("\u033c\3\2\2\2\u033e\u00f0\3\2\2\2\u033f\u0344\7)\2\2") + buf.write("\u0340\u0343\5\u00f9}\2\u0341\u0343\n\b\2\2\u0342\u0340") + buf.write("\3\2\2\2\u0342\u0341\3\2\2\2\u0343\u0346\3\2\2\2\u0344") + buf.write("\u0342\3\2\2\2\u0344\u0345\3\2\2\2\u0345\u0347\3\2\2\2") + buf.write("\u0346\u0344\3\2\2\2\u0347\u0352\7)\2\2\u0348\u034d\7") + buf.write("$\2\2\u0349\u034c\5\u00f9}\2\u034a\u034c\n\t\2\2\u034b") + buf.write("\u0349\3\2\2\2\u034b\u034a\3\2\2\2\u034c\u034f\3\2\2\2") + buf.write("\u034d\u034b\3\2\2\2\u034d\u034e\3\2\2\2\u034e\u0350\3") + buf.write("\2\2\2\u034f\u034d\3\2\2\2\u0350\u0352\7$\2\2\u0351\u033f") + buf.write("\3\2\2\2\u0351\u0348\3\2\2\2\u0352\u00f2\3\2\2\2\u0353") + buf.write("\u0354\7)\2\2\u0354\u0355\7)\2\2\u0355\u0356\7)\2\2\u0356") + buf.write("\u035a\3\2\2\2\u0357\u0359\5\u00f5{\2\u0358\u0357\3\2") + buf.write("\2\2\u0359\u035c\3\2\2\2\u035a\u035b\3\2\2\2\u035a\u0358") + buf.write("\3\2\2\2\u035b\u035d\3\2\2\2\u035c\u035a\3\2\2\2\u035d") + buf.write("\u035e\7)\2\2\u035e\u035f\7)\2\2\u035f\u036e\7)\2\2\u0360") + buf.write("\u0361\7$\2\2\u0361\u0362\7$\2\2\u0362\u0363\7$\2\2\u0363") + buf.write("\u0367\3\2\2\2\u0364\u0366\5\u00f5{\2\u0365\u0364\3\2") + buf.write("\2\2\u0366\u0369\3\2\2\2\u0367\u0368\3\2\2\2\u0367\u0365") + buf.write("\3\2\2\2\u0368\u036a\3\2\2\2\u0369\u0367\3\2\2\2\u036a") + buf.write("\u036b\7$\2\2\u036b\u036c\7$\2\2\u036c\u036e\7$\2\2\u036d") + buf.write("\u0353\3\2\2\2\u036d\u0360\3\2\2\2\u036e\u00f4\3\2\2\2") + buf.write("\u036f\u0372\5\u00f7|\2\u0370\u0372\5\u00f9}\2\u0371\u036f") + buf.write("\3\2\2\2\u0371\u0370\3\2\2\2\u0372\u00f6\3\2\2\2\u0373") + buf.write("\u0374\n\n\2\2\u0374\u00f8\3\2\2\2\u0375\u0376\7^\2\2") + buf.write("\u0376\u037a\13\2\2\2\u0377\u0378\7^\2\2\u0378\u037a\5") + buf.write("o8\2\u0379\u0375\3\2\2\2\u0379\u0377\3\2\2\2\u037a\u00fa") + buf.write("\3\2\2\2\36\2\u01d2\u01d8\u01de\u01e1\u01e8\u01ed\u01f2") + buf.write("\u01fa\u0203\u0206\u02f0\u030a\u030f\u0315\u031b\u0323") + buf.write("\u033d\u0342\u0344\u034b\u034d\u0351\u035a\u0367\u036d") + buf.write("\u0371\u0379\f\38\2\b\2\2\3d\3\3e\4\3q\5\3r\6\3s\7\3t") + buf.write("\b\3u\t\3v\n") return buf.getvalue() @@ -503,18 +509,19 @@ class HarmonyLexer(Lexer): ATOMICALLY = 102 BOOL = 103 ETERNAL = 104 - INT = 105 - NAME = 106 - ATOM = 107 - HEX_INTEGER = 108 - OPEN_BRACK = 109 - CLOSE_BRACK = 110 - OPEN_BRACES = 111 - CLOSE_BRACES = 112 - OPEN_PAREN = 113 - CLOSE_PAREN = 114 - SEMI_COLON = 115 - STRING = 116 + HYPER = 105 + INT = 106 + NAME = 107 + ATOM = 108 + HEX_INTEGER = 109 + OPEN_BRACK = 110 + CLOSE_BRACK = 111 + OPEN_BRACES = 112 + CLOSE_BRACES = 113 + OPEN_PAREN = 114 + CLOSE_PAREN = 115 + SEMI_COLON = 116 + STRING = 117 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] @@ -536,7 +543,8 @@ class HarmonyLexer(Lexer): "'go'", "'sequential'", "'when'", "'let'", "'if'", "'elif'", "'else'", "'@'", "'while'", "'def'", "'exists'", "'where'", "'='", "'for'", "'in'", "':'", "'None'", "'atomically'", "'eternal'", - "'['", "']'", "'{'", "'}'", "'('", "')'", "';'" ] + "'hyper_assert'", "'['", "']'", "'{'", "'}'", "'('", "')'", + "';'" ] symbolicNames = [ "", "NL", "WS", "COMMENT_START", "OPEN_MULTI_COMMENT", "CLOSE_MULTI_COMMENT", @@ -546,9 +554,9 @@ class HarmonyLexer(Lexer): "DEL", "SPAWN", "INVARIANT", "GO", "SEQUENTIAL", "WHEN", "LET", "IF", "ELIF", "ELSE", "AT", "WHILE", "DEF", "EXISTS", "WHERE", "EQ", "FOR", "IN", "COLON", "NONE", "ATOMICALLY", "BOOL", "ETERNAL", - "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", "CLOSE_BRACK", - "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", "CLOSE_PAREN", - "SEMI_COLON", "STRING" ] + "HYPER", "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", + "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", + "CLOSE_PAREN", "SEMI_COLON", "STRING" ] ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13", @@ -567,9 +575,9 @@ class HarmonyLexer(Lexer): "GO", "SEQUENTIAL", "WHEN", "LET", "IF", "ELIF", "ELSE", "AT", "WHILE", "DEF", "EXISTS", "WHERE", "EQ", "FOR", "IN", "COLON", "NONE", "ATOMICALLY", "BOOL", "ETERNAL", - "INT", "NAME", "ATOM", "HEX_INTEGER", "HEX_DIGIT", "OPEN_BRACK", - "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", - "CLOSE_PAREN", "SEMI_COLON", "STRING", "SHORT_STRING", + "HYPER", "INT", "NAME", "ATOM", "HEX_INTEGER", "HEX_DIGIT", + "OPEN_BRACK", "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", + "OPEN_PAREN", "CLOSE_PAREN", "SEMI_COLON", "STRING", "SHORT_STRING", "LONG_STRING", "LONG_STRING_ITEM", "LONG_STRING_CHAR", "STRING_ESCAPE_SEQ" ] @@ -609,12 +617,12 @@ def action(self, localctx:RuleContext, ruleIndex:int, actionIndex:int): actions[54] = self.NL_action actions[98] = self.FOR_action actions[99] = self.IN_action - actions[110] = self.OPEN_BRACK_action - actions[111] = self.CLOSE_BRACK_action - actions[112] = self.OPEN_BRACES_action - actions[113] = self.CLOSE_BRACES_action - actions[114] = self.OPEN_PAREN_action - actions[115] = self.CLOSE_PAREN_action + actions[111] = self.OPEN_BRACK_action + actions[112] = self.CLOSE_BRACK_action + actions[113] = self.OPEN_BRACES_action + actions[114] = self.CLOSE_BRACES_action + actions[115] = self.OPEN_PAREN_action + actions[116] = self.CLOSE_PAREN_action self._actions = actions action = self._actions.get(ruleIndex, None) if action is not None: diff --git a/harmony_model_checker/parser/HarmonyParser.py b/harmony_model_checker/parser/HarmonyParser.py index 1c91d7c5..8504f3ca 100644 --- a/harmony_model_checker/parser/HarmonyParser.py +++ b/harmony_model_checker/parser/HarmonyParser.py @@ -11,8 +11,8 @@ def serializedATN(): with StringIO() as buf: - buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3x") - buf.write("\u0236\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3y") + buf.write("\u0245\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31") @@ -20,267 +20,273 @@ def serializedATN(): buf.write("\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t") buf.write("&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4") buf.write("/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t\64") - buf.write("\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\3\2\7\2r\n\2\f\2") - buf.write("\16\2u\13\2\3\2\3\2\3\3\3\3\5\3{\n\3\3\3\5\3~\n\3\3\3") - buf.write("\3\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\5\5\u008a\n\5\3\6") - buf.write("\3\6\3\6\7\6\u008f\n\6\f\6\16\6\u0092\13\6\3\7\3\7\3\7") - buf.write("\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\5\7\u00a1\n\7") - buf.write("\3\b\3\b\3\b\7\b\u00a6\n\b\f\b\16\b\u00a9\13\b\3\b\3\b") - buf.write("\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f") - buf.write("\3\f\5\f\u00bb\n\f\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00c3\n") - buf.write("\f\3\f\3\f\3\f\5\f\u00c8\n\f\3\f\3\f\3\f\5\f\u00cd\n\f") - buf.write("\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\7\r\u00d8\n\r\f\r") - buf.write("\16\r\u00db\13\r\5\r\u00dd\n\r\3\r\3\r\3\r\3\r\3\r\7\r") - buf.write("\u00e4\n\r\f\r\16\r\u00e7\13\r\5\r\u00e9\n\r\3\16\3\16") - buf.write("\3\16\7\16\u00ee\n\16\f\16\16\16\u00f1\13\16\3\17\3\17") - buf.write("\3\17\3\17\3\17\3\17\5\17\u00f9\n\17\3\17\3\17\3\17\3") - buf.write("\20\3\20\3\20\3\21\3\21\3\21\3\21\7\21\u0105\n\21\f\21") - buf.write("\16\21\u0108\13\21\3\21\5\21\u010b\n\21\5\21\u010d\n\21") - buf.write("\3\22\3\22\5\22\u0111\n\22\3\22\3\22\3\22\3\22\3\22\7") - buf.write("\22\u0118\n\22\f\22\16\22\u011b\13\22\3\22\3\22\3\22\3") - buf.write("\22\3\22\3\22\3\22\3\22\7\22\u0125\n\22\f\22\16\22\u0128") - buf.write("\13\22\5\22\u012a\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3") - buf.write("\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23") - buf.write("\3\23\5\23\u013e\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3") - buf.write("\24\3\24\7\24\u0148\n\24\f\24\16\24\u014b\13\24\3\25\3") - buf.write("\25\3\26\3\26\3\27\3\27\3\30\3\30\3\30\6\30\u0156\n\30") - buf.write("\r\30\16\30\u0157\3\30\3\30\3\31\3\31\3\31\3\31\3\32\3") - buf.write("\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\5\33\u0169\n\33") - buf.write("\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36") - buf.write("\3\37\3\37\3 \3 \3 \3!\3!\3!\3\"\3\"\5\"\u0180\n\"\3\"") - buf.write("\3\"\3#\3#\3#\3#\3$\3$\3$\3%\3%\3%\3%\7%\u018f\n%\f%\16") - buf.write("%\u0192\13%\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3") - buf.write("(\5(\u01a1\n(\3)\3)\3)\3)\3)\3)\3)\5)\u01aa\n)\3)\5)\u01ad") - buf.write("\n)\3*\3*\5*\u01b1\n*\3*\5*\u01b4\n*\3+\3+\3+\3+\3,\3") - buf.write(",\3,\3,\3,\3,\3-\3-\3-\3-\3-\3.\3.\3.\3.\3.\3/\3/\3/\3") - buf.write("/\3\60\3\60\3\60\3\60\3\60\7\60\u01d3\n\60\f\60\16\60") - buf.write("\u01d6\13\60\3\60\5\60\u01d9\n\60\3\61\6\61\u01dc\n\61") - buf.write("\r\61\16\61\u01dd\3\62\3\62\5\62\u01e2\n\62\3\63\3\63") - buf.write("\3\63\3\63\5\63\u01e8\n\63\3\63\3\63\3\63\5\63\u01ed\n") - buf.write("\63\3\64\5\64\u01f0\n\64\3\64\3\64\3\64\3\64\3\64\3\64") - buf.write("\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\3\64\5\64\u0201") - buf.write("\n\64\3\65\5\65\u0204\n\65\3\65\3\65\3\65\3\65\3\65\3") - buf.write("\65\5\65\u020c\n\65\3\66\3\66\5\66\u0210\n\66\3\66\3\66") - buf.write("\3\66\5\66\u0215\n\66\3\67\3\67\6\67\u0219\n\67\r\67\16") - buf.write("\67\u021a\38\58\u021e\n8\38\58\u0221\n8\38\78\u0224\n") - buf.write("8\f8\168\u0227\138\38\38\38\38\58\u022d\n8\38\38\58\u0231") - buf.write("\n8\38\58\u0234\n8\38\2\3&9\2\4\6\b\n\f\16\20\22\24\26") - buf.write("\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\") - buf.write("^`bdfhjln\2\6\4\2\3\21??\3\2\22\27\5\2\t\t\30(LL\3\2*") - buf.write("8\2\u025e\2s\3\2\2\2\4z\3\2\2\2\6\u0081\3\2\2\2\b\u0084") - buf.write("\3\2\2\2\n\u008b\3\2\2\2\f\u00a0\3\2\2\2\16\u00a7\3\2") - buf.write("\2\2\20\u00ac\3\2\2\2\22\u00ae\3\2\2\2\24\u00b0\3\2\2") - buf.write("\2\26\u00cc\3\2\2\2\30\u00ce\3\2\2\2\32\u00ea\3\2\2\2") - buf.write("\34\u00f2\3\2\2\2\36\u00fd\3\2\2\2 \u0100\3\2\2\2\"\u010e") - buf.write("\3\2\2\2$\u013d\3\2\2\2&\u013f\3\2\2\2(\u014c\3\2\2\2") - buf.write("*\u014e\3\2\2\2,\u0150\3\2\2\2.\u0155\3\2\2\2\60\u015b") - buf.write("\3\2\2\2\62\u015f\3\2\2\2\64\u0164\3\2\2\2\66\u016a\3") - buf.write("\2\2\28\u016d\3\2\2\2:\u0172\3\2\2\2<\u0175\3\2\2\2>\u0177") - buf.write("\3\2\2\2@\u017a\3\2\2\2B\u017d\3\2\2\2D\u0183\3\2\2\2") - buf.write("F\u0187\3\2\2\2H\u018a\3\2\2\2J\u0193\3\2\2\2L\u0197\3") - buf.write("\2\2\2N\u019b\3\2\2\2P\u01a2\3\2\2\2R\u01b0\3\2\2\2T\u01b5") - buf.write("\3\2\2\2V\u01b9\3\2\2\2X\u01bf\3\2\2\2Z\u01c4\3\2\2\2") - buf.write("\\\u01c9\3\2\2\2^\u01cd\3\2\2\2`\u01db\3\2\2\2b\u01e1") - buf.write("\3\2\2\2d\u01e3\3\2\2\2f\u01ef\3\2\2\2h\u0203\3\2\2\2") - buf.write("j\u020d\3\2\2\2l\u0218\3\2\2\2n\u0233\3\2\2\2pr\5n8\2") - buf.write("qp\3\2\2\2ru\3\2\2\2sq\3\2\2\2st\3\2\2\2tv\3\2\2\2us\3") - buf.write("\2\2\2vw\7\2\2\3w\3\3\2\2\2x{\5\6\4\2y{\5\b\5\2zx\3\2") - buf.write("\2\2zy\3\2\2\2{}\3\2\2\2|~\7u\2\2}|\3\2\2\2}~\3\2\2\2") - buf.write("~\177\3\2\2\2\177\u0080\79\2\2\u0080\5\3\2\2\2\u0081\u0082") - buf.write("\7B\2\2\u0082\u0083\5\n\6\2\u0083\7\3\2\2\2\u0084\u0085") - buf.write("\7D\2\2\u0085\u0086\7l\2\2\u0086\u0089\7B\2\2\u0087\u008a") - buf.write("\7?\2\2\u0088\u008a\5\n\6\2\u0089\u0087\3\2\2\2\u0089") - buf.write("\u0088\3\2\2\2\u008a\t\3\2\2\2\u008b\u0090\7l\2\2\u008c") - buf.write("\u008d\7M\2\2\u008d\u008f\7l\2\2\u008e\u008c\3\2\2\2\u008f") - buf.write("\u0092\3\2\2\2\u0090\u008e\3\2\2\2\u0090\u0091\3\2\2\2") - buf.write("\u0091\13\3\2\2\2\u0092\u0090\3\2\2\2\u0093\u00a1\7l\2") - buf.write("\2\u0094\u0095\7s\2\2\u0095\u0096\5\16\b\2\u0096\u0097") - buf.write("\7t\2\2\u0097\u00a1\3\2\2\2\u0098\u0099\7o\2\2\u0099\u009a") - buf.write("\5\16\b\2\u009a\u009b\7p\2\2\u009b\u00a1\3\2\2\2\u009c") - buf.write("\u009d\7s\2\2\u009d\u00a1\7t\2\2\u009e\u009f\7o\2\2\u009f") - buf.write("\u00a1\7p\2\2\u00a0\u0093\3\2\2\2\u00a0\u0094\3\2\2\2") - buf.write("\u00a0\u0098\3\2\2\2\u00a0\u009c\3\2\2\2\u00a0\u009e\3") - buf.write("\2\2\2\u00a1\r\3\2\2\2\u00a2\u00a3\5\f\7\2\u00a3\u00a4") - buf.write("\7M\2\2\u00a4\u00a6\3\2\2\2\u00a5\u00a2\3\2\2\2\u00a6") - buf.write("\u00a9\3\2\2\2\u00a7\u00a5\3\2\2\2\u00a7\u00a8\3\2\2\2") - buf.write("\u00a8\u00aa\3\2\2\2\u00a9\u00a7\3\2\2\2\u00aa\u00ab\5") - buf.write("\f\7\2\u00ab\17\3\2\2\2\u00ac\u00ad\t\2\2\2\u00ad\21\3") - buf.write("\2\2\2\u00ae\u00af\t\3\2\2\u00af\23\3\2\2\2\u00b0\u00b1") - buf.write("\t\4\2\2\u00b1\25\3\2\2\2\u00b2\u00cd\7k\2\2\u00b3\u00cd") - buf.write("\7i\2\2\u00b4\u00cd\7m\2\2\u00b5\u00cd\7l\2\2\u00b6\u00cd") - buf.write("\7v\2\2\u00b7\u00cd\7g\2\2\u00b8\u00ba\7q\2\2\u00b9\u00bb") - buf.write("\5\30\r\2\u00ba\u00b9\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb") - buf.write("\u00bc\3\2\2\2\u00bc\u00cd\7r\2\2\u00bd\u00be\7q\2\2\u00be") - buf.write("\u00bf\7f\2\2\u00bf\u00cd\7r\2\2\u00c0\u00c2\7s\2\2\u00c1") - buf.write("\u00c3\5 \21\2\u00c2\u00c1\3\2\2\2\u00c2\u00c3\3\2\2\2") - buf.write("\u00c3\u00c4\3\2\2\2\u00c4\u00cd\7t\2\2\u00c5\u00c7\7") - buf.write("o\2\2\u00c6\u00c8\5 \21\2\u00c7\u00c6\3\2\2\2\u00c7\u00c8") - buf.write("\3\2\2\2\u00c8\u00c9\3\2\2\2\u00c9\u00cd\7p\2\2\u00ca") - buf.write("\u00cb\7K\2\2\u00cb\u00cd\5$\23\2\u00cc\u00b2\3\2\2\2") - buf.write("\u00cc\u00b3\3\2\2\2\u00cc\u00b4\3\2\2\2\u00cc\u00b5\3") - buf.write("\2\2\2\u00cc\u00b6\3\2\2\2\u00cc\u00b7\3\2\2\2\u00cc\u00b8") - buf.write("\3\2\2\2\u00cc\u00bd\3\2\2\2\u00cc\u00c0\3\2\2\2\u00cc") - buf.write("\u00c5\3\2\2\2\u00cc\u00ca\3\2\2\2\u00cd\27\3\2\2\2\u00ce") - buf.write("\u00e8\5\"\22\2\u00cf\u00d0\7f\2\2\u00d0\u00dc\5\"\22") - buf.write("\2\u00d1\u00dd\5\32\16\2\u00d2\u00d3\7M\2\2\u00d3\u00d4") - buf.write("\5\"\22\2\u00d4\u00d5\7f\2\2\u00d5\u00d6\5\"\22\2\u00d6") - buf.write("\u00d8\3\2\2\2\u00d7\u00d2\3\2\2\2\u00d8\u00db\3\2\2\2") - buf.write("\u00d9\u00d7\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u00dd\3") - buf.write("\2\2\2\u00db\u00d9\3\2\2\2\u00dc\u00d1\3\2\2\2\u00dc\u00d9") - buf.write("\3\2\2\2\u00dd\u00e9\3\2\2\2\u00de\u00e9\5\32\16\2\u00df") - buf.write("\u00e0\7E\2\2\u00e0\u00e9\5\"\22\2\u00e1\u00e2\7M\2\2") - buf.write("\u00e2\u00e4\5\"\22\2\u00e3\u00e1\3\2\2\2\u00e4\u00e7") - buf.write("\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6") - buf.write("\u00e9\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e8\u00cf\3\2\2\2") - buf.write("\u00e8\u00de\3\2\2\2\u00e8\u00df\3\2\2\2\u00e8\u00e5\3") - buf.write("\2\2\2\u00e9\31\3\2\2\2\u00ea\u00ef\5\34\17\2\u00eb\u00ee") - buf.write("\5\34\17\2\u00ec\u00ee\5\36\20\2\u00ed\u00eb\3\2\2\2\u00ed") - buf.write("\u00ec\3\2\2\2\u00ee\u00f1\3\2\2\2\u00ef\u00ed\3\2\2\2") - buf.write("\u00ef\u00f0\3\2\2\2\u00f0\33\3\2\2\2\u00f1\u00ef\3\2") - buf.write("\2\2\u00f2\u00f8\7d\2\2\u00f3\u00f9\5\16\b\2\u00f4\u00f5") - buf.write("\5\16\b\2\u00f5\u00f6\7f\2\2\u00f6\u00f7\5\16\b\2\u00f7") - buf.write("\u00f9\3\2\2\2\u00f8\u00f3\3\2\2\2\u00f8\u00f4\3\2\2\2") - buf.write("\u00f9\u00fa\3\2\2\2\u00fa\u00fb\7e\2\2\u00fb\u00fc\5") - buf.write("\"\22\2\u00fc\35\3\2\2\2\u00fd\u00fe\7b\2\2\u00fe\u00ff") - buf.write("\5\"\22\2\u00ff\37\3\2\2\2\u0100\u010c\5\"\22\2\u0101") - buf.write("\u010d\5\32\16\2\u0102\u0103\7M\2\2\u0103\u0105\5\"\22") - buf.write("\2\u0104\u0102\3\2\2\2\u0105\u0108\3\2\2\2\u0106\u0104") - buf.write("\3\2\2\2\u0106\u0107\3\2\2\2\u0107\u010a\3\2\2\2\u0108") - buf.write("\u0106\3\2\2\2\u0109\u010b\7M\2\2\u010a\u0109\3\2\2\2") - buf.write("\u010a\u010b\3\2\2\2\u010b\u010d\3\2\2\2\u010c\u0101\3") - buf.write("\2\2\2\u010c\u0106\3\2\2\2\u010d!\3\2\2\2\u010e\u0129") - buf.write("\5$\23\2\u010f\u0111\7L\2\2\u0110\u010f\3\2\2\2\u0110") - buf.write("\u0111\3\2\2\2\u0111\u0112\3\2\2\2\u0112\u0113\7e\2\2") - buf.write("\u0113\u012a\5$\23\2\u0114\u0115\5\22\n\2\u0115\u0116") - buf.write("\5$\23\2\u0116\u0118\3\2\2\2\u0117\u0114\3\2\2\2\u0118") - buf.write("\u011b\3\2\2\2\u0119\u0117\3\2\2\2\u0119\u011a\3\2\2\2") - buf.write("\u011a\u012a\3\2\2\2\u011b\u0119\3\2\2\2\u011c\u011d\7") - buf.write("[\2\2\u011d\u011e\5\"\22\2\u011e\u011f\7]\2\2\u011f\u0120") - buf.write("\5$\23\2\u0120\u012a\3\2\2\2\u0121\u0122\5\20\t\2\u0122") - buf.write("\u0123\5$\23\2\u0123\u0125\3\2\2\2\u0124\u0121\3\2\2\2") - buf.write("\u0125\u0128\3\2\2\2\u0126\u0124\3\2\2\2\u0126\u0127\3") - buf.write("\2\2\2\u0127\u012a\3\2\2\2\u0128\u0126\3\2\2\2\u0129\u0110") - buf.write("\3\2\2\2\u0129\u0119\3\2\2\2\u0129\u011c\3\2\2\2\u0129") - buf.write("\u0126\3\2\2\2\u012a#\3\2\2\2\u012b\u012c\7J\2\2\u012c") - buf.write("\u012d\5\16\b\2\u012d\u012e\7f\2\2\u012e\u012f\5\"\22") - buf.write("\2\u012f\u0130\7)\2\2\u0130\u013e\3\2\2\2\u0131\u0132") - buf.write("\7F\2\2\u0132\u013e\5$\23\2\u0133\u0134\7H\2\2\u0134\u013e") - buf.write("\5$\23\2\u0135\u0136\7I\2\2\u0136\u013e\5$\23\2\u0137") - buf.write("\u0138\7>\2\2\u0138\u013e\5$\23\2\u0139\u013a\5\24\13") - buf.write("\2\u013a\u013b\5$\23\2\u013b\u013e\3\2\2\2\u013c\u013e") - buf.write("\5&\24\2\u013d\u012b\3\2\2\2\u013d\u0131\3\2\2\2\u013d") - buf.write("\u0133\3\2\2\2\u013d\u0135\3\2\2\2\u013d\u0137\3\2\2\2") - buf.write("\u013d\u0139\3\2\2\2\u013d\u013c\3\2\2\2\u013e%\3\2\2") - buf.write("\2\u013f\u0140\b\24\1\2\u0140\u0141\5\26\f\2\u0141\u0149") - buf.write("\3\2\2\2\u0142\u0143\f\4\2\2\u0143\u0144\7G\2\2\u0144") - buf.write("\u0148\7l\2\2\u0145\u0146\f\3\2\2\u0146\u0148\5\26\f\2") - buf.write("\u0147\u0142\3\2\2\2\u0147\u0145\3\2\2\2\u0148\u014b\3") - buf.write("\2\2\2\u0149\u0147\3\2\2\2\u0149\u014a\3\2\2\2\u014a\'") - buf.write("\3\2\2\2\u014b\u0149\3\2\2\2\u014c\u014d\5\"\22\2\u014d") - buf.write(")\3\2\2\2\u014e\u014f\t\5\2\2\u014f+\3\2\2\2\u0150\u0151") - buf.write("\5 \21\2\u0151-\3\2\2\2\u0152\u0153\5 \21\2\u0153\u0154") - buf.write("\7c\2\2\u0154\u0156\3\2\2\2\u0155\u0152\3\2\2\2\u0156") - buf.write("\u0157\3\2\2\2\u0157\u0155\3\2\2\2\u0157\u0158\3\2\2\2") - buf.write("\u0158\u0159\3\2\2\2\u0159\u015a\5 \21\2\u015a/\3\2\2") - buf.write("\2\u015b\u015c\5 \21\2\u015c\u015d\5*\26\2\u015d\u015e") - buf.write("\5 \21\2\u015e\61\3\2\2\2\u015f\u0160\7N\2\2\u0160\u0161") - buf.write("\5\16\b\2\u0161\u0162\7c\2\2\u0162\u0163\5(\25\2\u0163") - buf.write("\63\3\2\2\2\u0164\u0165\7P\2\2\u0165\u0168\5(\25\2\u0166") - buf.write("\u0167\7M\2\2\u0167\u0169\5(\25\2\u0168\u0166\3\2\2\2") - buf.write("\u0168\u0169\3\2\2\2\u0169\65\3\2\2\2\u016a\u016b\7O\2") - buf.write("\2\u016b\u016c\5(\25\2\u016c\67\3\2\2\2\u016d\u016e\7") - buf.write("Q\2\2\u016e\u016f\5\16\b\2\u016f\u0170\7c\2\2\u0170\u0171") - buf.write("\5 \21\2\u01719\3\2\2\2\u0172\u0173\7R\2\2\u0173\u0174") - buf.write("\5(\25\2\u0174;\3\2\2\2\u0175\u0176\7S\2\2\u0176=\3\2") - buf.write("\2\2\u0177\u0178\7V\2\2\u0178\u0179\5(\25\2\u0179?\3\2") - buf.write("\2\2\u017a\u017b\7T\2\2\u017b\u017c\5(\25\2\u017cA\3\2") - buf.write("\2\2\u017d\u017f\7U\2\2\u017e\u0180\7j\2\2\u017f\u017e") - buf.write("\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0181\3\2\2\2\u0181") - buf.write("\u0182\5(\25\2\u0182C\3\2\2\2\u0183\u0184\7W\2\2\u0184") - buf.write("\u0185\5(\25\2\u0185\u0186\5(\25\2\u0186E\3\2\2\2\u0187") - buf.write("\u0188\7C\2\2\u0188\u0189\5(\25\2\u0189G\3\2\2\2\u018a") - buf.write("\u018b\7X\2\2\u018b\u0190\5(\25\2\u018c\u018d\7M\2\2\u018d") - buf.write("\u018f\5(\25\2\u018e\u018c\3\2\2\2\u018f\u0192\3\2\2\2") - buf.write("\u0190\u018e\3\2\2\2\u0190\u0191\3\2\2\2\u0191I\3\2\2") - buf.write("\2\u0192\u0190\3\2\2\2\u0193\u0194\7h\2\2\u0194\u0195") - buf.write("\7f\2\2\u0195\u0196\5b\62\2\u0196K\3\2\2\2\u0197\u0198") - buf.write("\5\32\16\2\u0198\u0199\7f\2\2\u0199\u019a\5b\62\2\u019a") - buf.write("M\3\2\2\2\u019b\u019c\7Z\2\2\u019c\u019d\5\16\b\2\u019d") - buf.write("\u019e\7c\2\2\u019e\u01a0\5 \21\2\u019f\u01a1\79\2\2\u01a0") - buf.write("\u019f\3\2\2\2\u01a0\u01a1\3\2\2\2\u01a1O\3\2\2\2\u01a2") - buf.write("\u01a9\7Y\2\2\u01a3\u01a4\7a\2\2\u01a4\u01a5\5\16\b\2") - buf.write("\u01a5\u01a6\7e\2\2\u01a6\u01a7\5(\25\2\u01a7\u01aa\3") - buf.write("\2\2\2\u01a8\u01aa\5(\25\2\u01a9\u01a3\3\2\2\2\u01a9\u01a8") - buf.write("\3\2\2\2\u01aa\u01ac\3\2\2\2\u01ab\u01ad\79\2\2\u01ac") - buf.write("\u01ab\3\2\2\2\u01ac\u01ad\3\2\2\2\u01adQ\3\2\2\2\u01ae") - buf.write("\u01b1\5N(\2\u01af\u01b1\5P)\2\u01b0\u01ae\3\2\2\2\u01b0") - buf.write("\u01af\3\2\2\2\u01b1\u01b3\3\2\2\2\u01b2\u01b4\5R*\2\u01b3") - buf.write("\u01b2\3\2\2\2\u01b3\u01b4\3\2\2\2\u01b4S\3\2\2\2\u01b5") - buf.write("\u01b6\5R*\2\u01b6\u01b7\7f\2\2\u01b7\u01b8\5b\62\2\u01b8") - buf.write("U\3\2\2\2\u01b9\u01ba\7`\2\2\u01ba\u01bb\7l\2\2\u01bb") - buf.write("\u01bc\5\16\b\2\u01bc\u01bd\7f\2\2\u01bd\u01be\5b\62\2") - buf.write("\u01beW\3\2\2\2\u01bf\u01c0\7_\2\2\u01c0\u01c1\5(\25\2") - buf.write("\u01c1\u01c2\7f\2\2\u01c2\u01c3\5b\62\2\u01c3Y\3\2\2\2") - buf.write("\u01c4\u01c5\7\\\2\2\u01c5\u01c6\5(\25\2\u01c6\u01c7\7") - buf.write("f\2\2\u01c7\u01c8\5b\62\2\u01c8[\3\2\2\2\u01c9\u01ca\7") - buf.write("]\2\2\u01ca\u01cb\7f\2\2\u01cb\u01cc\5b\62\2\u01cc]\3") - buf.write("\2\2\2\u01cd\u01ce\7[\2\2\u01ce\u01cf\5(\25\2\u01cf\u01d0") - buf.write("\7f\2\2\u01d0\u01d4\5b\62\2\u01d1\u01d3\5Z.\2\u01d2\u01d1") - buf.write("\3\2\2\2\u01d3\u01d6\3\2\2\2\u01d4\u01d2\3\2\2\2\u01d4") - buf.write("\u01d5\3\2\2\2\u01d5\u01d8\3\2\2\2\u01d6\u01d4\3\2\2\2") - buf.write("\u01d7\u01d9\5\\/\2\u01d8\u01d7\3\2\2\2\u01d8\u01d9\3") - buf.write("\2\2\2\u01d9_\3\2\2\2\u01da\u01dc\5n8\2\u01db\u01da\3") - buf.write("\2\2\2\u01dc\u01dd\3\2\2\2\u01dd\u01db\3\2\2\2\u01dd\u01de") - buf.write("\3\2\2\2\u01dea\3\2\2\2\u01df\u01e2\5d\63\2\u01e0\u01e2") - buf.write("\5j\66\2\u01e1\u01df\3\2\2\2\u01e1\u01e0\3\2\2\2\u01e2") - buf.write("c\3\2\2\2\u01e3\u01e7\7w\2\2\u01e4\u01e8\5`\61\2\u01e5") - buf.write("\u01e6\7w\2\2\u01e6\u01e8\5b\62\2\u01e7\u01e4\3\2\2\2") - buf.write("\u01e7\u01e5\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01ec\7") - buf.write("x\2\2\u01ea\u01eb\7u\2\2\u01eb\u01ed\79\2\2\u01ec\u01ea") - buf.write("\3\2\2\2\u01ec\u01ed\3\2\2\2\u01ede\3\2\2\2\u01ee\u01f0") - buf.write("\7h\2\2\u01ef\u01ee\3\2\2\2\u01ef\u01f0\3\2\2\2\u01f0") - buf.write("\u0200\3\2\2\2\u01f1\u0201\5.\30\2\u01f2\u0201\5\62\32") - buf.write("\2\u01f3\u0201\5\66\34\2\u01f4\u0201\58\35\2\u01f5\u0201") - buf.write("\5> \2\u01f6\u0201\5@!\2\u01f7\u0201\5B\"\2\u01f8\u0201") - buf.write("\5:\36\2\u01f9\u0201\5D#\2\u01fa\u0201\5F$\2\u01fb\u0201") - buf.write("\5<\37\2\u01fc\u0201\5H%\2\u01fd\u0201\5\64\33\2\u01fe") - buf.write("\u0201\5\60\31\2\u01ff\u0201\5,\27\2\u0200\u01f1\3\2\2") - buf.write("\2\u0200\u01f2\3\2\2\2\u0200\u01f3\3\2\2\2\u0200\u01f4") - buf.write("\3\2\2\2\u0200\u01f5\3\2\2\2\u0200\u01f6\3\2\2\2\u0200") - buf.write("\u01f7\3\2\2\2\u0200\u01f8\3\2\2\2\u0200\u01f9\3\2\2\2") - buf.write("\u0200\u01fa\3\2\2\2\u0200\u01fb\3\2\2\2\u0200\u01fc\3") - buf.write("\2\2\2\u0200\u01fd\3\2\2\2\u0200\u01fe\3\2\2\2\u0200\u01ff") - buf.write("\3\2\2\2\u0201g\3\2\2\2\u0202\u0204\7h\2\2\u0203\u0202") - buf.write("\3\2\2\2\u0203\u0204\3\2\2\2\u0204\u020b\3\2\2\2\u0205") - buf.write("\u020c\5^\60\2\u0206\u020c\5X-\2\u0207\u020c\5L\'\2\u0208") - buf.write("\u020c\5T+\2\u0209\u020c\5J&\2\u020a\u020c\5V,\2\u020b") - buf.write("\u0205\3\2\2\2\u020b\u0206\3\2\2\2\u020b\u0207\3\2\2\2") - buf.write("\u020b\u0208\3\2\2\2\u020b\u0209\3\2\2\2\u020b\u020a\3") - buf.write("\2\2\2\u020ci\3\2\2\2\u020d\u0214\5f\64\2\u020e\u0210") - buf.write("\7u\2\2\u020f\u020e\3\2\2\2\u020f\u0210\3\2\2\2\u0210") - buf.write("\u0211\3\2\2\2\u0211\u0215\79\2\2\u0212\u0213\7u\2\2\u0213") - buf.write("\u0215\5j\66\2\u0214\u020f\3\2\2\2\u0214\u0212\3\2\2\2") - buf.write("\u0215k\3\2\2\2\u0216\u0217\7l\2\2\u0217\u0219\7f\2\2") - buf.write("\u0218\u0216\3\2\2\2\u0219\u021a\3\2\2\2\u021a\u0218\3") - buf.write("\2\2\2\u021a\u021b\3\2\2\2\u021bm\3\2\2\2\u021c\u021e") - buf.write("\5l\67\2\u021d\u021c\3\2\2\2\u021d\u021e\3\2\2\2\u021e") - buf.write("\u0221\3\2\2\2\u021f\u0221\7f\2\2\u0220\u021d\3\2\2\2") - buf.write("\u0220\u021f\3\2\2\2\u0221\u022c\3\2\2\2\u0222\u0224\7") - buf.write("u\2\2\u0223\u0222\3\2\2\2\u0224\u0227\3\2\2\2\u0225\u0223") - buf.write("\3\2\2\2\u0225\u0226\3\2\2\2\u0226\u0228\3\2\2\2\u0227") - buf.write("\u0225\3\2\2\2\u0228\u022d\79\2\2\u0229\u022d\5j\66\2") - buf.write("\u022a\u022d\5h\65\2\u022b\u022d\5\4\3\2\u022c\u0225\3") - buf.write("\2\2\2\u022c\u0229\3\2\2\2\u022c\u022a\3\2\2\2\u022c\u022b") - buf.write("\3\2\2\2\u022d\u0234\3\2\2\2\u022e\u0231\5l\67\2\u022f") - buf.write("\u0231\7f\2\2\u0230\u022e\3\2\2\2\u0230\u022f\3\2\2\2") - buf.write("\u0231\u0232\3\2\2\2\u0232\u0234\5d\63\2\u0233\u0220\3") - buf.write("\2\2\2\u0233\u0230\3\2\2\2\u0234o\3\2\2\2:sz}\u0089\u0090") - buf.write("\u00a0\u00a7\u00ba\u00c2\u00c7\u00cc\u00d9\u00dc\u00e5") - buf.write("\u00e8\u00ed\u00ef\u00f8\u0106\u010a\u010c\u0110\u0119") - buf.write("\u0126\u0129\u013d\u0147\u0149\u0157\u0168\u017f\u0190") - buf.write("\u01a0\u01a9\u01ac\u01b0\u01b3\u01d4\u01d8\u01dd\u01e1") - buf.write("\u01e7\u01ec\u01ef\u0200\u0203\u020b\u020f\u0214\u021a") - buf.write("\u021d\u0220\u0225\u022c\u0230\u0233") + buf.write("\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\3\2\7") + buf.write("\2v\n\2\f\2\16\2y\13\2\3\2\3\2\3\3\3\3\5\3\177\n\3\3\3") + buf.write("\5\3\u0082\n\3\3\3\3\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5") + buf.write("\5\5\u008e\n\5\3\6\3\6\3\6\7\6\u0093\n\6\f\6\16\6\u0096") + buf.write("\13\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7") + buf.write("\3\7\5\7\u00a5\n\7\3\b\3\b\3\b\7\b\u00aa\n\b\f\b\16\b") + buf.write("\u00ad\13\b\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f") + buf.write("\3\f\3\f\3\f\3\f\3\f\3\f\5\f\u00bf\n\f\3\f\3\f\3\f\3\f") + buf.write("\3\f\3\f\5\f\u00c7\n\f\3\f\3\f\3\f\5\f\u00cc\n\f\3\f\3") + buf.write("\f\3\f\5\f\u00d1\n\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3") + buf.write("\r\7\r\u00dc\n\r\f\r\16\r\u00df\13\r\5\r\u00e1\n\r\3\r") + buf.write("\3\r\3\r\3\r\3\r\7\r\u00e8\n\r\f\r\16\r\u00eb\13\r\5\r") + buf.write("\u00ed\n\r\3\16\3\16\3\16\7\16\u00f2\n\16\f\16\16\16\u00f5") + buf.write("\13\16\3\17\3\17\3\17\3\17\3\17\3\17\5\17\u00fd\n\17\3") + buf.write("\17\3\17\3\17\3\20\3\20\3\20\3\21\3\21\3\21\3\21\7\21") + buf.write("\u0109\n\21\f\21\16\21\u010c\13\21\3\21\5\21\u010f\n\21") + buf.write("\5\21\u0111\n\21\3\22\3\22\5\22\u0115\n\22\3\22\3\22\3") + buf.write("\22\3\22\3\22\7\22\u011c\n\22\f\22\16\22\u011f\13\22\3") + buf.write("\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\7\22\u0129\n\22") + buf.write("\f\22\16\22\u012c\13\22\5\22\u012e\n\22\3\23\3\23\3\23") + buf.write("\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23") + buf.write("\3\23\3\23\3\23\3\23\5\23\u0142\n\23\3\24\3\24\3\24\3") + buf.write("\24\3\24\3\24\3\24\3\24\7\24\u014c\n\24\f\24\16\24\u014f") + buf.write("\13\24\3\25\3\25\3\26\3\26\3\27\3\27\3\30\3\30\3\30\6") + buf.write("\30\u015a\n\30\r\30\16\30\u015b\3\30\3\30\3\31\3\31\3") + buf.write("\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33") + buf.write("\5\33\u016d\n\33\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3") + buf.write("\35\3\36\3\36\3\36\3\37\3\37\3 \3 \3 \3!\3!\3!\3\"\3\"") + buf.write("\5\"\u0184\n\"\3\"\3\"\3#\3#\3#\3#\3$\3$\3$\3%\3%\3%\3") + buf.write("%\7%\u0193\n%\f%\16%\u0196\13%\3&\3&\3&\3&\3\'\3\'\3\'") + buf.write("\3\'\3(\3(\3(\3(\3(\5(\u01a5\n(\3)\3)\3)\3)\3)\3)\3)\5") + buf.write(")\u01ae\n)\3)\5)\u01b1\n)\3*\3*\5*\u01b5\n*\3*\5*\u01b8") + buf.write("\n*\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3-\3-\3-\3-\3-\3.\3") + buf.write(".\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\7\60\u01d7") + buf.write("\n\60\f\60\16\60\u01da\13\60\3\60\5\60\u01dd\n\60\3\61") + buf.write("\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\63\6\63") + buf.write("\u01ea\n\63\r\63\16\63\u01eb\3\64\3\64\5\64\u01f0\n\64") + buf.write("\3\65\3\65\3\65\3\65\5\65\u01f6\n\65\3\65\3\65\3\65\5") + buf.write("\65\u01fb\n\65\3\66\5\66\u01fe\n\66\3\66\3\66\3\66\3\66") + buf.write("\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66") + buf.write("\5\66\u020f\n\66\3\67\5\67\u0212\n\67\3\67\3\67\3\67\3") + buf.write("\67\3\67\3\67\5\67\u021a\n\67\38\38\58\u021e\n8\38\38") + buf.write("\38\58\u0223\n8\39\39\69\u0227\n9\r9\169\u0228\3:\5:\u022c") + buf.write("\n:\3:\5:\u022f\n:\3:\7:\u0232\n:\f:\16:\u0235\13:\3:") + buf.write("\3:\3:\3:\3:\5:\u023c\n:\3:\3:\5:\u0240\n:\3:\5:\u0243") + buf.write("\n:\3:\2\3&;\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"") + buf.write("$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnpr\2\6") + buf.write("\4\2\3\21??\3\2\22\27\5\2\t\t\30(LL\3\2*8\2\u026c\2w\3") + buf.write("\2\2\2\4~\3\2\2\2\6\u0085\3\2\2\2\b\u0088\3\2\2\2\n\u008f") + buf.write("\3\2\2\2\f\u00a4\3\2\2\2\16\u00ab\3\2\2\2\20\u00b0\3\2") + buf.write("\2\2\22\u00b2\3\2\2\2\24\u00b4\3\2\2\2\26\u00d0\3\2\2") + buf.write("\2\30\u00d2\3\2\2\2\32\u00ee\3\2\2\2\34\u00f6\3\2\2\2") + buf.write("\36\u0101\3\2\2\2 \u0104\3\2\2\2\"\u0112\3\2\2\2$\u0141") + buf.write("\3\2\2\2&\u0143\3\2\2\2(\u0150\3\2\2\2*\u0152\3\2\2\2") + buf.write(",\u0154\3\2\2\2.\u0159\3\2\2\2\60\u015f\3\2\2\2\62\u0163") + buf.write("\3\2\2\2\64\u0168\3\2\2\2\66\u016e\3\2\2\28\u0171\3\2") + buf.write("\2\2:\u0176\3\2\2\2<\u0179\3\2\2\2>\u017b\3\2\2\2@\u017e") + buf.write("\3\2\2\2B\u0181\3\2\2\2D\u0187\3\2\2\2F\u018b\3\2\2\2") + buf.write("H\u018e\3\2\2\2J\u0197\3\2\2\2L\u019b\3\2\2\2N\u019f\3") + buf.write("\2\2\2P\u01a6\3\2\2\2R\u01b4\3\2\2\2T\u01b9\3\2\2\2V\u01bd") + buf.write("\3\2\2\2X\u01c3\3\2\2\2Z\u01c8\3\2\2\2\\\u01cd\3\2\2\2") + buf.write("^\u01d1\3\2\2\2`\u01de\3\2\2\2b\u01e1\3\2\2\2d\u01e9\3") + buf.write("\2\2\2f\u01ef\3\2\2\2h\u01f1\3\2\2\2j\u01fd\3\2\2\2l\u0211") + buf.write("\3\2\2\2n\u021b\3\2\2\2p\u0226\3\2\2\2r\u0242\3\2\2\2") + buf.write("tv\5r:\2ut\3\2\2\2vy\3\2\2\2wu\3\2\2\2wx\3\2\2\2xz\3\2") + buf.write("\2\2yw\3\2\2\2z{\7\2\2\3{\3\3\2\2\2|\177\5\6\4\2}\177") + buf.write("\5\b\5\2~|\3\2\2\2~}\3\2\2\2\177\u0081\3\2\2\2\u0080\u0082") + buf.write("\7v\2\2\u0081\u0080\3\2\2\2\u0081\u0082\3\2\2\2\u0082") + buf.write("\u0083\3\2\2\2\u0083\u0084\79\2\2\u0084\5\3\2\2\2\u0085") + buf.write("\u0086\7B\2\2\u0086\u0087\5\n\6\2\u0087\7\3\2\2\2\u0088") + buf.write("\u0089\7D\2\2\u0089\u008a\7m\2\2\u008a\u008d\7B\2\2\u008b") + buf.write("\u008e\7?\2\2\u008c\u008e\5\n\6\2\u008d\u008b\3\2\2\2") + buf.write("\u008d\u008c\3\2\2\2\u008e\t\3\2\2\2\u008f\u0094\7m\2") + buf.write("\2\u0090\u0091\7M\2\2\u0091\u0093\7m\2\2\u0092\u0090\3") + buf.write("\2\2\2\u0093\u0096\3\2\2\2\u0094\u0092\3\2\2\2\u0094\u0095") + buf.write("\3\2\2\2\u0095\13\3\2\2\2\u0096\u0094\3\2\2\2\u0097\u00a5") + buf.write("\7m\2\2\u0098\u0099\7t\2\2\u0099\u009a\5\16\b\2\u009a") + buf.write("\u009b\7u\2\2\u009b\u00a5\3\2\2\2\u009c\u009d\7p\2\2\u009d") + buf.write("\u009e\5\16\b\2\u009e\u009f\7q\2\2\u009f\u00a5\3\2\2\2") + buf.write("\u00a0\u00a1\7t\2\2\u00a1\u00a5\7u\2\2\u00a2\u00a3\7p") + buf.write("\2\2\u00a3\u00a5\7q\2\2\u00a4\u0097\3\2\2\2\u00a4\u0098") + buf.write("\3\2\2\2\u00a4\u009c\3\2\2\2\u00a4\u00a0\3\2\2\2\u00a4") + buf.write("\u00a2\3\2\2\2\u00a5\r\3\2\2\2\u00a6\u00a7\5\f\7\2\u00a7") + buf.write("\u00a8\7M\2\2\u00a8\u00aa\3\2\2\2\u00a9\u00a6\3\2\2\2") + buf.write("\u00aa\u00ad\3\2\2\2\u00ab\u00a9\3\2\2\2\u00ab\u00ac\3") + buf.write("\2\2\2\u00ac\u00ae\3\2\2\2\u00ad\u00ab\3\2\2\2\u00ae\u00af") + buf.write("\5\f\7\2\u00af\17\3\2\2\2\u00b0\u00b1\t\2\2\2\u00b1\21") + buf.write("\3\2\2\2\u00b2\u00b3\t\3\2\2\u00b3\23\3\2\2\2\u00b4\u00b5") + buf.write("\t\4\2\2\u00b5\25\3\2\2\2\u00b6\u00d1\7l\2\2\u00b7\u00d1") + buf.write("\7i\2\2\u00b8\u00d1\7n\2\2\u00b9\u00d1\7m\2\2\u00ba\u00d1") + buf.write("\7w\2\2\u00bb\u00d1\7g\2\2\u00bc\u00be\7r\2\2\u00bd\u00bf") + buf.write("\5\30\r\2\u00be\u00bd\3\2\2\2\u00be\u00bf\3\2\2\2\u00bf") + buf.write("\u00c0\3\2\2\2\u00c0\u00d1\7s\2\2\u00c1\u00c2\7r\2\2\u00c2") + buf.write("\u00c3\7f\2\2\u00c3\u00d1\7s\2\2\u00c4\u00c6\7t\2\2\u00c5") + buf.write("\u00c7\5 \21\2\u00c6\u00c5\3\2\2\2\u00c6\u00c7\3\2\2\2") + buf.write("\u00c7\u00c8\3\2\2\2\u00c8\u00d1\7u\2\2\u00c9\u00cb\7") + buf.write("p\2\2\u00ca\u00cc\5 \21\2\u00cb\u00ca\3\2\2\2\u00cb\u00cc") + buf.write("\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd\u00d1\7q\2\2\u00ce") + buf.write("\u00cf\7K\2\2\u00cf\u00d1\5$\23\2\u00d0\u00b6\3\2\2\2") + buf.write("\u00d0\u00b7\3\2\2\2\u00d0\u00b8\3\2\2\2\u00d0\u00b9\3") + buf.write("\2\2\2\u00d0\u00ba\3\2\2\2\u00d0\u00bb\3\2\2\2\u00d0\u00bc") + buf.write("\3\2\2\2\u00d0\u00c1\3\2\2\2\u00d0\u00c4\3\2\2\2\u00d0") + buf.write("\u00c9\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d1\27\3\2\2\2\u00d2") + buf.write("\u00ec\5\"\22\2\u00d3\u00d4\7f\2\2\u00d4\u00e0\5\"\22") + buf.write("\2\u00d5\u00e1\5\32\16\2\u00d6\u00d7\7M\2\2\u00d7\u00d8") + buf.write("\5\"\22\2\u00d8\u00d9\7f\2\2\u00d9\u00da\5\"\22\2\u00da") + buf.write("\u00dc\3\2\2\2\u00db\u00d6\3\2\2\2\u00dc\u00df\3\2\2\2") + buf.write("\u00dd\u00db\3\2\2\2\u00dd\u00de\3\2\2\2\u00de\u00e1\3") + buf.write("\2\2\2\u00df\u00dd\3\2\2\2\u00e0\u00d5\3\2\2\2\u00e0\u00dd") + buf.write("\3\2\2\2\u00e1\u00ed\3\2\2\2\u00e2\u00ed\5\32\16\2\u00e3") + buf.write("\u00e4\7E\2\2\u00e4\u00ed\5\"\22\2\u00e5\u00e6\7M\2\2") + buf.write("\u00e6\u00e8\5\"\22\2\u00e7\u00e5\3\2\2\2\u00e8\u00eb") + buf.write("\3\2\2\2\u00e9\u00e7\3\2\2\2\u00e9\u00ea\3\2\2\2\u00ea") + buf.write("\u00ed\3\2\2\2\u00eb\u00e9\3\2\2\2\u00ec\u00d3\3\2\2\2") + buf.write("\u00ec\u00e2\3\2\2\2\u00ec\u00e3\3\2\2\2\u00ec\u00e9\3") + buf.write("\2\2\2\u00ed\31\3\2\2\2\u00ee\u00f3\5\34\17\2\u00ef\u00f2") + buf.write("\5\34\17\2\u00f0\u00f2\5\36\20\2\u00f1\u00ef\3\2\2\2\u00f1") + buf.write("\u00f0\3\2\2\2\u00f2\u00f5\3\2\2\2\u00f3\u00f1\3\2\2\2") + buf.write("\u00f3\u00f4\3\2\2\2\u00f4\33\3\2\2\2\u00f5\u00f3\3\2") + buf.write("\2\2\u00f6\u00fc\7d\2\2\u00f7\u00fd\5\16\b\2\u00f8\u00f9") + buf.write("\5\16\b\2\u00f9\u00fa\7f\2\2\u00fa\u00fb\5\16\b\2\u00fb") + buf.write("\u00fd\3\2\2\2\u00fc\u00f7\3\2\2\2\u00fc\u00f8\3\2\2\2") + buf.write("\u00fd\u00fe\3\2\2\2\u00fe\u00ff\7e\2\2\u00ff\u0100\5") + buf.write("\"\22\2\u0100\35\3\2\2\2\u0101\u0102\7b\2\2\u0102\u0103") + buf.write("\5\"\22\2\u0103\37\3\2\2\2\u0104\u0110\5\"\22\2\u0105") + buf.write("\u0111\5\32\16\2\u0106\u0107\7M\2\2\u0107\u0109\5\"\22") + buf.write("\2\u0108\u0106\3\2\2\2\u0109\u010c\3\2\2\2\u010a\u0108") + buf.write("\3\2\2\2\u010a\u010b\3\2\2\2\u010b\u010e\3\2\2\2\u010c") + buf.write("\u010a\3\2\2\2\u010d\u010f\7M\2\2\u010e\u010d\3\2\2\2") + buf.write("\u010e\u010f\3\2\2\2\u010f\u0111\3\2\2\2\u0110\u0105\3") + buf.write("\2\2\2\u0110\u010a\3\2\2\2\u0111!\3\2\2\2\u0112\u012d") + buf.write("\5$\23\2\u0113\u0115\7L\2\2\u0114\u0113\3\2\2\2\u0114") + buf.write("\u0115\3\2\2\2\u0115\u0116\3\2\2\2\u0116\u0117\7e\2\2") + buf.write("\u0117\u012e\5$\23\2\u0118\u0119\5\22\n\2\u0119\u011a") + buf.write("\5$\23\2\u011a\u011c\3\2\2\2\u011b\u0118\3\2\2\2\u011c") + buf.write("\u011f\3\2\2\2\u011d\u011b\3\2\2\2\u011d\u011e\3\2\2\2") + buf.write("\u011e\u012e\3\2\2\2\u011f\u011d\3\2\2\2\u0120\u0121\7") + buf.write("[\2\2\u0121\u0122\5\"\22\2\u0122\u0123\7]\2\2\u0123\u0124") + buf.write("\5$\23\2\u0124\u012e\3\2\2\2\u0125\u0126\5\20\t\2\u0126") + buf.write("\u0127\5$\23\2\u0127\u0129\3\2\2\2\u0128\u0125\3\2\2\2") + buf.write("\u0129\u012c\3\2\2\2\u012a\u0128\3\2\2\2\u012a\u012b\3") + buf.write("\2\2\2\u012b\u012e\3\2\2\2\u012c\u012a\3\2\2\2\u012d\u0114") + buf.write("\3\2\2\2\u012d\u011d\3\2\2\2\u012d\u0120\3\2\2\2\u012d") + buf.write("\u012a\3\2\2\2\u012e#\3\2\2\2\u012f\u0130\7J\2\2\u0130") + buf.write("\u0131\5\16\b\2\u0131\u0132\7f\2\2\u0132\u0133\5\"\22") + buf.write("\2\u0133\u0134\7)\2\2\u0134\u0142\3\2\2\2\u0135\u0136") + buf.write("\7F\2\2\u0136\u0142\5$\23\2\u0137\u0138\7H\2\2\u0138\u0142") + buf.write("\5$\23\2\u0139\u013a\7I\2\2\u013a\u0142\5$\23\2\u013b") + buf.write("\u013c\7>\2\2\u013c\u0142\5$\23\2\u013d\u013e\5\24\13") + buf.write("\2\u013e\u013f\5$\23\2\u013f\u0142\3\2\2\2\u0140\u0142") + buf.write("\5&\24\2\u0141\u012f\3\2\2\2\u0141\u0135\3\2\2\2\u0141") + buf.write("\u0137\3\2\2\2\u0141\u0139\3\2\2\2\u0141\u013b\3\2\2\2") + buf.write("\u0141\u013d\3\2\2\2\u0141\u0140\3\2\2\2\u0142%\3\2\2") + buf.write("\2\u0143\u0144\b\24\1\2\u0144\u0145\5\26\f\2\u0145\u014d") + buf.write("\3\2\2\2\u0146\u0147\f\4\2\2\u0147\u0148\7G\2\2\u0148") + buf.write("\u014c\7m\2\2\u0149\u014a\f\3\2\2\u014a\u014c\5\26\f\2") + buf.write("\u014b\u0146\3\2\2\2\u014b\u0149\3\2\2\2\u014c\u014f\3") + buf.write("\2\2\2\u014d\u014b\3\2\2\2\u014d\u014e\3\2\2\2\u014e\'") + buf.write("\3\2\2\2\u014f\u014d\3\2\2\2\u0150\u0151\5\"\22\2\u0151") + buf.write(")\3\2\2\2\u0152\u0153\t\5\2\2\u0153+\3\2\2\2\u0154\u0155") + buf.write("\5 \21\2\u0155-\3\2\2\2\u0156\u0157\5 \21\2\u0157\u0158") + buf.write("\7c\2\2\u0158\u015a\3\2\2\2\u0159\u0156\3\2\2\2\u015a") + buf.write("\u015b\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015c\3\2\2\2") + buf.write("\u015c\u015d\3\2\2\2\u015d\u015e\5 \21\2\u015e/\3\2\2") + buf.write("\2\u015f\u0160\5 \21\2\u0160\u0161\5*\26\2\u0161\u0162") + buf.write("\5 \21\2\u0162\61\3\2\2\2\u0163\u0164\7N\2\2\u0164\u0165") + buf.write("\5\16\b\2\u0165\u0166\7c\2\2\u0166\u0167\5(\25\2\u0167") + buf.write("\63\3\2\2\2\u0168\u0169\7P\2\2\u0169\u016c\5(\25\2\u016a") + buf.write("\u016b\7M\2\2\u016b\u016d\5(\25\2\u016c\u016a\3\2\2\2") + buf.write("\u016c\u016d\3\2\2\2\u016d\65\3\2\2\2\u016e\u016f\7O\2") + buf.write("\2\u016f\u0170\5(\25\2\u0170\67\3\2\2\2\u0171\u0172\7") + buf.write("Q\2\2\u0172\u0173\5\16\b\2\u0173\u0174\7c\2\2\u0174\u0175") + buf.write("\5 \21\2\u01759\3\2\2\2\u0176\u0177\7R\2\2\u0177\u0178") + buf.write("\5(\25\2\u0178;\3\2\2\2\u0179\u017a\7S\2\2\u017a=\3\2") + buf.write("\2\2\u017b\u017c\7V\2\2\u017c\u017d\5(\25\2\u017d?\3\2") + buf.write("\2\2\u017e\u017f\7T\2\2\u017f\u0180\5(\25\2\u0180A\3\2") + buf.write("\2\2\u0181\u0183\7U\2\2\u0182\u0184\7j\2\2\u0183\u0182") + buf.write("\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u0185\3\2\2\2\u0185") + buf.write("\u0186\5(\25\2\u0186C\3\2\2\2\u0187\u0188\7W\2\2\u0188") + buf.write("\u0189\5(\25\2\u0189\u018a\5(\25\2\u018aE\3\2\2\2\u018b") + buf.write("\u018c\7C\2\2\u018c\u018d\5(\25\2\u018dG\3\2\2\2\u018e") + buf.write("\u018f\7X\2\2\u018f\u0194\5(\25\2\u0190\u0191\7M\2\2\u0191") + buf.write("\u0193\5(\25\2\u0192\u0190\3\2\2\2\u0193\u0196\3\2\2\2") + buf.write("\u0194\u0192\3\2\2\2\u0194\u0195\3\2\2\2\u0195I\3\2\2") + buf.write("\2\u0196\u0194\3\2\2\2\u0197\u0198\7h\2\2\u0198\u0199") + buf.write("\7f\2\2\u0199\u019a\5f\64\2\u019aK\3\2\2\2\u019b\u019c") + buf.write("\5\32\16\2\u019c\u019d\7f\2\2\u019d\u019e\5f\64\2\u019e") + buf.write("M\3\2\2\2\u019f\u01a0\7Z\2\2\u01a0\u01a1\5\16\b\2\u01a1") + buf.write("\u01a2\7c\2\2\u01a2\u01a4\5 \21\2\u01a3\u01a5\79\2\2\u01a4") + buf.write("\u01a3\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5O\3\2\2\2\u01a6") + buf.write("\u01ad\7Y\2\2\u01a7\u01a8\7a\2\2\u01a8\u01a9\5\16\b\2") + buf.write("\u01a9\u01aa\7e\2\2\u01aa\u01ab\5(\25\2\u01ab\u01ae\3") + buf.write("\2\2\2\u01ac\u01ae\5(\25\2\u01ad\u01a7\3\2\2\2\u01ad\u01ac") + buf.write("\3\2\2\2\u01ae\u01b0\3\2\2\2\u01af\u01b1\79\2\2\u01b0") + buf.write("\u01af\3\2\2\2\u01b0\u01b1\3\2\2\2\u01b1Q\3\2\2\2\u01b2") + buf.write("\u01b5\5N(\2\u01b3\u01b5\5P)\2\u01b4\u01b2\3\2\2\2\u01b4") + buf.write("\u01b3\3\2\2\2\u01b5\u01b7\3\2\2\2\u01b6\u01b8\5R*\2\u01b7") + buf.write("\u01b6\3\2\2\2\u01b7\u01b8\3\2\2\2\u01b8S\3\2\2\2\u01b9") + buf.write("\u01ba\5R*\2\u01ba\u01bb\7f\2\2\u01bb\u01bc\5f\64\2\u01bc") + buf.write("U\3\2\2\2\u01bd\u01be\7`\2\2\u01be\u01bf\7m\2\2\u01bf") + buf.write("\u01c0\5\16\b\2\u01c0\u01c1\7f\2\2\u01c1\u01c2\5f\64\2") + buf.write("\u01c2W\3\2\2\2\u01c3\u01c4\7_\2\2\u01c4\u01c5\5(\25\2") + buf.write("\u01c5\u01c6\7f\2\2\u01c6\u01c7\5f\64\2\u01c7Y\3\2\2\2") + buf.write("\u01c8\u01c9\7\\\2\2\u01c9\u01ca\5(\25\2\u01ca\u01cb\7") + buf.write("f\2\2\u01cb\u01cc\5f\64\2\u01cc[\3\2\2\2\u01cd\u01ce\7") + buf.write("]\2\2\u01ce\u01cf\7f\2\2\u01cf\u01d0\5f\64\2\u01d0]\3") + buf.write("\2\2\2\u01d1\u01d2\7[\2\2\u01d2\u01d3\5(\25\2\u01d3\u01d4") + buf.write("\7f\2\2\u01d4\u01d8\5f\64\2\u01d5\u01d7\5Z.\2\u01d6\u01d5") + buf.write("\3\2\2\2\u01d7\u01da\3\2\2\2\u01d8\u01d6\3\2\2\2\u01d8") + buf.write("\u01d9\3\2\2\2\u01d9\u01dc\3\2\2\2\u01da\u01d8\3\2\2\2") + buf.write("\u01db\u01dd\5\\/\2\u01dc\u01db\3\2\2\2\u01dc\u01dd\3") + buf.write("\2\2\2\u01dd_\3\2\2\2\u01de\u01df\7\32\2\2\u01df\u01e0") + buf.write("\7m\2\2\u01e0a\3\2\2\2\u01e1\u01e2\7k\2\2\u01e2\u01e3") + buf.write("\7t\2\2\u01e3\u01e4\5`\61\2\u01e4\u01e5\7u\2\2\u01e5\u01e6") + buf.write("\5\22\n\2\u01e6\u01e7\5(\25\2\u01e7c\3\2\2\2\u01e8\u01ea") + buf.write("\5r:\2\u01e9\u01e8\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb\u01e9") + buf.write("\3\2\2\2\u01eb\u01ec\3\2\2\2\u01ece\3\2\2\2\u01ed\u01f0") + buf.write("\5h\65\2\u01ee\u01f0\5n8\2\u01ef\u01ed\3\2\2\2\u01ef\u01ee") + buf.write("\3\2\2\2\u01f0g\3\2\2\2\u01f1\u01f5\7x\2\2\u01f2\u01f6") + buf.write("\5d\63\2\u01f3\u01f4\7x\2\2\u01f4\u01f6\5f\64\2\u01f5") + buf.write("\u01f2\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01f7\3\2\2\2") + buf.write("\u01f7\u01fa\7y\2\2\u01f8\u01f9\7v\2\2\u01f9\u01fb\79") + buf.write("\2\2\u01fa\u01f8\3\2\2\2\u01fa\u01fb\3\2\2\2\u01fbi\3") + buf.write("\2\2\2\u01fc\u01fe\7h\2\2\u01fd\u01fc\3\2\2\2\u01fd\u01fe") + buf.write("\3\2\2\2\u01fe\u020e\3\2\2\2\u01ff\u020f\5.\30\2\u0200") + buf.write("\u020f\5\62\32\2\u0201\u020f\5\66\34\2\u0202\u020f\58") + buf.write("\35\2\u0203\u020f\5> \2\u0204\u020f\5@!\2\u0205\u020f") + buf.write("\5B\"\2\u0206\u020f\5:\36\2\u0207\u020f\5D#\2\u0208\u020f") + buf.write("\5F$\2\u0209\u020f\5<\37\2\u020a\u020f\5H%\2\u020b\u020f") + buf.write("\5\64\33\2\u020c\u020f\5\60\31\2\u020d\u020f\5,\27\2\u020e") + buf.write("\u01ff\3\2\2\2\u020e\u0200\3\2\2\2\u020e\u0201\3\2\2\2") + buf.write("\u020e\u0202\3\2\2\2\u020e\u0203\3\2\2\2\u020e\u0204\3") + buf.write("\2\2\2\u020e\u0205\3\2\2\2\u020e\u0206\3\2\2\2\u020e\u0207") + buf.write("\3\2\2\2\u020e\u0208\3\2\2\2\u020e\u0209\3\2\2\2\u020e") + buf.write("\u020a\3\2\2\2\u020e\u020b\3\2\2\2\u020e\u020c\3\2\2\2") + buf.write("\u020e\u020d\3\2\2\2\u020fk\3\2\2\2\u0210\u0212\7h\2\2") + buf.write("\u0211\u0210\3\2\2\2\u0211\u0212\3\2\2\2\u0212\u0219\3") + buf.write("\2\2\2\u0213\u021a\5^\60\2\u0214\u021a\5X-\2\u0215\u021a") + buf.write("\5L\'\2\u0216\u021a\5T+\2\u0217\u021a\5J&\2\u0218\u021a") + buf.write("\5V,\2\u0219\u0213\3\2\2\2\u0219\u0214\3\2\2\2\u0219\u0215") + buf.write("\3\2\2\2\u0219\u0216\3\2\2\2\u0219\u0217\3\2\2\2\u0219") + buf.write("\u0218\3\2\2\2\u021am\3\2\2\2\u021b\u0222\5j\66\2\u021c") + buf.write("\u021e\7v\2\2\u021d\u021c\3\2\2\2\u021d\u021e\3\2\2\2") + buf.write("\u021e\u021f\3\2\2\2\u021f\u0223\79\2\2\u0220\u0221\7") + buf.write("v\2\2\u0221\u0223\5n8\2\u0222\u021d\3\2\2\2\u0222\u0220") + buf.write("\3\2\2\2\u0223o\3\2\2\2\u0224\u0225\7m\2\2\u0225\u0227") + buf.write("\7f\2\2\u0226\u0224\3\2\2\2\u0227\u0228\3\2\2\2\u0228") + buf.write("\u0226\3\2\2\2\u0228\u0229\3\2\2\2\u0229q\3\2\2\2\u022a") + buf.write("\u022c\5p9\2\u022b\u022a\3\2\2\2\u022b\u022c\3\2\2\2\u022c") + buf.write("\u022f\3\2\2\2\u022d\u022f\7f\2\2\u022e\u022b\3\2\2\2") + buf.write("\u022e\u022d\3\2\2\2\u022f\u023b\3\2\2\2\u0230\u0232\7") + buf.write("v\2\2\u0231\u0230\3\2\2\2\u0232\u0235\3\2\2\2\u0233\u0231") + buf.write("\3\2\2\2\u0233\u0234\3\2\2\2\u0234\u0236\3\2\2\2\u0235") + buf.write("\u0233\3\2\2\2\u0236\u023c\79\2\2\u0237\u023c\5n8\2\u0238") + buf.write("\u023c\5l\67\2\u0239\u023c\5\4\3\2\u023a\u023c\5b\62\2") + buf.write("\u023b\u0233\3\2\2\2\u023b\u0237\3\2\2\2\u023b\u0238\3") + buf.write("\2\2\2\u023b\u0239\3\2\2\2\u023b\u023a\3\2\2\2\u023c\u0243") + buf.write("\3\2\2\2\u023d\u0240\5p9\2\u023e\u0240\7f\2\2\u023f\u023d") + buf.write("\3\2\2\2\u023f\u023e\3\2\2\2\u0240\u0241\3\2\2\2\u0241") + buf.write("\u0243\5h\65\2\u0242\u022e\3\2\2\2\u0242\u023f\3\2\2\2") + buf.write("\u0243s\3\2\2\2:w~\u0081\u008d\u0094\u00a4\u00ab\u00be") + buf.write("\u00c6\u00cb\u00d0\u00dd\u00e0\u00e9\u00ec\u00f1\u00f3") + buf.write("\u00fc\u010a\u010e\u0110\u0114\u011d\u012a\u012d\u0141") + buf.write("\u014b\u014d\u015b\u016c\u0183\u0194\u01a4\u01ad\u01b0") + buf.write("\u01b4\u01b7\u01d8\u01dc\u01eb\u01ef\u01f5\u01fa\u01fd") + buf.write("\u020e\u0211\u0219\u021d\u0222\u0228\u022b\u022e\u0233") + buf.write("\u023b\u023f\u0242") return buf.getvalue() @@ -312,9 +318,9 @@ class HarmonyParser ( Parser ): "'when'", "'let'", "'if'", "'elif'", "'else'", "'@'", "'while'", "'def'", "'exists'", "'where'", "'='", "'for'", "'in'", "':'", "'None'", "'atomically'", "", - "'eternal'", "", "", "", - "", "'['", "']'", "'{'", "'}'", "'('", "')'", - "';'" ] + "'eternal'", "'hyper_assert'", "", "", + "", "", "'['", "']'", "'{'", "'}'", + "'('", "')'", "';'" ] symbolicNames = [ "", "", "", "", "", "", "", "", @@ -338,7 +344,7 @@ class HarmonyParser ( Parser ): "GO", "SEQUENTIAL", "WHEN", "LET", "IF", "ELIF", "ELSE", "AT", "WHILE", "DEF", "EXISTS", "WHERE", "EQ", "FOR", "IN", "COLON", "NONE", "ATOMICALLY", "BOOL", "ETERNAL", - "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", + "HYPER", "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", "CLOSE_PAREN", "SEMI_COLON", "STRING", "INDENT", "DEDENT" ] @@ -389,14 +395,16 @@ class HarmonyParser ( Parser ): RULE_elif_block = 44 RULE_else_block = 45 RULE_if_block = 46 - RULE_block_stmts = 47 - RULE_block = 48 - RULE_normal_block = 49 - RULE_simple_stmt = 50 - RULE_compound_stmt = 51 - RULE_one_line_stmt = 52 - RULE_label = 53 - RULE_stmt = 54 + RULE_hyper_condition = 47 + RULE_hyperassert_stmt = 48 + RULE_block_stmts = 49 + RULE_block = 50 + RULE_normal_block = 51 + RULE_simple_stmt = 52 + RULE_compound_stmt = 53 + RULE_one_line_stmt = 54 + RULE_label = 55 + RULE_stmt = 56 ruleNames = [ "program", "import_stmt", "import_name", "import_from", "import_names_seq", "tuple_bound", "bound", "arith_op", @@ -409,9 +417,9 @@ class HarmonyParser ( Parser ): "go_stmt", "print_stmt", "sequential_stmt", "atomic_block", "for_block", "let_decl", "when_decl", "let_when_decl", "let_when_block", "method_decl", "while_block", "elif_block", - "else_block", "if_block", "block_stmts", "block", "normal_block", - "simple_stmt", "compound_stmt", "one_line_stmt", "label", - "stmt" ] + "else_block", "if_block", "hyper_condition", "hyperassert_stmt", + "block_stmts", "block", "normal_block", "simple_stmt", + "compound_stmt", "one_line_stmt", "label", "stmt" ] EOF = Token.EOF T__0=1 @@ -518,20 +526,21 @@ class HarmonyParser ( Parser ): ATOMICALLY=102 BOOL=103 ETERNAL=104 - INT=105 - NAME=106 - ATOM=107 - HEX_INTEGER=108 - OPEN_BRACK=109 - CLOSE_BRACK=110 - OPEN_BRACES=111 - CLOSE_BRACES=112 - OPEN_PAREN=113 - CLOSE_PAREN=114 - SEMI_COLON=115 - STRING=116 - INDENT=117 - DEDENT=118 + HYPER=105 + INT=106 + NAME=107 + ATOM=108 + HEX_INTEGER=109 + OPEN_BRACK=110 + CLOSE_BRACK=111 + OPEN_BRACES=112 + CLOSE_BRACES=113 + OPEN_PAREN=114 + CLOSE_PAREN=115 + SEMI_COLON=116 + STRING=117 + INDENT=118 + DEDENT=119 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) @@ -578,17 +587,17 @@ def program(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 113 + self.state = 117 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0): - self.state = 110 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.HYPER - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0): + self.state = 114 self.stmt() - self.state = 115 + self.state = 119 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 116 + self.state = 120 self.match(HarmonyParser.EOF) except RecognitionException as re: localctx.exception = re @@ -639,29 +648,29 @@ def import_stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 120 + self.state = 124 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.IMPORT]: - self.state = 118 + self.state = 122 self.import_name() pass elif token in [HarmonyParser.FROM]: - self.state = 119 + self.state = 123 self.import_from() pass else: raise NoViableAltException(self) - self.state = 123 + self.state = 127 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.SEMI_COLON: - self.state = 122 + self.state = 126 self.match(HarmonyParser.SEMI_COLON) - self.state = 125 + self.state = 129 self.match(HarmonyParser.NL) except RecognitionException as re: localctx.exception = re @@ -704,9 +713,9 @@ def import_name(self): self.enterRule(localctx, 4, self.RULE_import_name) try: self.enterOuterAlt(localctx, 1) - self.state = 127 + self.state = 131 self.match(HarmonyParser.IMPORT) - self.state = 128 + self.state = 132 self.import_names_seq() except RecognitionException as re: localctx.exception = re @@ -758,21 +767,21 @@ def import_from(self): self.enterRule(localctx, 6, self.RULE_import_from) try: self.enterOuterAlt(localctx, 1) - self.state = 130 + self.state = 134 self.match(HarmonyParser.FROM) - self.state = 131 + self.state = 135 self.match(HarmonyParser.NAME) - self.state = 132 + self.state = 136 self.match(HarmonyParser.IMPORT) - self.state = 135 + self.state = 139 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.STAR]: - self.state = 133 + self.state = 137 self.match(HarmonyParser.STAR) pass elif token in [HarmonyParser.NAME]: - self.state = 134 + self.state = 138 self.import_names_seq() pass else: @@ -825,17 +834,17 @@ def import_names_seq(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 137 + self.state = 141 self.match(HarmonyParser.NAME) - self.state = 142 + self.state = 146 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.COMMA: - self.state = 138 + self.state = 142 self.match(HarmonyParser.COMMA) - self.state = 139 + self.state = 143 self.match(HarmonyParser.NAME) - self.state = 144 + self.state = 148 self._errHandler.sync(self) _la = self._input.LA(1) @@ -891,48 +900,48 @@ def tuple_bound(self): localctx = HarmonyParser.Tuple_boundContext(self, self._ctx, self.state) self.enterRule(localctx, 10, self.RULE_tuple_bound) try: - self.state = 158 + self.state = 162 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,5,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 145 + self.state = 149 self.match(HarmonyParser.NAME) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 146 + self.state = 150 self.match(HarmonyParser.OPEN_PAREN) - self.state = 147 + self.state = 151 self.bound() - self.state = 148 + self.state = 152 self.match(HarmonyParser.CLOSE_PAREN) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 150 + self.state = 154 self.match(HarmonyParser.OPEN_BRACK) - self.state = 151 + self.state = 155 self.bound() - self.state = 152 + self.state = 156 self.match(HarmonyParser.CLOSE_BRACK) pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 154 + self.state = 158 self.match(HarmonyParser.OPEN_PAREN) - self.state = 155 + self.state = 159 self.match(HarmonyParser.CLOSE_PAREN) pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 156 + self.state = 160 self.match(HarmonyParser.OPEN_BRACK) - self.state = 157 + self.state = 161 self.match(HarmonyParser.CLOSE_BRACK) pass @@ -984,20 +993,20 @@ def bound(self): self.enterRule(localctx, 12, self.RULE_bound) try: self.enterOuterAlt(localctx, 1) - self.state = 165 + self.state = 169 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,6,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 160 + self.state = 164 self.tuple_bound() - self.state = 161 + self.state = 165 self.match(HarmonyParser.COMMA) - self.state = 167 + self.state = 171 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,6,self._ctx) - self.state = 168 + self.state = 172 self.tuple_bound() except RecognitionException as re: localctx.exception = re @@ -1037,7 +1046,7 @@ def arith_op(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 170 + self.state = 174 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__0) | (1 << HarmonyParser.T__1) | (1 << HarmonyParser.T__2) | (1 << HarmonyParser.T__3) | (1 << HarmonyParser.T__4) | (1 << HarmonyParser.T__5) | (1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__7) | (1 << HarmonyParser.T__8) | (1 << HarmonyParser.T__9) | (1 << HarmonyParser.T__10) | (1 << HarmonyParser.T__11) | (1 << HarmonyParser.T__12) | (1 << HarmonyParser.T__13) | (1 << HarmonyParser.T__14) | (1 << HarmonyParser.STAR))) != 0)): self._errHandler.recoverInline(self) @@ -1080,7 +1089,7 @@ def comp_op(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 172 + self.state = 176 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__15) | (1 << HarmonyParser.T__16) | (1 << HarmonyParser.T__17) | (1 << HarmonyParser.T__18) | (1 << HarmonyParser.T__19) | (1 << HarmonyParser.T__20))) != 0)): self._errHandler.recoverInline(self) @@ -1125,7 +1134,7 @@ def unary_op(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 174 + self.state = 178 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37))) != 0) or _la==HarmonyParser.NOT): self._errHandler.recoverInline(self) @@ -1363,119 +1372,119 @@ def basic_expr(self): self.enterRule(localctx, 20, self.RULE_basic_expr) self._la = 0 # Token type try: - self.state = 202 + self.state = 206 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,10,self._ctx) if la_ == 1: localctx = HarmonyParser.IntContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 176 + self.state = 180 self.match(HarmonyParser.INT) pass elif la_ == 2: localctx = HarmonyParser.BoolContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 177 + self.state = 181 self.match(HarmonyParser.BOOL) pass elif la_ == 3: localctx = HarmonyParser.AtomContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 178 + self.state = 182 self.match(HarmonyParser.ATOM) pass elif la_ == 4: localctx = HarmonyParser.NameContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 179 + self.state = 183 self.match(HarmonyParser.NAME) pass elif la_ == 5: localctx = HarmonyParser.StrContext(self, localctx) self.enterOuterAlt(localctx, 5) - self.state = 180 + self.state = 184 self.match(HarmonyParser.STRING) pass elif la_ == 6: localctx = HarmonyParser.NoneContext(self, localctx) self.enterOuterAlt(localctx, 6) - self.state = 181 + self.state = 185 self.match(HarmonyParser.NONE) pass elif la_ == 7: localctx = HarmonyParser.Set_rule_1Context(self, localctx) self.enterOuterAlt(localctx, 7) - self.state = 182 + self.state = 186 self.match(HarmonyParser.OPEN_BRACES) - self.state = 184 + self.state = 188 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 68)) & ~0x3f) == 0 and ((1 << (_la - 68)) & ((1 << (HarmonyParser.SETINTLEVEL - 68)) | (1 << (HarmonyParser.SAVE - 68)) | (1 << (HarmonyParser.STOP - 68)) | (1 << (HarmonyParser.LAMBDA - 68)) | (1 << (HarmonyParser.ADDRESS_OF - 68)) | (1 << (HarmonyParser.NOT - 68)) | (1 << (HarmonyParser.NONE - 68)) | (1 << (HarmonyParser.BOOL - 68)) | (1 << (HarmonyParser.INT - 68)) | (1 << (HarmonyParser.NAME - 68)) | (1 << (HarmonyParser.ATOM - 68)) | (1 << (HarmonyParser.OPEN_BRACK - 68)) | (1 << (HarmonyParser.OPEN_BRACES - 68)) | (1 << (HarmonyParser.OPEN_PAREN - 68)) | (1 << (HarmonyParser.STRING - 68)))) != 0): - self.state = 183 + self.state = 187 self.set_rule() - self.state = 186 + self.state = 190 self.match(HarmonyParser.CLOSE_BRACES) pass elif la_ == 8: localctx = HarmonyParser.Empty_dictContext(self, localctx) self.enterOuterAlt(localctx, 8) - self.state = 187 + self.state = 191 self.match(HarmonyParser.OPEN_BRACES) - self.state = 188 + self.state = 192 self.match(HarmonyParser.COLON) - self.state = 189 + self.state = 193 self.match(HarmonyParser.CLOSE_BRACES) pass elif la_ == 9: localctx = HarmonyParser.Paren_tupleContext(self, localctx) self.enterOuterAlt(localctx, 9) - self.state = 190 + self.state = 194 self.match(HarmonyParser.OPEN_PAREN) - self.state = 192 + self.state = 196 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 68)) & ~0x3f) == 0 and ((1 << (_la - 68)) & ((1 << (HarmonyParser.SETINTLEVEL - 68)) | (1 << (HarmonyParser.SAVE - 68)) | (1 << (HarmonyParser.STOP - 68)) | (1 << (HarmonyParser.LAMBDA - 68)) | (1 << (HarmonyParser.ADDRESS_OF - 68)) | (1 << (HarmonyParser.NOT - 68)) | (1 << (HarmonyParser.NONE - 68)) | (1 << (HarmonyParser.BOOL - 68)) | (1 << (HarmonyParser.INT - 68)) | (1 << (HarmonyParser.NAME - 68)) | (1 << (HarmonyParser.ATOM - 68)) | (1 << (HarmonyParser.OPEN_BRACK - 68)) | (1 << (HarmonyParser.OPEN_BRACES - 68)) | (1 << (HarmonyParser.OPEN_PAREN - 68)) | (1 << (HarmonyParser.STRING - 68)))) != 0): - self.state = 191 + self.state = 195 self.tuple_rule() - self.state = 194 + self.state = 198 self.match(HarmonyParser.CLOSE_PAREN) pass elif la_ == 10: localctx = HarmonyParser.Bracket_tupleContext(self, localctx) self.enterOuterAlt(localctx, 10) - self.state = 195 + self.state = 199 self.match(HarmonyParser.OPEN_BRACK) - self.state = 197 + self.state = 201 self._errHandler.sync(self) _la = self._input.LA(1) if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 68)) & ~0x3f) == 0 and ((1 << (_la - 68)) & ((1 << (HarmonyParser.SETINTLEVEL - 68)) | (1 << (HarmonyParser.SAVE - 68)) | (1 << (HarmonyParser.STOP - 68)) | (1 << (HarmonyParser.LAMBDA - 68)) | (1 << (HarmonyParser.ADDRESS_OF - 68)) | (1 << (HarmonyParser.NOT - 68)) | (1 << (HarmonyParser.NONE - 68)) | (1 << (HarmonyParser.BOOL - 68)) | (1 << (HarmonyParser.INT - 68)) | (1 << (HarmonyParser.NAME - 68)) | (1 << (HarmonyParser.ATOM - 68)) | (1 << (HarmonyParser.OPEN_BRACK - 68)) | (1 << (HarmonyParser.OPEN_BRACES - 68)) | (1 << (HarmonyParser.OPEN_PAREN - 68)) | (1 << (HarmonyParser.STRING - 68)))) != 0): - self.state = 196 + self.state = 200 self.tuple_rule() - self.state = 199 + self.state = 203 self.match(HarmonyParser.CLOSE_BRACK) pass elif la_ == 11: localctx = HarmonyParser.AddressContext(self, localctx) self.enterOuterAlt(localctx, 11) - self.state = 200 + self.state = 204 self.match(HarmonyParser.ADDRESS_OF) - self.state = 201 + self.state = 205 self.expr_rule() pass @@ -1541,37 +1550,37 @@ def set_rule(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 204 + self.state = 208 self.nary_expr() - self.state = 230 + self.state = 234 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.COLON]: - self.state = 205 + self.state = 209 self.match(HarmonyParser.COLON) - self.state = 206 + self.state = 210 self.nary_expr() - self.state = 218 + self.state = 222 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.FOR]: - self.state = 207 + self.state = 211 self.iter_parse() pass elif token in [HarmonyParser.COMMA, HarmonyParser.CLOSE_BRACES]: - self.state = 215 + self.state = 219 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.COMMA: - self.state = 208 + self.state = 212 self.match(HarmonyParser.COMMA) - self.state = 209 + self.state = 213 self.nary_expr() - self.state = 210 + self.state = 214 self.match(HarmonyParser.COLON) - self.state = 211 + self.state = 215 self.nary_expr() - self.state = 217 + self.state = 221 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1581,25 +1590,25 @@ def set_rule(self): pass elif token in [HarmonyParser.FOR]: - self.state = 220 + self.state = 224 self.iter_parse() pass elif token in [HarmonyParser.RANGE]: - self.state = 221 + self.state = 225 self.match(HarmonyParser.RANGE) - self.state = 222 + self.state = 226 self.nary_expr() pass elif token in [HarmonyParser.COMMA, HarmonyParser.CLOSE_BRACES]: - self.state = 227 + self.state = 231 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.COMMA: - self.state = 223 + self.state = 227 self.match(HarmonyParser.COMMA) - self.state = 224 + self.state = 228 self.nary_expr() - self.state = 229 + self.state = 233 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1656,27 +1665,27 @@ def iter_parse(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 232 + self.state = 236 self.for_parse() - self.state = 237 + self.state = 241 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.WHERE or _la==HarmonyParser.FOR: - self.state = 235 + self.state = 239 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.FOR]: - self.state = 233 + self.state = 237 self.for_parse() pass elif token in [HarmonyParser.WHERE]: - self.state = 234 + self.state = 238 self.where_parse() pass else: raise NoViableAltException(self) - self.state = 239 + self.state = 243 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1734,29 +1743,29 @@ def for_parse(self): self.enterRule(localctx, 26, self.RULE_for_parse) try: self.enterOuterAlt(localctx, 1) - self.state = 240 + self.state = 244 self.match(HarmonyParser.FOR) - self.state = 246 + self.state = 250 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,17,self._ctx) if la_ == 1: - self.state = 241 + self.state = 245 self.bound() pass elif la_ == 2: - self.state = 242 + self.state = 246 self.bound() - self.state = 243 + self.state = 247 self.match(HarmonyParser.COLON) - self.state = 244 + self.state = 248 self.bound() pass - self.state = 248 + self.state = 252 self.match(HarmonyParser.IN) - self.state = 249 + self.state = 253 self.nary_expr() except RecognitionException as re: localctx.exception = re @@ -1799,9 +1808,9 @@ def where_parse(self): self.enterRule(localctx, 28, self.RULE_where_parse) try: self.enterOuterAlt(localctx, 1) - self.state = 251 + self.state = 255 self.match(HarmonyParser.WHERE) - self.state = 252 + self.state = 256 self.nary_expr() except RecognitionException as re: localctx.exception = re @@ -1855,34 +1864,34 @@ def tuple_rule(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 254 + self.state = 258 self.nary_expr() - self.state = 266 + self.state = 270 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.FOR]: - self.state = 255 + self.state = 259 self.iter_parse() pass elif token in [HarmonyParser.T__39, HarmonyParser.T__40, HarmonyParser.T__41, HarmonyParser.T__42, HarmonyParser.T__43, HarmonyParser.T__44, HarmonyParser.T__45, HarmonyParser.T__46, HarmonyParser.T__47, HarmonyParser.T__48, HarmonyParser.T__49, HarmonyParser.T__50, HarmonyParser.T__51, HarmonyParser.T__52, HarmonyParser.T__53, HarmonyParser.NL, HarmonyParser.COMMA, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.EQ, HarmonyParser.COLON, HarmonyParser.CLOSE_BRACK, HarmonyParser.CLOSE_PAREN, HarmonyParser.SEMI_COLON]: - self.state = 260 + self.state = 264 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,18,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 256 + self.state = 260 self.match(HarmonyParser.COMMA) - self.state = 257 + self.state = 261 self.nary_expr() - self.state = 262 + self.state = 266 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,18,self._ctx) - self.state = 264 + self.state = 268 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.COMMA: - self.state = 263 + self.state = 267 self.match(HarmonyParser.COMMA) @@ -1962,63 +1971,63 @@ def nary_expr(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 268 + self.state = 272 self.expr_rule() - self.state = 295 + self.state = 299 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,24,self._ctx) if la_ == 1: - self.state = 270 + self.state = 274 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.NOT: - self.state = 269 + self.state = 273 self.match(HarmonyParser.NOT) - self.state = 272 + self.state = 276 self.match(HarmonyParser.IN) - self.state = 273 + self.state = 277 self.expr_rule() pass elif la_ == 2: - self.state = 279 + self.state = 283 self._errHandler.sync(self) _la = self._input.LA(1) while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__15) | (1 << HarmonyParser.T__16) | (1 << HarmonyParser.T__17) | (1 << HarmonyParser.T__18) | (1 << HarmonyParser.T__19) | (1 << HarmonyParser.T__20))) != 0): - self.state = 274 + self.state = 278 self.comp_op() - self.state = 275 + self.state = 279 self.expr_rule() - self.state = 281 + self.state = 285 self._errHandler.sync(self) _la = self._input.LA(1) pass elif la_ == 3: - self.state = 282 + self.state = 286 self.match(HarmonyParser.IF) - self.state = 283 + self.state = 287 self.nary_expr() - self.state = 284 + self.state = 288 self.match(HarmonyParser.ELSE) - self.state = 285 + self.state = 289 self.expr_rule() pass elif la_ == 4: - self.state = 292 + self.state = 296 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,23,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 287 + self.state = 291 self.arith_op() - self.state = 288 + self.state = 292 self.expr_rule() - self.state = 294 + self.state = 298 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,23,self._ctx) @@ -2096,60 +2105,60 @@ def expr_rule(self): localctx = HarmonyParser.Expr_ruleContext(self, self._ctx, self.state) self.enterRule(localctx, 34, self.RULE_expr_rule) try: - self.state = 315 + self.state = 319 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.LAMBDA]: self.enterOuterAlt(localctx, 1) - self.state = 297 + self.state = 301 self.match(HarmonyParser.LAMBDA) - self.state = 298 + self.state = 302 self.bound() - self.state = 299 + self.state = 303 self.match(HarmonyParser.COLON) - self.state = 300 + self.state = 304 self.nary_expr() - self.state = 301 + self.state = 305 self.match(HarmonyParser.T__38) pass elif token in [HarmonyParser.SETINTLEVEL]: self.enterOuterAlt(localctx, 2) - self.state = 303 + self.state = 307 self.match(HarmonyParser.SETINTLEVEL) - self.state = 304 + self.state = 308 self.expr_rule() pass elif token in [HarmonyParser.SAVE]: self.enterOuterAlt(localctx, 3) - self.state = 305 + self.state = 309 self.match(HarmonyParser.SAVE) - self.state = 306 + self.state = 310 self.expr_rule() pass elif token in [HarmonyParser.STOP]: self.enterOuterAlt(localctx, 4) - self.state = 307 + self.state = 311 self.match(HarmonyParser.STOP) - self.state = 308 + self.state = 312 self.expr_rule() pass elif token in [HarmonyParser.POINTER_OF]: self.enterOuterAlt(localctx, 5) - self.state = 309 + self.state = 313 self.match(HarmonyParser.POINTER_OF) - self.state = 310 + self.state = 314 self.expr_rule() pass elif token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NOT]: self.enterOuterAlt(localctx, 6) - self.state = 311 + self.state = 315 self.unary_op() - self.state = 312 + self.state = 316 self.expr_rule() pass elif token in [HarmonyParser.ADDRESS_OF, HarmonyParser.NONE, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.STRING]: self.enterOuterAlt(localctx, 7) - self.state = 314 + self.state = 318 self.application(0) pass else: @@ -2205,10 +2214,10 @@ def application(self, _p:int=0): self.enterRecursionRule(localctx, 36, self.RULE_application, _p) try: self.enterOuterAlt(localctx, 1) - self.state = 318 + self.state = 322 self.basic_expr() self._ctx.stop = self._input.LT(-1) - self.state = 327 + self.state = 331 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,27,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: @@ -2216,35 +2225,35 @@ def application(self, _p:int=0): if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx - self.state = 325 + self.state = 329 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,26,self._ctx) if la_ == 1: localctx = HarmonyParser.ApplicationContext(self, _parentctx, _parentState) self.pushNewRecursionContext(localctx, _startState, self.RULE_application) - self.state = 320 + self.state = 324 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") - self.state = 321 + self.state = 325 self.match(HarmonyParser.ARROW) - self.state = 322 + self.state = 326 self.match(HarmonyParser.NAME) pass elif la_ == 2: localctx = HarmonyParser.ApplicationContext(self, _parentctx, _parentState) self.pushNewRecursionContext(localctx, _startState, self.RULE_application) - self.state = 323 + self.state = 327 if not self.precpred(self._ctx, 1): from antlr4.error.Errors import FailedPredicateException raise FailedPredicateException(self, "self.precpred(self._ctx, 1)") - self.state = 324 + self.state = 328 self.basic_expr() pass - self.state = 329 + self.state = 333 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,27,self._ctx) @@ -2286,7 +2295,7 @@ def expr(self): self.enterRule(localctx, 38, self.RULE_expr) try: self.enterOuterAlt(localctx, 1) - self.state = 330 + self.state = 334 self.nary_expr() except RecognitionException as re: localctx.exception = re @@ -2324,7 +2333,7 @@ def aug_assign_op(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 332 + self.state = 336 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__39) | (1 << HarmonyParser.T__40) | (1 << HarmonyParser.T__41) | (1 << HarmonyParser.T__42) | (1 << HarmonyParser.T__43) | (1 << HarmonyParser.T__44) | (1 << HarmonyParser.T__45) | (1 << HarmonyParser.T__46) | (1 << HarmonyParser.T__47) | (1 << HarmonyParser.T__48) | (1 << HarmonyParser.T__49) | (1 << HarmonyParser.T__50) | (1 << HarmonyParser.T__51) | (1 << HarmonyParser.T__52) | (1 << HarmonyParser.T__53))) != 0)): self._errHandler.recoverInline(self) @@ -2369,7 +2378,7 @@ def expr_stmt(self): self.enterRule(localctx, 42, self.RULE_expr_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 334 + self.state = 338 self.tuple_rule() except RecognitionException as re: localctx.exception = re @@ -2418,23 +2427,23 @@ def assign_stmt(self): self.enterRule(localctx, 44, self.RULE_assign_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 339 + self.state = 343 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 336 + self.state = 340 self.tuple_rule() - self.state = 337 + self.state = 341 self.match(HarmonyParser.EQ) else: raise NoViableAltException(self) - self.state = 341 + self.state = 345 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,28,self._ctx) - self.state = 343 + self.state = 347 self.tuple_rule() except RecognitionException as re: localctx.exception = re @@ -2481,11 +2490,11 @@ def aug_assign_stmt(self): self.enterRule(localctx, 46, self.RULE_aug_assign_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 345 + self.state = 349 self.tuple_rule() - self.state = 346 + self.state = 350 self.aug_assign_op() - self.state = 347 + self.state = 351 self.tuple_rule() except RecognitionException as re: localctx.exception = re @@ -2535,13 +2544,13 @@ def const_assign_stmt(self): self.enterRule(localctx, 48, self.RULE_const_assign_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 349 + self.state = 353 self.match(HarmonyParser.CONST) - self.state = 350 + self.state = 354 self.bound() - self.state = 351 + self.state = 355 self.match(HarmonyParser.EQ) - self.state = 352 + self.state = 356 self.expr() except RecognitionException as re: localctx.exception = re @@ -2591,17 +2600,17 @@ def assert_stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 354 + self.state = 358 self.match(HarmonyParser.ASSERT) - self.state = 355 + self.state = 359 self.expr() - self.state = 358 + self.state = 362 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.COMMA: - self.state = 356 + self.state = 360 self.match(HarmonyParser.COMMA) - self.state = 357 + self.state = 361 self.expr() @@ -2646,9 +2655,9 @@ def await_stmt(self): self.enterRule(localctx, 52, self.RULE_await_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 360 + self.state = 364 self.match(HarmonyParser.AWAIT) - self.state = 361 + self.state = 365 self.expr() except RecognitionException as re: localctx.exception = re @@ -2698,13 +2707,13 @@ def var_stmt(self): self.enterRule(localctx, 54, self.RULE_var_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 363 + self.state = 367 self.match(HarmonyParser.VAR) - self.state = 364 + self.state = 368 self.bound() - self.state = 365 + self.state = 369 self.match(HarmonyParser.EQ) - self.state = 366 + self.state = 370 self.tuple_rule() except RecognitionException as re: localctx.exception = re @@ -2747,9 +2756,9 @@ def trap_stmt(self): self.enterRule(localctx, 56, self.RULE_trap_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 368 + self.state = 372 self.match(HarmonyParser.TRAP) - self.state = 369 + self.state = 373 self.expr() except RecognitionException as re: localctx.exception = re @@ -2788,7 +2797,7 @@ def pass_stmt(self): self.enterRule(localctx, 58, self.RULE_pass_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 371 + self.state = 375 self.match(HarmonyParser.PASS) except RecognitionException as re: localctx.exception = re @@ -2831,9 +2840,9 @@ def invariant_stmt(self): self.enterRule(localctx, 60, self.RULE_invariant_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 373 + self.state = 377 self.match(HarmonyParser.INVARIANT) - self.state = 374 + self.state = 378 self.expr() except RecognitionException as re: localctx.exception = re @@ -2876,9 +2885,9 @@ def del_stmt(self): self.enterRule(localctx, 62, self.RULE_del_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 376 + self.state = 380 self.match(HarmonyParser.DEL) - self.state = 377 + self.state = 381 self.expr() except RecognitionException as re: localctx.exception = re @@ -2925,17 +2934,17 @@ def spawn_stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 379 + self.state = 383 self.match(HarmonyParser.SPAWN) - self.state = 381 + self.state = 385 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.ETERNAL: - self.state = 380 + self.state = 384 self.match(HarmonyParser.ETERNAL) - self.state = 383 + self.state = 387 self.expr() except RecognitionException as re: localctx.exception = re @@ -2981,11 +2990,11 @@ def go_stmt(self): self.enterRule(localctx, 66, self.RULE_go_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 385 + self.state = 389 self.match(HarmonyParser.GO) - self.state = 386 + self.state = 390 self.expr() - self.state = 387 + self.state = 391 self.expr() except RecognitionException as re: localctx.exception = re @@ -3028,9 +3037,9 @@ def print_stmt(self): self.enterRule(localctx, 68, self.RULE_print_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 389 + self.state = 393 self.match(HarmonyParser.PRINT) - self.state = 390 + self.state = 394 self.expr() except RecognitionException as re: localctx.exception = re @@ -3083,19 +3092,19 @@ def sequential_stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 392 + self.state = 396 self.match(HarmonyParser.SEQUENTIAL) - self.state = 393 + self.state = 397 self.expr() - self.state = 398 + self.state = 402 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.COMMA: - self.state = 394 + self.state = 398 self.match(HarmonyParser.COMMA) - self.state = 395 + self.state = 399 self.expr() - self.state = 400 + self.state = 404 self._errHandler.sync(self) _la = self._input.LA(1) @@ -3143,11 +3152,11 @@ def atomic_block(self): self.enterRule(localctx, 72, self.RULE_atomic_block) try: self.enterOuterAlt(localctx, 1) - self.state = 401 + self.state = 405 self.match(HarmonyParser.ATOMICALLY) - self.state = 402 + self.state = 406 self.match(HarmonyParser.COLON) - self.state = 403 + self.state = 407 self.block() except RecognitionException as re: localctx.exception = re @@ -3194,11 +3203,11 @@ def for_block(self): self.enterRule(localctx, 74, self.RULE_for_block) try: self.enterOuterAlt(localctx, 1) - self.state = 405 + self.state = 409 self.iter_parse() - self.state = 406 + self.state = 410 self.match(HarmonyParser.COLON) - self.state = 407 + self.state = 411 self.block() except RecognitionException as re: localctx.exception = re @@ -3252,19 +3261,19 @@ def let_decl(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 409 + self.state = 413 self.match(HarmonyParser.LET) - self.state = 410 + self.state = 414 self.bound() - self.state = 411 + self.state = 415 self.match(HarmonyParser.EQ) - self.state = 412 + self.state = 416 self.tuple_rule() - self.state = 414 + self.state = 418 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.NL: - self.state = 413 + self.state = 417 self.match(HarmonyParser.NL) @@ -3323,33 +3332,33 @@ def when_decl(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 416 + self.state = 420 self.match(HarmonyParser.WHEN) - self.state = 423 + self.state = 427 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.EXISTS]: - self.state = 417 + self.state = 421 self.match(HarmonyParser.EXISTS) - self.state = 418 + self.state = 422 self.bound() - self.state = 419 + self.state = 423 self.match(HarmonyParser.IN) - self.state = 420 + self.state = 424 self.expr() pass elif token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.POINTER_OF, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.NONE, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.STRING]: - self.state = 422 + self.state = 426 self.expr() pass else: raise NoViableAltException(self) - self.state = 426 + self.state = 430 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.NL: - self.state = 425 + self.state = 429 self.match(HarmonyParser.NL) @@ -3400,25 +3409,25 @@ def let_when_decl(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 430 + self.state = 434 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.LET]: - self.state = 428 + self.state = 432 self.let_decl() pass elif token in [HarmonyParser.WHEN]: - self.state = 429 + self.state = 433 self.when_decl() pass else: raise NoViableAltException(self) - self.state = 433 + self.state = 437 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.WHEN or _la==HarmonyParser.LET: - self.state = 432 + self.state = 436 self.let_when_decl() @@ -3467,11 +3476,11 @@ def let_when_block(self): self.enterRule(localctx, 82, self.RULE_let_when_block) try: self.enterOuterAlt(localctx, 1) - self.state = 435 + self.state = 439 self.let_when_decl() - self.state = 436 + self.state = 440 self.match(HarmonyParser.COLON) - self.state = 437 + self.state = 441 self.block() except RecognitionException as re: localctx.exception = re @@ -3524,15 +3533,15 @@ def method_decl(self): self.enterRule(localctx, 84, self.RULE_method_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 439 + self.state = 443 self.match(HarmonyParser.DEF) - self.state = 440 + self.state = 444 self.match(HarmonyParser.NAME) - self.state = 441 + self.state = 445 self.bound() - self.state = 442 + self.state = 446 self.match(HarmonyParser.COLON) - self.state = 443 + self.state = 447 self.block() except RecognitionException as re: localctx.exception = re @@ -3582,13 +3591,13 @@ def while_block(self): self.enterRule(localctx, 86, self.RULE_while_block) try: self.enterOuterAlt(localctx, 1) - self.state = 445 + self.state = 449 self.match(HarmonyParser.WHILE) - self.state = 446 + self.state = 450 self.expr() - self.state = 447 + self.state = 451 self.match(HarmonyParser.COLON) - self.state = 448 + self.state = 452 self.block() except RecognitionException as re: localctx.exception = re @@ -3638,13 +3647,13 @@ def elif_block(self): self.enterRule(localctx, 88, self.RULE_elif_block) try: self.enterOuterAlt(localctx, 1) - self.state = 450 + self.state = 454 self.match(HarmonyParser.ELIF) - self.state = 451 + self.state = 455 self.expr() - self.state = 452 + self.state = 456 self.match(HarmonyParser.COLON) - self.state = 453 + self.state = 457 self.block() except RecognitionException as re: localctx.exception = re @@ -3690,11 +3699,11 @@ def else_block(self): self.enterRule(localctx, 90, self.RULE_else_block) try: self.enterOuterAlt(localctx, 1) - self.state = 455 + self.state = 459 self.match(HarmonyParser.ELSE) - self.state = 456 + self.state = 460 self.match(HarmonyParser.COLON) - self.state = 457 + self.state = 461 self.block() except RecognitionException as re: localctx.exception = re @@ -3756,29 +3765,29 @@ def if_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 459 + self.state = 463 self.match(HarmonyParser.IF) - self.state = 460 + self.state = 464 self.expr() - self.state = 461 + self.state = 465 self.match(HarmonyParser.COLON) - self.state = 462 - self.block() self.state = 466 + self.block() + self.state = 470 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.ELIF: - self.state = 463 + self.state = 467 self.elif_block() - self.state = 468 + self.state = 472 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 470 + self.state = 474 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.ELSE: - self.state = 469 + self.state = 473 self.else_block() @@ -3791,6 +3800,114 @@ def if_block(self): return localctx + class Hyper_conditionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def NAME(self): + return self.getToken(HarmonyParser.NAME, 0) + + def getRuleIndex(self): + return HarmonyParser.RULE_hyper_condition + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitHyper_condition" ): + return visitor.visitHyper_condition(self) + else: + return visitor.visitChildren(self) + + + + + def hyper_condition(self): + + localctx = HarmonyParser.Hyper_conditionContext(self, self._ctx, self.state) + self.enterRule(localctx, 94, self.RULE_hyper_condition) + try: + self.enterOuterAlt(localctx, 1) + self.state = 476 + self.match(HarmonyParser.T__23) + self.state = 477 + self.match(HarmonyParser.NAME) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class Hyperassert_stmtContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def HYPER(self): + return self.getToken(HarmonyParser.HYPER, 0) + + def OPEN_PAREN(self): + return self.getToken(HarmonyParser.OPEN_PAREN, 0) + + def hyper_condition(self): + return self.getTypedRuleContext(HarmonyParser.Hyper_conditionContext,0) + + + def CLOSE_PAREN(self): + return self.getToken(HarmonyParser.CLOSE_PAREN, 0) + + def comp_op(self): + return self.getTypedRuleContext(HarmonyParser.Comp_opContext,0) + + + def expr(self): + return self.getTypedRuleContext(HarmonyParser.ExprContext,0) + + + def getRuleIndex(self): + return HarmonyParser.RULE_hyperassert_stmt + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitHyperassert_stmt" ): + return visitor.visitHyperassert_stmt(self) + else: + return visitor.visitChildren(self) + + + + + def hyperassert_stmt(self): + + localctx = HarmonyParser.Hyperassert_stmtContext(self, self._ctx, self.state) + self.enterRule(localctx, 96, self.RULE_hyperassert_stmt) + try: + self.enterOuterAlt(localctx, 1) + self.state = 479 + self.match(HarmonyParser.HYPER) + self.state = 480 + self.match(HarmonyParser.OPEN_PAREN) + self.state = 481 + self.hyper_condition() + self.state = 482 + self.match(HarmonyParser.CLOSE_PAREN) + self.state = 483 + self.comp_op() + self.state = 484 + self.expr() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Block_stmtsContext(ParserRuleContext): __slots__ = 'parser' @@ -3820,20 +3937,20 @@ def accept(self, visitor:ParseTreeVisitor): def block_stmts(self): localctx = HarmonyParser.Block_stmtsContext(self, self._ctx, self.state) - self.enterRule(localctx, 94, self.RULE_block_stmts) + self.enterRule(localctx, 98, self.RULE_block_stmts) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 473 + self.state = 487 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 472 + self.state = 486 self.stmt() - self.state = 475 + self.state = 489 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0)): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.HYPER - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0)): break except RecognitionException as re: @@ -3875,19 +3992,19 @@ def accept(self, visitor:ParseTreeVisitor): def block(self): localctx = HarmonyParser.BlockContext(self, self._ctx, self.state) - self.enterRule(localctx, 96, self.RULE_block) + self.enterRule(localctx, 100, self.RULE_block) try: - self.state = 479 + self.state = 493 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.INDENT]: self.enterOuterAlt(localctx, 1) - self.state = 477 + self.state = 491 self.normal_block() pass elif token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.POINTER_OF, HarmonyParser.PRINT, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.STRING]: self.enterOuterAlt(localctx, 2) - self.state = 478 + self.state = 492 self.one_line_stmt() pass else: @@ -3947,36 +4064,36 @@ def accept(self, visitor:ParseTreeVisitor): def normal_block(self): localctx = HarmonyParser.Normal_blockContext(self, self._ctx, self.state) - self.enterRule(localctx, 98, self.RULE_normal_block) + self.enterRule(localctx, 102, self.RULE_normal_block) try: self.enterOuterAlt(localctx, 1) - self.state = 481 + self.state = 495 self.match(HarmonyParser.INDENT) - self.state = 485 + self.state = 499 self._errHandler.sync(self) token = self._input.LA(1) - if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.COLON, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: - self.state = 482 + if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.COLON, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.HYPER, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: + self.state = 496 self.block_stmts() pass elif token in [HarmonyParser.INDENT]: - self.state = 483 + self.state = 497 self.match(HarmonyParser.INDENT) - self.state = 484 + self.state = 498 self.block() pass else: raise NoViableAltException(self) - self.state = 487 + self.state = 501 self.match(HarmonyParser.DEDENT) - self.state = 490 + self.state = 504 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,42,self._ctx) if la_ == 1: - self.state = 488 + self.state = 502 self.match(HarmonyParser.SEMI_COLON) - self.state = 489 + self.state = 503 self.match(HarmonyParser.NL) @@ -4074,93 +4191,93 @@ def accept(self, visitor:ParseTreeVisitor): def simple_stmt(self): localctx = HarmonyParser.Simple_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 100, self.RULE_simple_stmt) + self.enterRule(localctx, 104, self.RULE_simple_stmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 493 + self.state = 507 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.ATOMICALLY: - self.state = 492 + self.state = 506 self.match(HarmonyParser.ATOMICALLY) - self.state = 510 + self.state = 524 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,44,self._ctx) if la_ == 1: - self.state = 495 + self.state = 509 self.assign_stmt() pass elif la_ == 2: - self.state = 496 + self.state = 510 self.const_assign_stmt() pass elif la_ == 3: - self.state = 497 + self.state = 511 self.await_stmt() pass elif la_ == 4: - self.state = 498 + self.state = 512 self.var_stmt() pass elif la_ == 5: - self.state = 499 + self.state = 513 self.invariant_stmt() pass elif la_ == 6: - self.state = 500 + self.state = 514 self.del_stmt() pass elif la_ == 7: - self.state = 501 + self.state = 515 self.spawn_stmt() pass elif la_ == 8: - self.state = 502 + self.state = 516 self.trap_stmt() pass elif la_ == 9: - self.state = 503 + self.state = 517 self.go_stmt() pass elif la_ == 10: - self.state = 504 + self.state = 518 self.print_stmt() pass elif la_ == 11: - self.state = 505 + self.state = 519 self.pass_stmt() pass elif la_ == 12: - self.state = 506 + self.state = 520 self.sequential_stmt() pass elif la_ == 13: - self.state = 507 + self.state = 521 self.assert_stmt() pass elif la_ == 14: - self.state = 508 + self.state = 522 self.aug_assign_stmt() pass elif la_ == 15: - self.state = 509 + self.state = 523 self.expr_stmt() pass @@ -4223,42 +4340,42 @@ def accept(self, visitor:ParseTreeVisitor): def compound_stmt(self): localctx = HarmonyParser.Compound_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 102, self.RULE_compound_stmt) + self.enterRule(localctx, 106, self.RULE_compound_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 513 + self.state = 527 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,45,self._ctx) if la_ == 1: - self.state = 512 + self.state = 526 self.match(HarmonyParser.ATOMICALLY) - self.state = 521 + self.state = 535 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.IF]: - self.state = 515 + self.state = 529 self.if_block() pass elif token in [HarmonyParser.WHILE]: - self.state = 516 + self.state = 530 self.while_block() pass elif token in [HarmonyParser.FOR]: - self.state = 517 + self.state = 531 self.for_block() pass elif token in [HarmonyParser.WHEN, HarmonyParser.LET]: - self.state = 518 + self.state = 532 self.let_when_block() pass elif token in [HarmonyParser.ATOMICALLY]: - self.state = 519 + self.state = 533 self.atomic_block() pass elif token in [HarmonyParser.DEF]: - self.state = 520 + self.state = 534 self.method_decl() pass else: @@ -4309,32 +4426,32 @@ def accept(self, visitor:ParseTreeVisitor): def one_line_stmt(self): localctx = HarmonyParser.One_line_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 104, self.RULE_one_line_stmt) + self.enterRule(localctx, 108, self.RULE_one_line_stmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 523 + self.state = 537 self.simple_stmt() - self.state = 530 + self.state = 544 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,48,self._ctx) if la_ == 1: - self.state = 525 + self.state = 539 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.SEMI_COLON: - self.state = 524 + self.state = 538 self.match(HarmonyParser.SEMI_COLON) - self.state = 527 + self.state = 541 self.match(HarmonyParser.NL) pass elif la_ == 2: - self.state = 528 + self.state = 542 self.match(HarmonyParser.SEMI_COLON) - self.state = 529 + self.state = 543 self.one_line_stmt() pass @@ -4382,22 +4499,22 @@ def accept(self, visitor:ParseTreeVisitor): def label(self): localctx = HarmonyParser.LabelContext(self, self._ctx, self.state) - self.enterRule(localctx, 106, self.RULE_label) + self.enterRule(localctx, 110, self.RULE_label) try: self.enterOuterAlt(localctx, 1) - self.state = 534 + self.state = 548 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 532 + self.state = 546 self.match(HarmonyParser.NAME) - self.state = 533 + self.state = 547 self.match(HarmonyParser.COLON) else: raise NoViableAltException(self) - self.state = 536 + self.state = 550 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,49,self._ctx) @@ -4439,6 +4556,10 @@ def import_stmt(self): return self.getTypedRuleContext(HarmonyParser.Import_stmtContext,0) + def hyperassert_stmt(self): + return self.getTypedRuleContext(HarmonyParser.Hyperassert_stmtContext,0) + + def label(self): return self.getTypedRuleContext(HarmonyParser.LabelContext,0) @@ -4464,86 +4585,91 @@ def accept(self, visitor:ParseTreeVisitor): def stmt(self): localctx = HarmonyParser.StmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 108, self.RULE_stmt) + self.enterRule(localctx, 112, self.RULE_stmt) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 561 + self.state = 576 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,55,self._ctx) if la_ == 1: - self.state = 542 + self.state = 556 self._errHandler.sync(self) token = self._input.LA(1) - if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: - self.state = 539 + if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.HYPER, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: + self.state = 553 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,50,self._ctx) if la_ == 1: - self.state = 538 + self.state = 552 self.label() pass elif token in [HarmonyParser.COLON]: - self.state = 541 + self.state = 555 self.match(HarmonyParser.COLON) pass else: raise NoViableAltException(self) - self.state = 554 + self.state = 569 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,53,self._ctx) if la_ == 1: - self.state = 547 + self.state = 561 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.SEMI_COLON: - self.state = 544 + self.state = 558 self.match(HarmonyParser.SEMI_COLON) - self.state = 549 + self.state = 563 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 550 + self.state = 564 self.match(HarmonyParser.NL) pass elif la_ == 2: - self.state = 551 + self.state = 565 self.one_line_stmt() pass elif la_ == 3: - self.state = 552 + self.state = 566 self.compound_stmt() pass elif la_ == 4: - self.state = 553 + self.state = 567 self.import_stmt() pass + elif la_ == 5: + self.state = 568 + self.hyperassert_stmt() + pass + pass elif la_ == 2: - self.state = 558 + self.state = 573 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.NAME]: - self.state = 556 + self.state = 571 self.label() pass elif token in [HarmonyParser.COLON]: - self.state = 557 + self.state = 572 self.match(HarmonyParser.COLON) pass else: raise NoViableAltException(self) - self.state = 560 + self.state = 575 self.normal_block() pass diff --git a/harmony_model_checker/parser/HarmonyVisitor.py b/harmony_model_checker/parser/HarmonyVisitor.py index 14259aa7..e9570064 100644 --- a/harmony_model_checker/parser/HarmonyVisitor.py +++ b/harmony_model_checker/parser/HarmonyVisitor.py @@ -294,6 +294,16 @@ def visitIf_block(self, ctx:HarmonyParser.If_blockContext): return self.visitChildren(ctx) + # Visit a parse tree produced by HarmonyParser#hyper_condition. + def visitHyper_condition(self, ctx:HarmonyParser.Hyper_conditionContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by HarmonyParser#hyperassert_stmt. + def visitHyperassert_stmt(self, ctx:HarmonyParser.Hyperassert_stmtContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by HarmonyParser#block_stmts. def visitBlock_stmts(self, ctx:HarmonyParser.Block_stmtsContext): return self.visitChildren(ctx) diff --git a/harmony_model_checker/parser/antlr_rule_visitor.py b/harmony_model_checker/parser/antlr_rule_visitor.py index dbac181d..ca1af9f4 100644 --- a/harmony_model_checker/parser/antlr_rule_visitor.py +++ b/harmony_model_checker/parser/antlr_rule_visitor.py @@ -435,6 +435,8 @@ def visitStmt(self, ctx: HarmonyParser.StmtContext): stmt = self.visit(ctx.compound_stmt()) elif ctx.import_stmt() is not None: stmt = self.visit(ctx.import_stmt()) + elif ctx.hyperassert_stmt() is not None: + stmt = self.visit(ctx.hyperassert_stmt()) elif ctx.normal_block() is not None: stmt = self.visit(ctx.normal_block()) else: @@ -630,6 +632,15 @@ def visitExpr_rule(self, ctx:HarmonyParser.Expr_ruleContext): lexeme=tkn[0] ) + def visitHyperassert_stmt(self, ctx): + # Does nothing for now + return [] + + def visitHyper_condition(self, ctx): + # Does nothing for now + return [] + + # Visit a parse tree produced by HarmonyParser#application. def visitApplication(self, ctx:HarmonyParser.ApplicationContext): tkn = self.get_token(ctx.start, ctx.start.text) From fcccb95cd1682c82c98cdf1a7b4421cc4c2e6146 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Mon, 14 Mar 2022 09:16:02 -0400 Subject: [PATCH 05/12] fixed variable name --- harmony_model_checker/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/harmony_model_checker/main.py b/harmony_model_checker/main.py index 7cde0e2a..5d962289 100644 --- a/harmony_model_checker/main.py +++ b/harmony_model_checker/main.py @@ -143,7 +143,7 @@ def handle_hco(ns, output_files): disable_browser = settings.values.disable_web or ns.noweb b = Brief() - b.run(output_files, behavior, probabilistic) + b.run(output_files, behavior, probability_states) gh = GenHTML() gh.run(output_files) if not suppress_output: From 260c669c2cde9b9b5876f7164327d88777d8bf24 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Mon, 14 Mar 2022 11:37:01 -0400 Subject: [PATCH 06/12] filter implemented but crashes --- harmony_model_checker/charm/charm.c | 114 ++++++++++++++++++++------- harmony_model_checker/charm/filter.c | 29 +++++++ harmony_model_checker/charm/filter.h | 18 +++++ harmony_model_checker/charm/graph.h | 7 ++ harmony_model_checker/charm/vector.h | 15 ++++ 5 files changed, 153 insertions(+), 30 deletions(-) create mode 100644 harmony_model_checker/charm/filter.c create mode 100644 harmony_model_checker/charm/filter.h create mode 100644 harmony_model_checker/charm/vector.h diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 3f5f9619..892e242a 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -24,9 +24,11 @@ #include "strbuf.h" #include "iface/iface.h" #include "hashdict.h" +#include "hashset.h" #include "dfa.h" #include "thread.h" #include "spawn.h" +#include "filter.h" #define WALLOC_CHUNK (1024 * 1024) @@ -67,6 +69,8 @@ struct worker { // These need to be next to one another struct context ctx; hvalue_t stack[MAX_CONTEXT_STACK]; + + struct filter_t filters; // filters states for probability checking }; // Per thread one-time memory allocator (no free) @@ -213,7 +217,8 @@ static bool onestep( hvalue_t choice, // if about to make a choice, which choice? bool interrupt, // start with invoking interrupt handler bool infloop_detect, // try to detect infloop from the start - int multiplicity // #contexts that are in the current state + int multiplicity, // #contexts that are in the current state + struct filter_t filter ) { assert(!step->ctx->terminated); assert(step->ctx->failure == 0); @@ -238,10 +243,19 @@ static bool onestep( bool rollback = false, failure = false, stopped = false; bool terminated = false; int choice_size = 1; // Number of choices to make. It is 1 + int filterstates[20]; + int filter_len = 0; for (;;) { int pc = step->ctx->pc; - // If I'm pthread 0 and it's time, print some stats + for (int i = 0; i < filter.len; ++i) { + // if (filter.conditions[i].pc == pc) { + // filterstates[filter_len] = i; + // ++filter_len; + // } + } + + // If I'm phread 0 and it's time, print some stats if (w->index == 0 && w->timecnt-- == 0) { double now = gettime(); if (now - global->lasttime > 1) { @@ -468,6 +482,7 @@ static bool onestep( // Weight of this step int weight = ctx == node->after ? 0 : 1; +<<<<<<< HEAD // Allocate edge now struct edge *edge = walloc(w, sizeof(struct edge), false); edge->ctx = ctx; @@ -498,6 +513,7 @@ static bool onestep( next->choice = choice_copy; next->choice_size = choice_size; next->interrupt = interrupt; + next->filter_len = 0; } } else { @@ -511,6 +527,7 @@ static bool onestep( next->len = node->len + weight; next->steps = node->steps + instrcnt; next->choice_size = choice_size; + next->filter_len = 0; *w->last = next; w->last = &next->next; k->value = next; @@ -559,7 +576,8 @@ static void make_step( struct node *node, hvalue_t ctx, hvalue_t choice, // if about to make a choice, which choice? - int multiplicity // #contexts that are in the current state + int multiplicity, // #contexts that are in the current state + struct filter_t filter ) { struct step step; memset(&step, 0, sizeof(step)); @@ -577,9 +595,9 @@ static void make_step( // See if we need to interrupt if (sc.choosing == 0 && cc->trap_pc != 0 && !cc->interruptlevel) { - bool succ = onestep(w, node, &sc, ctx, &step, choice, true, false, multiplicity); + bool succ = onestep(w, node, &sc, ctx, &step, choice, true, false, multiplicity, filter); if (!succ) { // ran into an infinite loop - (void) onestep(w, node, &sc, ctx, &step, choice, true, true, multiplicity); + (void) onestep(w, node, &sc, ctx, &step, choice, true, true, multiplicity, filter); } sc = node->state; @@ -587,9 +605,9 @@ static void make_step( } sc.choosing = 0; - bool succ = onestep(w, node, &sc, ctx, &step, choice, false, false, multiplicity); + bool succ = onestep(w, node, &sc, ctx, &step, choice, false, false, multiplicity, filter); if (!succ) { // ran into an infinite loop - (void) onestep(w, node, &sc, ctx, &step, choice, false, true, multiplicity); + (void) onestep(w, node, &sc, ctx, &step, choice, false, true, multiplicity, filter); } } @@ -1533,7 +1551,8 @@ static void do_work(struct worker *w){ node, state->choosing, vals[i], - 1 + 1, + w->filter ); } } @@ -1550,7 +1569,8 @@ static void do_work(struct worker *w){ node, ctxs[i], 0, - VALUE_FROM_INT(ctxs[i+1]) + VALUE_FROM_INT(ctxs[i+1]), + w->filter ); } } @@ -1888,6 +1908,12 @@ int main(int argc, char **argv){ assert(jc->type == JV_LIST); global->code = code_init_parse(&engine, jc); + struct json_value *filt = dict_lookup(jv->u.map, "filter", 6); + + // Create filters + // TODO: Do I want to heap allocate this? + struct filter_t filters = create_filter(filt); + // Create an initial state struct context *init_ctx = calloc(1, sizeof(struct context) + MAX_CONTEXT_STACK * sizeof(hvalue_t)); init_ctx->name = global->init_name; @@ -1956,6 +1982,7 @@ int main(int argc, char **argv){ w->nworkers = nworkers; w->visited = visited; w->last = &w->results; + w->filter = filters; // Create a context for evaluating invariants w->inv_step.ctx = calloc(1, sizeof(struct context) + @@ -2232,32 +2259,59 @@ int main(int argc, char **argv){ if (probabilistic) { fprintf(out, " \"probabilities\": [\n"); - bool first = true; - for (int i = 0; i < global->graph.size; i++) { - struct node *node = global->graph.nodes[i]; - assert(node->id == i); + { + bool first = true; + for (int i = 0; i < global->graph.size; i++) { + struct node *node = global->graph.nodes[i]; + assert(node->id == i); - for (struct edge *edge = node->fwd; edge != NULL; edge = edge->fwdnext) { - if (first) { - first = false; - } else { - fprintf(out, ",\n"); - } + for (struct edge *edge = node->fwd; edge != NULL; edge = edge->fwdnext) { + if (first) { + first = false; + } else { + fprintf(out, ",\n"); + } - fprintf( - out, - " {\"from\": %d, \"to\": %d, \"probability\": {\"numerator\": %d, \"denominator\": %d}}", - i, - edge->dst->id, - edge->probability_numerator, - edge->probability_denominator - ); + fprintf( + out, + " {\"from\": %d, \"to\": %d, \"probability\": {\"numerator\": %d, \"denominator\": %d}}", + i, + edge->dst->id, + edge->probability_numerator, + edge->probability_denominator + ); + } } - } - fprintf(out, "\n"); - fprintf(out, " ],\n"); + fprintf(out, "\n"); + fprintf(out, " ],\n"); + } fprintf(out, " \"total_states\": %d,\n", global->graph.size); + + fprintf(out, " \"filter_states\": [\n"); + + // { + // bool first = true; + // for (int i = 0; i < global->graph.size; i++) { + // struct node *node = global->graph.nodes[i]; + // assert(node->id == i); + + // for (int j = 0; j < node->filter_len; j++) { + // if (first) { + // first = false; + // } else { + // fprintf(out, ",\n"); + // } + + // fprintf( + // out, + // " {\"state\": %d, \"query\": %d}", + // i, + // node->filter_states[i] + // ); + // } + // } + // } } diff --git a/harmony_model_checker/charm/filter.c b/harmony_model_checker/charm/filter.c new file mode 100644 index 00000000..80442da2 --- /dev/null +++ b/harmony_model_checker/charm/filter.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include "hashdict.h" +#include "filter.h" + +struct filter_t create_filter(struct json_value* val) { + assert(val->type == JV_LIST); + + struct filter_t filter; + filter.len = val->u.list.nvals; + filter.conditions = malloc(filter.len * sizeof(struct condition_t)); + + for (unsigned int i = 0; i < val->u.list.nvals; i++) { + struct condition_t cond; + struct json_value* cond_map = val->u.list.vals[i]; + struct json_value* pc = dict_lookup(cond_map->u.map, "pc", 2); + assert(pc->type == JV_ATOM); + + char *copy = malloc(pc->u.atom.len + 1); + memcpy(copy, pc->u.atom.base, pc->u.atom.len); + copy[pc->u.atom.len] = 0; + cond.pc = atoi(copy); + free(copy); + + filter.conditions[i] = cond; + } + return filter; +} diff --git a/harmony_model_checker/charm/filter.h b/harmony_model_checker/charm/filter.h new file mode 100644 index 00000000..e9efa85e --- /dev/null +++ b/harmony_model_checker/charm/filter.h @@ -0,0 +1,18 @@ +#ifndef FILTER_H +#define FILTER_H + +#include "json.h" + +// TODO +struct condition_t { + int pc; +}; + +struct filter_t { + struct condition_t* conditions; + int len; +}; + +struct filter_t create_filter(struct json_value* val); + +#endif diff --git a/harmony_model_checker/charm/graph.h b/harmony_model_checker/charm/graph.h index bc51aaa3..207893a5 100644 --- a/harmony_model_checker/charm/graph.h +++ b/harmony_model_checker/charm/graph.h @@ -5,6 +5,7 @@ #include "value.h" #include "minheap.h" #include "thread.h" +#include "hashset.h" struct component { bool good; // terminating or out-going edge @@ -75,6 +76,12 @@ struct node { // NFA compression bool reachable; + + // Whether this is a state that we are interested in (for probabiliy + // checking) + // TODO: Don't know if this is a good idea + int filter_states[20]; + int filter_len; }; struct failure { diff --git a/harmony_model_checker/charm/vector.h b/harmony_model_checker/charm/vector.h new file mode 100644 index 00000000..72b526e4 --- /dev/null +++ b/harmony_model_checker/charm/vector.h @@ -0,0 +1,15 @@ +#ifndef VECTOR_H +#define VECTOR_H + + +struct intvector { + int* v; + int len; + int capacity; +} + +void push(struct intvector*, int v) { + +} + +#endif From 4e9104674f0961c577f297019f336aeafb03428c Mon Sep 17 00:00:00 2001 From: attilusleung Date: Mon, 4 Apr 2022 02:46:02 -0400 Subject: [PATCH 07/12] vector and charm filter states --- Makefile | 2 +- harmony_model_checker/charm/charm.c | 67 +++++++++++++--------------- harmony_model_checker/charm/graph.h | 5 +-- harmony_model_checker/charm/vector.c | 26 +++++++++++ harmony_model_checker/charm/vector.h | 11 +++-- harmony_model_checker/harmony/ast.py | 4 ++ harmony_model_checker/main.py | 2 +- 7 files changed, 73 insertions(+), 44 deletions(-) create mode 100644 harmony_model_checker/charm/vector.c diff --git a/Makefile b/Makefile index 2081e001..06b0dc8e 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ gen: chmod +x harmony charm: - gcc -Iharmony_model_checker/charm -Iharmony_model_checker/charm/iface -o charm.exe -pthread harmony_model_checker/charm/*.c harmony_model_checker/charm/iface/*.c + gcc -ggdb -Wall -Werror -Iharmony_model_checker/charm -Iharmony_model_checker/charm/iface -o charm.exe -pthread harmony_model_checker/charm/*.c harmony_model_checker/charm/iface/*.c behavior: x.hny ./harmony -o x.hny diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 892e242a..0675f4e4 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -29,6 +29,7 @@ #include "thread.h" #include "spawn.h" #include "filter.h" +#include "vector.h" #define WALLOC_CHUNK (1024 * 1024) @@ -243,16 +244,14 @@ static bool onestep( bool rollback = false, failure = false, stopped = false; bool terminated = false; int choice_size = 1; // Number of choices to make. It is 1 - int filterstates[20]; - int filter_len = 0; + struct int_vector filterstates = int_vector_init(20); for (;;) { int pc = step->ctx->pc; for (int i = 0; i < filter.len; ++i) { - // if (filter.conditions[i].pc == pc) { - // filterstates[filter_len] = i; - // ++filter_len; - // } + if (filter.conditions[i].pc == pc) { + int_vector_push(&filterstates, i); + } } // If I'm phread 0 and it's time, print some stats @@ -482,7 +481,6 @@ static bool onestep( // Weight of this step int weight = ctx == node->after ? 0 : 1; -<<<<<<< HEAD // Allocate edge now struct edge *edge = walloc(w, sizeof(struct edge), false); edge->ctx = ctx; @@ -513,7 +511,7 @@ static bool onestep( next->choice = choice_copy; next->choice_size = choice_size; next->interrupt = interrupt; - next->filter_len = 0; + next->filter_states = filterstates; } } else { @@ -527,7 +525,6 @@ static bool onestep( next->len = node->len + weight; next->steps = node->steps + instrcnt; next->choice_size = choice_size; - next->filter_len = 0; *w->last = next; w->last = &next->next; k->value = next; @@ -2257,9 +2254,8 @@ int main(int argc, char **argv){ fprintf(out, " \"issue\": \"No issues\",\n"); if (probabilistic) { - fprintf(out, " \"probabilities\": [\n"); - { + fprintf(out, " \"probabilities\": [\n"); bool first = true; for (int i = 0; i < global->graph.size; i++) { struct node *node = global->graph.nodes[i]; @@ -2288,30 +2284,31 @@ int main(int argc, char **argv){ } fprintf(out, " \"total_states\": %d,\n", global->graph.size); - fprintf(out, " \"filter_states\": [\n"); - - // { - // bool first = true; - // for (int i = 0; i < global->graph.size; i++) { - // struct node *node = global->graph.nodes[i]; - // assert(node->id == i); - - // for (int j = 0; j < node->filter_len; j++) { - // if (first) { - // first = false; - // } else { - // fprintf(out, ",\n"); - // } - - // fprintf( - // out, - // " {\"state\": %d, \"query\": %d}", - // i, - // node->filter_states[i] - // ); - // } - // } - // } + { + fprintf(out, " \"filter_states\": [\n"); + bool first = true; + for (int i = 0; i < global->graph.size; i++) { + struct node *node = global->graph.nodes[i]; + assert(node->id == i); + + for (int j = 0; j < node->filter_states.len; j++) { + if (first) { + first = false; + } else { + fprintf(out, ",\n"); + } + + fprintf( + out, + " {\"query\": %d, \"state\": %d}", + int_vector_get(&node->filter_states, j), + i + ); + } + } + fprintf(out, "\n"); + fprintf(out, " ],\n"); + } } diff --git a/harmony_model_checker/charm/graph.h b/harmony_model_checker/charm/graph.h index 207893a5..94db9eb5 100644 --- a/harmony_model_checker/charm/graph.h +++ b/harmony_model_checker/charm/graph.h @@ -6,6 +6,7 @@ #include "minheap.h" #include "thread.h" #include "hashset.h" +#include "vector.h" struct component { bool good; // terminating or out-going edge @@ -79,9 +80,7 @@ struct node { // Whether this is a state that we are interested in (for probabiliy // checking) - // TODO: Don't know if this is a good idea - int filter_states[20]; - int filter_len; + struct int_vector filter_states; }; struct failure { diff --git a/harmony_model_checker/charm/vector.c b/harmony_model_checker/charm/vector.c new file mode 100644 index 00000000..e78f8d04 --- /dev/null +++ b/harmony_model_checker/charm/vector.c @@ -0,0 +1,26 @@ +#include +#include +#include "vector.h" + +struct int_vector int_vector_init(int capacity) { + struct int_vector vec; + vec.capacity = capacity; + vec.len = 0; + vec.v = malloc(sizeof(int) * vec.capacity); + return vec; +} + + +void int_vector_push(struct int_vector* vec, int v) { + if (vec->len >= vec->capacity) { + vec->v = realloc(vec->v, sizeof(int) * (vec->capacity * 2)); + } + vec->v[vec->len] = v; + ++ vec->len; +} + + +int int_vector_get(struct int_vector* vec, int i) { + assert(i < vec->len); + return vec->v[i]; +} diff --git a/harmony_model_checker/charm/vector.h b/harmony_model_checker/charm/vector.h index 72b526e4..dfb80a77 100644 --- a/harmony_model_checker/charm/vector.h +++ b/harmony_model_checker/charm/vector.h @@ -1,15 +1,18 @@ #ifndef VECTOR_H #define VECTOR_H +// A simple vector implementation -struct intvector { +struct int_vector { int* v; int len; int capacity; -} +}; -void push(struct intvector*, int v) { +struct int_vector int_vector_init(int); -} +void int_vector_push(struct int_vector*, int); + +int int_vector_get(struct int_vector*, int); #endif diff --git a/harmony_model_checker/harmony/ast.py b/harmony_model_checker/harmony/ast.py index c4b9873b..fbf3fdcc 100644 --- a/harmony_model_checker/harmony/ast.py +++ b/harmony_model_checker/harmony/ast.py @@ -1722,3 +1722,7 @@ def compile(self, scope, code): def accept_visitor(self, visitor, *args, **kwargs): return visitor.visit_const(self, *args, **kwargs) + +class HyperassertAST(AST): + def __init__(self, token): + super().__init__(self, token, True) diff --git a/harmony_model_checker/main.py b/harmony_model_checker/main.py index 5d962289..d86d70d5 100644 --- a/harmony_model_checker/main.py +++ b/harmony_model_checker/main.py @@ -51,7 +51,7 @@ help="get or set configuration value. " "Use --config to get the value of a setting. " "Use --config to set the value of a setting") -args.add_argument("--probabilistic", type=str, +args.add_argument("--probabilistic", action="store_true" help="use probabilistic model checking") # Internal flags From 1d9644fd1b41271295a53f4606820eb03f1c7ce0 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Mon, 11 Apr 2022 18:38:51 -0400 Subject: [PATCH 08/12] functionally complete version of probabilistic model checking --- Harmony.g4 | 4 +- harmony_model_checker/charm/charm.c | 7 +- harmony_model_checker/compile.py | 1 - harmony_model_checker/harmony/ast.py | 40 +- harmony_model_checker/harmony/brief.py | 4 +- harmony_model_checker/harmony/buildversion | 1 + harmony_model_checker/harmony/code.py | 7 +- harmony_model_checker/harmony/harmony.py | 7 + .../harmony/probabilities.py | 98 ++++- harmony_model_checker/main.py | 10 +- harmony_model_checker/parser/HarmonyLexer.py | 83 ++-- harmony_model_checker/parser/HarmonyParser.py | 354 +++++++++--------- .../parser/antlr_rule_visitor.py | 16 +- 13 files changed, 386 insertions(+), 246 deletions(-) create mode 100644 harmony_model_checker/harmony/buildversion diff --git a/Harmony.g4 b/Harmony.g4 index 0638fcc9..66f83b68 100644 --- a/Harmony.g4 +++ b/Harmony.g4 @@ -221,7 +221,7 @@ else_block: ELSE COLON block; if_block: IF expr COLON block elif_block* else_block?; // TODO: atLabel is duplicated. Is this a problem? -hyper_condition: 'atLabel' NAME; +hyper_condition: NAME; hyperassert_stmt: HYPER OPEN_PAREN hyper_condition CLOSE_PAREN comp_op expr; block_stmts: stmt+; @@ -325,12 +325,12 @@ IN : 'in' { if self.opened_for > 0: self.opened_for -= 1 }; +HYPER : 'hyper_assert'; COLON : ':'; NONE : 'None'; ATOMICALLY: 'atomically'; BOOL : 'False' | 'True'; ETERNAL: 'eternal'; -HYPER : 'hyper_assert'; // STRING : '"' .*? '"' | '\'' .*? '\''; INT : [0-9]+ | 'inf'; diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 0675f4e4..0cb86a9d 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -1549,7 +1549,7 @@ static void do_work(struct worker *w){ state->choosing, vals[i], 1, - w->filter + w->filters ); } } @@ -1567,7 +1567,7 @@ static void do_work(struct worker *w){ ctxs[i], 0, VALUE_FROM_INT(ctxs[i+1]), - w->filter + w->filters ); } } @@ -1908,7 +1908,6 @@ int main(int argc, char **argv){ struct json_value *filt = dict_lookup(jv->u.map, "filter", 6); // Create filters - // TODO: Do I want to heap allocate this? struct filter_t filters = create_filter(filt); // Create an initial state @@ -1979,7 +1978,7 @@ int main(int argc, char **argv){ w->nworkers = nworkers; w->visited = visited; w->last = &w->results; - w->filter = filters; + w->filters = filters; // Create a context for evaluating invariants w->inv_step.ctx = calloc(1, sizeof(struct context) + diff --git a/harmony_model_checker/compile.py b/harmony_model_checker/compile.py index 61bf1f41..b3c516cc 100644 --- a/harmony_model_checker/compile.py +++ b/harmony_model_checker/compile.py @@ -106,7 +106,6 @@ def _load_file(filename: str, scope: Scope, code: Code): ast.compile(scope, code) legacy_harmony.namestack.pop() - def _do_import(scope: Scope, code: Code, module): (lexeme, file, line, column) = module # assert lexeme not in scope.names # TODO diff --git a/harmony_model_checker/harmony/ast.py b/harmony_model_checker/harmony/ast.py index fbf3fdcc..9b526bb6 100644 --- a/harmony_model_checker/harmony/ast.py +++ b/harmony_model_checker/harmony/ast.py @@ -1724,5 +1724,41 @@ def accept_visitor(self, visitor, *args, **kwargs): class HyperassertAST(AST): - def __init__(self, token): - super().__init__(self, token, True) + def __init__(self, token, condition, compare_op, expected): + super().__init__(token, True) + self.condition = condition + self.compare_op = compare_op + self.expected = expected + + def __repr__(self): + return f"Hyperassert({self.condition}, {self.expected})" + + def compile(self, scope, code): + code.hypers.append(( + self.token, + self.condition.compile(scope, code), + (self.compare_op, self.expected) + )) + + +# TODO: Make more extensible +class HyperConditionAST(AST): + def __init__(self, token, label): + super().__init__(token, True) + self.label = label + + def __repr__(self): + return f"HyperCondition({self.label})" + + def compile(self, scope, code): + # If we can find the label/constant, then create a hyperproperty + if self.label[0] in scope.names and scope.names[self.label[0]][0] == "constant": + return {"pc": scope.names[self.label[0]][1][0]} + else: + raise HarmonyCompilerError( + filename=self.token[1], + lexeme=self.token[0], + line=self.token[2], + column=self.token[3], + message=f"Label `{self.label[0]}` not found in the program" + ) diff --git a/harmony_model_checker/harmony/brief.py b/harmony_model_checker/harmony/brief.py index fc2b16de..dfd20a69 100644 --- a/harmony_model_checker/harmony/brief.py +++ b/harmony_model_checker/harmony/brief.py @@ -131,14 +131,14 @@ def print_macrostep(self, mas): self.failure = self.lastmis["failure"] self.interrupted = "interrupt" in self.lastmis and self.lastmis["interrupt"] == "True" - def run(self, outputfiles, behavior, probability_states): + def run(self, outputfiles, behavior, code, scope): with open(outputfiles["hco"], encoding='utf-8') as f: print("Phase 5: loading", outputfiles["hco"]) top = json.load(f) assert isinstance(top, dict) if top["issue"] == "No issues": behavior_parse(top, True, outputfiles, behavior) - find_probabilities(top, probability_states, outputfiles) + find_probabilities(top, outputfiles, code, scope) return True # print("Issue:", top["issue"]) diff --git a/harmony_model_checker/harmony/buildversion b/harmony_model_checker/harmony/buildversion new file mode 100644 index 00000000..c527f8c8 --- /dev/null +++ b/harmony_model_checker/harmony/buildversion @@ -0,0 +1 @@ +1,2, 2159 diff --git a/harmony_model_checker/harmony/code.py b/harmony_model_checker/harmony/code.py index 682bf901..350efafd 100644 --- a/harmony_model_checker/harmony/code.py +++ b/harmony_model_checker/harmony/code.py @@ -16,6 +16,7 @@ def __init__(self): self.endlabels = set() self.curFile = None self.curLine = 0 + self.hypers = [] def location(self, file, line): self.curFile = file @@ -89,6 +90,7 @@ def liveness(self): lop.live_out = live_out # Create new code with DelVars inserted newcode = Code() + newcode.hypers = self.hypers for lop in self.labeled_ops: # print(lop.op, lop.live_in, lop.live_out) file, line = lop.file, lop.line @@ -126,4 +128,7 @@ def link(self): map[label] = PcValue(pc) for lop in self.labeled_ops: lop.op.substitute(map) - + print(self.hypers) + for h in self.hypers: + if "pc" in h[1]: + h[1]["pc"] = h[1]["pc"].substitute(map).pc diff --git a/harmony_model_checker/harmony/harmony.py b/harmony_model_checker/harmony/harmony.py index 12bc9273..099a8ca6 100644 --- a/harmony_model_checker/harmony/harmony.py +++ b/harmony_model_checker/harmony/harmony.py @@ -1173,8 +1173,15 @@ def htmldump(nodes, code, scope, node, fulldump, verbose): def dumpCode(printCode, code, scope, f=sys.stdout): lastloc = None + print(code.hypers) if printCode == "json": print("{", file=f) + print(" \"filter\": [", file=f) + for d in code.hypers: + print("excuse") + print(d) + print(f" {json.dumps(d[1])},", file=f) + print(" ],", file=f) print(' "labels": {', file=f) if True: for (k, v) in scope.labels.items(): diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py index e95210a5..1813733b 100644 --- a/harmony_model_checker/harmony/probabilities.py +++ b/harmony_model_checker/harmony/probabilities.py @@ -1,12 +1,19 @@ from collections import defaultdict +import math import numpy as np +import json # TODO: This is just a simple port of charmpp. We probably want extended # functionality here. -def find_probabilities(top, states, outputfiles): +def find_probabilities(top, outputfiles, code, scope): if outputfiles['hpo'] is None: return + states = defaultdict(list) + + for o in top["filter_states"]: + states[o['query']].append(o['state']) + transitions = defaultdict(list) total_states = top['total_states'] matrix = np.zeros((total_states, total_states)) @@ -15,12 +22,88 @@ def find_probabilities(top, states, outputfiles): assert p['probability']['numerator'] != 0 matrix[p['from']][p['to']] = p['probability']['numerator'] / p['probability']['denominator'] transitions[p['from']].append(p['to']) - print(transitions) + # print(transitions) + + ret = [] + + # TODO: Make this more clear instead of using an arbitary id + for i in range(len(code.hypers)): + s = set(states[i]) + + if i not in states: + got_prob = 0 + else: + got_prob = gen_prob(s, total_states, transitions, matrix).get(0, 0.0) - states = set(int(s.strip()) for s in states.split(",")) + if code is not None: + try: + # This might throw an error, because it is an arbitary harmony + # expression. Might want to change this in the future. + expected_prob = eval(code.hypers[i][2][1]) + except SyntaxError: + print("WARNING: Cannot eval expected value for assertion {code.hypers[i][0][0]} in {code.hypers[i][0][1]}, {code.hypers[i][0][2]}, {code.hypers[i][0][3]}. Ignoring.") + + if code.hypers[i][2][0] == "==" and not math.isclose(got_prob, expected_prob): + print( + f"WARNING: Expected probabiliity {expected_prob} for assertion " + f"{code.hypers[i][0][0]} in {code.hypers[i][0][1]}, " + f"{code.hypers[i][0][2]}:{code.hypers[i][0][3]} but got " + f"{got_prob}" + ) + elif code.hypers[i][2][0] == "!=" and math.isclose(got_prob, expected_prob): + print( + "WARNING: Expected probabiliity not be equal to " + f"{expected_prob} for assertion {code.hypers[i][0][0]} in " + f"{code.hypers[i][0][1]}, {code.hypers[i][0][2]}:" + f"{code.hypers[i][0][3]} but got {got_prob}" + ) + elif code.hypers[i][2][0] == "<" and (math.isclose(got_prob, expected_prob) or got_prob > expected_prob): + print( + "WARNING: Expected probabiliity to be less than " + f"{expected_prob} for assertion {code.hypers[i][0][0]} in " + f"{code.hypers[i][0][1]}, {code.hypers[i][0][2]}:" + f"{code.hypers[i][0][3]} but got {got_prob}" + ) + elif code.hypers[i][2][0] == ">" and (math.isclose(got_prob, expected_prob) or got_prob < expected_prob): + print( + "WARNING: Expected probabiliity to be larger than " + f"{expected_prob} for assertion {code.hypers[i][0][0]} in " + f"{code.hypers[i][0][1]}, {code.hypers[i][0][2]}:" + f"{code.hypers[i][0][3]} but got {got_prob}" + ) + elif code.hypers[i][2][0] == "<=" and (not math.isclose(got_prob, expected_prob) and got_prob > expected_prob): + print( + "WARNING: Expected probabiliity to be less than or equal to " + f"{expected_prob} for assertion {code.hypers[i][0][0]} in " + f"{code.hypers[i][0][1]}, {code.hypers[i][0][2]}:" + f"{code.hypers[i][0][3]} but got {got_prob}" + ) + elif code.hypers[i][2][0] == ">=" and (not math.isclose(got_prob, expected_prob) and got_prob < expected_prob): + print( + "WARNING: Expected probabiliity to be larger or equal to " + f"{expected_prob} for assertion {code.hypers[i][0][0]} in " + f"{code.hypers[i][0][1]}, {code.hypers[i][0][2]}:" + f"{code.hypers[i][0][3]} but got {got_prob}" + ) + ret.append({ + "assertion": code.hypers[i][0][0], + "file": code.hypers[i][0][1], + "line": code.hypers[i][0][2], + "column": code.hypers[i][0][3], + "probability": got_prob, + }) + else: + ret.append(got_prob) + + with open(outputfiles['hpo'], 'w') as f: + json.dump({"probabilities": ret}, f, indent=2) + + +def gen_prob(states, total_states, transitions, matrix): reachable_states = [] list_b = [] + for i in range(total_states): if i in states: continue @@ -28,11 +111,17 @@ def find_probabilities(top, states, outputfiles): reachable_states.append(i) list_b.append(np.sum(matrix[i][list(states)])) + if not reachable_states: + return {} + reachable_states = np.array(reachable_states) + print(reachable_states) matrix_a = np.identity(len(reachable_states)) - matrix[np.ix_(reachable_states, reachable_states)] + print(matrix_a, list_b) probabilities = np.linalg.solve(matrix_a, list_b) - np.savetxt(outputfiles['hpo'], np.stack((reachable_states, probabilities), axis=1), delimiter=",") + # print(reachable_states, probabilities) + return dict(zip(reachable_states, probabilities)) """ @@ -44,7 +133,6 @@ def is_reachable(state, transitions, goals): visited = set() def search(s): - print(s) if s in goals: return True if s in visited: diff --git a/harmony_model_checker/main.py b/harmony_model_checker/main.py index d86d70d5..fcf81564 100644 --- a/harmony_model_checker/main.py +++ b/harmony_model_checker/main.py @@ -51,7 +51,7 @@ help="get or set configuration value. " "Use --config to get the value of a setting. " "Use --config to set the value of a setting") -args.add_argument("--probabilistic", action="store_true" +args.add_argument("--probabilistic", action="store_true", help="use probabilistic model checking") # Internal flags @@ -129,7 +129,7 @@ def handle_hvm(ns, output_files, parse_code_only, code, scope): print("charm model checker failed") exit(r) -def handle_hco(ns, output_files): +def handle_hco(ns, output_files, code=None, scope=None): suppress_output = ns.suppress behavior = None @@ -143,7 +143,7 @@ def handle_hco(ns, output_files): disable_browser = settings.values.disable_web or ns.noweb b = Brief() - b.run(output_files, behavior, probability_states) + b.run(output_files, behavior, code, scope) gh = GenHTML() gh.run(output_files) if not suppress_output: @@ -242,6 +242,8 @@ def main(): output_files["htm"] = stem + ".htm" if output_files["png"] is not None and output_files["gv"] is None: output_files["gv"] = stem + ".gv" + if output_files["hpo"] is None and ns.probabilistic: + output_files["hpo"] = stem + ".hpo" charm_flag = True print_code: Optional[str] = None @@ -260,7 +262,7 @@ def main(): code, scope = handle_hny(ns, output_files, parse_code_only, str(filename)) if charm_flag: handle_hvm(ns, output_files, parse_code_only, code, scope) - handle_hco(ns, output_files) + handle_hco(ns, output_files, code, scope) else: print("Skipping Phases 2-5...") legacy_harmony.dumpCode(print_code, code, scope) diff --git a/harmony_model_checker/parser/HarmonyLexer.py b/harmony_model_checker/parser/HarmonyLexer.py index 3fb668d9..9859c4a3 100644 --- a/harmony_model_checker/parser/HarmonyLexer.py +++ b/harmony_model_checker/parser/HarmonyLexer.py @@ -65,10 +65,10 @@ def serializedATN(): buf.write("X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3[\3[\3") buf.write("[\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3]\3^\3^\3_\3_\3_\3") buf.write("_\3_\3_\3`\3`\3`\3`\3a\3a\3a\3a\3a\3a\3a\3b\3b\3b\3b\3") - buf.write("b\3b\3c\3c\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3f\3f\3g\3") - buf.write("g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h\3h\3h\3h\3h\3i\3i\3i\3") - buf.write("i\3i\3i\3i\3i\3i\5i\u02f1\ni\3j\3j\3j\3j\3j\3j\3j\3j\3") - buf.write("k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3l\6l\u0309\nl\r") + buf.write("b\3b\3c\3c\3d\3d\3d\3d\3d\3d\3e\3e\3e\3e\3e\3f\3f\3f\3") + buf.write("f\3f\3f\3f\3f\3f\3f\3f\3f\3f\3g\3g\3h\3h\3h\3h\3h\3i\3") + buf.write("i\3i\3i\3i\3i\3i\3i\3i\3i\3i\3j\3j\3j\3j\3j\3j\3j\3j\3") + buf.write("j\5j\u02fe\nj\3k\3k\3k\3k\3k\3k\3k\3k\3l\6l\u0309\nl\r") buf.write("l\16l\u030a\3l\3l\3l\5l\u0310\nl\3m\3m\7m\u0314\nm\fm") buf.write("\16m\u0317\13m\3n\3n\3n\5n\u031c\nn\3o\3o\3o\3o\6o\u0322") buf.write("\no\ro\16o\u0323\3p\3p\3q\3q\3q\3r\3r\3r\3s\3s\3s\3t\3") @@ -153,9 +153,9 @@ def serializedATN(): buf.write("\3\2\2\2\u00bb\u02af\3\2\2\2\u00bd\u02b1\3\2\2\2\u00bf") buf.write("\u02b7\3\2\2\2\u00c1\u02bb\3\2\2\2\u00c3\u02c2\3\2\2\2") buf.write("\u00c5\u02c8\3\2\2\2\u00c7\u02ca\3\2\2\2\u00c9\u02d0\3") - buf.write("\2\2\2\u00cb\u02d5\3\2\2\2\u00cd\u02d7\3\2\2\2\u00cf\u02dc") - buf.write("\3\2\2\2\u00d1\u02f0\3\2\2\2\u00d3\u02f2\3\2\2\2\u00d5") - buf.write("\u02fa\3\2\2\2\u00d7\u030f\3\2\2\2\u00d9\u0311\3\2\2\2") + buf.write("\2\2\2\u00cb\u02d5\3\2\2\2\u00cd\u02e2\3\2\2\2\u00cf\u02e4") + buf.write("\3\2\2\2\u00d1\u02e9\3\2\2\2\u00d3\u02fd\3\2\2\2\u00d5") + buf.write("\u02ff\3\2\2\2\u00d7\u030f\3\2\2\2\u00d9\u0311\3\2\2\2") buf.write("\u00db\u0318\3\2\2\2\u00dd\u031d\3\2\2\2\u00df\u0325\3") buf.write("\2\2\2\u00e1\u0327\3\2\2\2\u00e3\u032a\3\2\2\2\u00e5\u032d") buf.write("\3\2\2\2\u00e7\u0330\3\2\2\2\u00e9\u0333\3\2\2\2\u00eb") @@ -326,27 +326,27 @@ def serializedATN(): buf.write("\2\2\u02cd\u02ce\3\2\2\2\u02ce\u02cf\bd\4\2\u02cf\u00c8") buf.write("\3\2\2\2\u02d0\u02d1\7k\2\2\u02d1\u02d2\7p\2\2\u02d2\u02d3") buf.write("\3\2\2\2\u02d3\u02d4\be\5\2\u02d4\u00ca\3\2\2\2\u02d5") - buf.write("\u02d6\7<\2\2\u02d6\u00cc\3\2\2\2\u02d7\u02d8\7P\2\2\u02d8") - buf.write("\u02d9\7q\2\2\u02d9\u02da\7p\2\2\u02da\u02db\7g\2\2\u02db") - buf.write("\u00ce\3\2\2\2\u02dc\u02dd\7c\2\2\u02dd\u02de\7v\2\2\u02de") - buf.write("\u02df\7q\2\2\u02df\u02e0\7o\2\2\u02e0\u02e1\7k\2\2\u02e1") - buf.write("\u02e2\7e\2\2\u02e2\u02e3\7c\2\2\u02e3\u02e4\7n\2\2\u02e4") - buf.write("\u02e5\7n\2\2\u02e5\u02e6\7{\2\2\u02e6\u00d0\3\2\2\2\u02e7") - buf.write("\u02e8\7H\2\2\u02e8\u02e9\7c\2\2\u02e9\u02ea\7n\2\2\u02ea") - buf.write("\u02eb\7u\2\2\u02eb\u02f1\7g\2\2\u02ec\u02ed\7V\2\2\u02ed") - buf.write("\u02ee\7t\2\2\u02ee\u02ef\7w\2\2\u02ef\u02f1\7g\2\2\u02f0") - buf.write("\u02e7\3\2\2\2\u02f0\u02ec\3\2\2\2\u02f1\u00d2\3\2\2\2") - buf.write("\u02f2\u02f3\7g\2\2\u02f3\u02f4\7v\2\2\u02f4\u02f5\7g") - buf.write("\2\2\u02f5\u02f6\7t\2\2\u02f6\u02f7\7p\2\2\u02f7\u02f8") - buf.write("\7c\2\2\u02f8\u02f9\7n\2\2\u02f9\u00d4\3\2\2\2\u02fa\u02fb") - buf.write("\7j\2\2\u02fb\u02fc\7{\2\2\u02fc\u02fd\7r\2\2\u02fd\u02fe") - buf.write("\7g\2\2\u02fe\u02ff\7t\2\2\u02ff\u0300\7a\2\2\u0300\u0301") - buf.write("\7c\2\2\u0301\u0302\7u\2\2\u0302\u0303\7u\2\2\u0303\u0304") - buf.write("\7g\2\2\u0304\u0305\7t\2\2\u0305\u0306\7v\2\2\u0306\u00d6") - buf.write("\3\2\2\2\u0307\u0309\t\3\2\2\u0308\u0307\3\2\2\2\u0309") - buf.write("\u030a\3\2\2\2\u030a\u0308\3\2\2\2\u030a\u030b\3\2\2\2") - buf.write("\u030b\u0310\3\2\2\2\u030c\u030d\7k\2\2\u030d\u030e\7") - buf.write("p\2\2\u030e\u0310\7h\2\2\u030f\u0308\3\2\2\2\u030f\u030c") + buf.write("\u02d6\7j\2\2\u02d6\u02d7\7{\2\2\u02d7\u02d8\7r\2\2\u02d8") + buf.write("\u02d9\7g\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7a\2\2\u02db") + buf.write("\u02dc\7c\2\2\u02dc\u02dd\7u\2\2\u02dd\u02de\7u\2\2\u02de") + buf.write("\u02df\7g\2\2\u02df\u02e0\7t\2\2\u02e0\u02e1\7v\2\2\u02e1") + buf.write("\u00cc\3\2\2\2\u02e2\u02e3\7<\2\2\u02e3\u00ce\3\2\2\2") + buf.write("\u02e4\u02e5\7P\2\2\u02e5\u02e6\7q\2\2\u02e6\u02e7\7p") + buf.write("\2\2\u02e7\u02e8\7g\2\2\u02e8\u00d0\3\2\2\2\u02e9\u02ea") + buf.write("\7c\2\2\u02ea\u02eb\7v\2\2\u02eb\u02ec\7q\2\2\u02ec\u02ed") + buf.write("\7o\2\2\u02ed\u02ee\7k\2\2\u02ee\u02ef\7e\2\2\u02ef\u02f0") + buf.write("\7c\2\2\u02f0\u02f1\7n\2\2\u02f1\u02f2\7n\2\2\u02f2\u02f3") + buf.write("\7{\2\2\u02f3\u00d2\3\2\2\2\u02f4\u02f5\7H\2\2\u02f5\u02f6") + buf.write("\7c\2\2\u02f6\u02f7\7n\2\2\u02f7\u02f8\7u\2\2\u02f8\u02fe") + buf.write("\7g\2\2\u02f9\u02fa\7V\2\2\u02fa\u02fb\7t\2\2\u02fb\u02fc") + buf.write("\7w\2\2\u02fc\u02fe\7g\2\2\u02fd\u02f4\3\2\2\2\u02fd\u02f9") + buf.write("\3\2\2\2\u02fe\u00d4\3\2\2\2\u02ff\u0300\7g\2\2\u0300") + buf.write("\u0301\7v\2\2\u0301\u0302\7g\2\2\u0302\u0303\7t\2\2\u0303") + buf.write("\u0304\7p\2\2\u0304\u0305\7c\2\2\u0305\u0306\7n\2\2\u0306") + buf.write("\u00d6\3\2\2\2\u0307\u0309\t\3\2\2\u0308\u0307\3\2\2\2") + buf.write("\u0309\u030a\3\2\2\2\u030a\u0308\3\2\2\2\u030a\u030b\3") + buf.write("\2\2\2\u030b\u0310\3\2\2\2\u030c\u030d\7k\2\2\u030d\u030e") + buf.write("\7p\2\2\u030e\u0310\7h\2\2\u030f\u0308\3\2\2\2\u030f\u030c") buf.write("\3\2\2\2\u0310\u00d8\3\2\2\2\u0311\u0315\t\4\2\2\u0312") buf.write("\u0314\t\5\2\2\u0313\u0312\3\2\2\2\u0314\u0317\3\2\2\2") buf.write("\u0315\u0313\3\2\2\2\u0315\u0316\3\2\2\2\u0316\u00da\3") @@ -392,7 +392,7 @@ def serializedATN(): buf.write("\u0376\u037a\13\2\2\2\u0377\u0378\7^\2\2\u0378\u037a\5") buf.write("o8\2\u0379\u0375\3\2\2\2\u0379\u0377\3\2\2\2\u037a\u00fa") buf.write("\3\2\2\2\36\2\u01d2\u01d8\u01de\u01e1\u01e8\u01ed\u01f2") - buf.write("\u01fa\u0203\u0206\u02f0\u030a\u030f\u0315\u031b\u0323") + buf.write("\u01fa\u0203\u0206\u02fd\u030a\u030f\u0315\u031b\u0323") buf.write("\u033d\u0342\u0344\u034b\u034d\u0351\u035a\u0367\u036d") buf.write("\u0371\u0379\f\38\2\b\2\2\3d\3\3e\4\3q\5\3r\6\3s\7\3t") buf.write("\b\3u\t\3v\n") @@ -504,12 +504,12 @@ class HarmonyLexer(Lexer): EQ = 97 FOR = 98 IN = 99 - COLON = 100 - NONE = 101 - ATOMICALLY = 102 - BOOL = 103 - ETERNAL = 104 - HYPER = 105 + HYPER = 100 + COLON = 101 + NONE = 102 + ATOMICALLY = 103 + BOOL = 104 + ETERNAL = 105 INT = 106 NAME = 107 ATOM = 108 @@ -542,9 +542,8 @@ class HarmonyLexer(Lexer): "'var'", "'trap'", "'pass'", "'del'", "'spawn'", "'invariant'", "'go'", "'sequential'", "'when'", "'let'", "'if'", "'elif'", "'else'", "'@'", "'while'", "'def'", "'exists'", "'where'", - "'='", "'for'", "'in'", "':'", "'None'", "'atomically'", "'eternal'", - "'hyper_assert'", "'['", "']'", "'{'", "'}'", "'('", "')'", - "';'" ] + "'='", "'for'", "'in'", "'hyper_assert'", "':'", "'None'", "'atomically'", + "'eternal'", "'['", "']'", "'{'", "'}'", "'('", "')'", "';'" ] symbolicNames = [ "", "NL", "WS", "COMMENT_START", "OPEN_MULTI_COMMENT", "CLOSE_MULTI_COMMENT", @@ -553,8 +552,8 @@ class HarmonyLexer(Lexer): "NOT", "COMMA", "CONST", "AWAIT", "ASSERT", "VAR", "TRAP", "PASS", "DEL", "SPAWN", "INVARIANT", "GO", "SEQUENTIAL", "WHEN", "LET", "IF", "ELIF", "ELSE", "AT", "WHILE", "DEF", "EXISTS", "WHERE", - "EQ", "FOR", "IN", "COLON", "NONE", "ATOMICALLY", "BOOL", "ETERNAL", - "HYPER", "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", + "EQ", "FOR", "IN", "HYPER", "COLON", "NONE", "ATOMICALLY", "BOOL", + "ETERNAL", "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", "CLOSE_PAREN", "SEMI_COLON", "STRING" ] @@ -574,8 +573,8 @@ class HarmonyLexer(Lexer): "ASSERT", "VAR", "TRAP", "PASS", "DEL", "SPAWN", "INVARIANT", "GO", "SEQUENTIAL", "WHEN", "LET", "IF", "ELIF", "ELSE", "AT", "WHILE", "DEF", "EXISTS", "WHERE", "EQ", "FOR", - "IN", "COLON", "NONE", "ATOMICALLY", "BOOL", "ETERNAL", - "HYPER", "INT", "NAME", "ATOM", "HEX_INTEGER", "HEX_DIGIT", + "IN", "HYPER", "COLON", "NONE", "ATOMICALLY", "BOOL", + "ETERNAL", "INT", "NAME", "ATOM", "HEX_INTEGER", "HEX_DIGIT", "OPEN_BRACK", "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", "CLOSE_PAREN", "SEMI_COLON", "STRING", "SHORT_STRING", "LONG_STRING", "LONG_STRING_ITEM", "LONG_STRING_CHAR", diff --git a/harmony_model_checker/parser/HarmonyParser.py b/harmony_model_checker/parser/HarmonyParser.py index 8504f3ca..bb7eb38a 100644 --- a/harmony_model_checker/parser/HarmonyParser.py +++ b/harmony_model_checker/parser/HarmonyParser.py @@ -12,7 +12,7 @@ def serializedATN(): with StringIO() as buf: buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3y") - buf.write("\u0245\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") + buf.write("\u0244\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31") @@ -55,19 +55,19 @@ def serializedATN(): buf.write("\n*\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3-\3-\3-\3-\3-\3.\3") buf.write(".\3.\3.\3.\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\7\60\u01d7") buf.write("\n\60\f\60\16\60\u01da\13\60\3\60\5\60\u01dd\n\60\3\61") - buf.write("\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\63\6\63") - buf.write("\u01ea\n\63\r\63\16\63\u01eb\3\64\3\64\5\64\u01f0\n\64") - buf.write("\3\65\3\65\3\65\3\65\5\65\u01f6\n\65\3\65\3\65\3\65\5") - buf.write("\65\u01fb\n\65\3\66\5\66\u01fe\n\66\3\66\3\66\3\66\3\66") - buf.write("\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66") - buf.write("\5\66\u020f\n\66\3\67\5\67\u0212\n\67\3\67\3\67\3\67\3") - buf.write("\67\3\67\3\67\5\67\u021a\n\67\38\38\58\u021e\n8\38\38") - buf.write("\38\58\u0223\n8\39\39\69\u0227\n9\r9\169\u0228\3:\5:\u022c") - buf.write("\n:\3:\5:\u022f\n:\3:\7:\u0232\n:\f:\16:\u0235\13:\3:") - buf.write("\3:\3:\3:\3:\5:\u023c\n:\3:\3:\5:\u0240\n:\3:\5:\u0243") + buf.write("\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\63\6\63\u01e9") + buf.write("\n\63\r\63\16\63\u01ea\3\64\3\64\5\64\u01ef\n\64\3\65") + buf.write("\3\65\3\65\3\65\5\65\u01f5\n\65\3\65\3\65\3\65\5\65\u01fa") + buf.write("\n\65\3\66\5\66\u01fd\n\66\3\66\3\66\3\66\3\66\3\66\3") + buf.write("\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\3\66\5\66") + buf.write("\u020e\n\66\3\67\5\67\u0211\n\67\3\67\3\67\3\67\3\67\3") + buf.write("\67\3\67\5\67\u0219\n\67\38\38\58\u021d\n8\38\38\38\5") + buf.write("8\u0222\n8\39\39\69\u0226\n9\r9\169\u0227\3:\5:\u022b") + buf.write("\n:\3:\5:\u022e\n:\3:\7:\u0231\n:\f:\16:\u0234\13:\3:") + buf.write("\3:\3:\3:\3:\5:\u023b\n:\3:\3:\5:\u023f\n:\3:\5:\u0242") buf.write("\n:\3:\2\3&;\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"") buf.write("$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnpr\2\6") - buf.write("\4\2\3\21??\3\2\22\27\5\2\t\t\30(LL\3\2*8\2\u026c\2w\3") + buf.write("\4\2\3\21??\3\2\22\27\5\2\t\t\30(LL\3\2*8\2\u026b\2w\3") buf.write("\2\2\2\4~\3\2\2\2\6\u0085\3\2\2\2\b\u0088\3\2\2\2\n\u008f") buf.write("\3\2\2\2\f\u00a4\3\2\2\2\16\u00ab\3\2\2\2\20\u00b0\3\2") buf.write("\2\2\22\u00b2\3\2\2\2\24\u00b4\3\2\2\2\26\u00d0\3\2\2") @@ -81,9 +81,9 @@ def serializedATN(): buf.write("H\u018e\3\2\2\2J\u0197\3\2\2\2L\u019b\3\2\2\2N\u019f\3") buf.write("\2\2\2P\u01a6\3\2\2\2R\u01b4\3\2\2\2T\u01b9\3\2\2\2V\u01bd") buf.write("\3\2\2\2X\u01c3\3\2\2\2Z\u01c8\3\2\2\2\\\u01cd\3\2\2\2") - buf.write("^\u01d1\3\2\2\2`\u01de\3\2\2\2b\u01e1\3\2\2\2d\u01e9\3") - buf.write("\2\2\2f\u01ef\3\2\2\2h\u01f1\3\2\2\2j\u01fd\3\2\2\2l\u0211") - buf.write("\3\2\2\2n\u021b\3\2\2\2p\u0226\3\2\2\2r\u0242\3\2\2\2") + buf.write("^\u01d1\3\2\2\2`\u01de\3\2\2\2b\u01e0\3\2\2\2d\u01e8\3") + buf.write("\2\2\2f\u01ee\3\2\2\2h\u01f0\3\2\2\2j\u01fc\3\2\2\2l\u0210") + buf.write("\3\2\2\2n\u021a\3\2\2\2p\u0225\3\2\2\2r\u0241\3\2\2\2") buf.write("tv\5r:\2ut\3\2\2\2vy\3\2\2\2wu\3\2\2\2wx\3\2\2\2xz\3\2") buf.write("\2\2yw\3\2\2\2z{\7\2\2\3{\3\3\2\2\2|\177\5\6\4\2}\177") buf.write("\5\b\5\2~|\3\2\2\2~}\3\2\2\2\177\u0081\3\2\2\2\u0080\u0082") @@ -109,11 +109,11 @@ def serializedATN(): buf.write("\5\f\7\2\u00af\17\3\2\2\2\u00b0\u00b1\t\2\2\2\u00b1\21") buf.write("\3\2\2\2\u00b2\u00b3\t\3\2\2\u00b3\23\3\2\2\2\u00b4\u00b5") buf.write("\t\4\2\2\u00b5\25\3\2\2\2\u00b6\u00d1\7l\2\2\u00b7\u00d1") - buf.write("\7i\2\2\u00b8\u00d1\7n\2\2\u00b9\u00d1\7m\2\2\u00ba\u00d1") - buf.write("\7w\2\2\u00bb\u00d1\7g\2\2\u00bc\u00be\7r\2\2\u00bd\u00bf") + buf.write("\7j\2\2\u00b8\u00d1\7n\2\2\u00b9\u00d1\7m\2\2\u00ba\u00d1") + buf.write("\7w\2\2\u00bb\u00d1\7h\2\2\u00bc\u00be\7r\2\2\u00bd\u00bf") buf.write("\5\30\r\2\u00be\u00bd\3\2\2\2\u00be\u00bf\3\2\2\2\u00bf") buf.write("\u00c0\3\2\2\2\u00c0\u00d1\7s\2\2\u00c1\u00c2\7r\2\2\u00c2") - buf.write("\u00c3\7f\2\2\u00c3\u00d1\7s\2\2\u00c4\u00c6\7t\2\2\u00c5") + buf.write("\u00c3\7g\2\2\u00c3\u00d1\7s\2\2\u00c4\u00c6\7t\2\2\u00c5") buf.write("\u00c7\5 \21\2\u00c6\u00c5\3\2\2\2\u00c6\u00c7\3\2\2\2") buf.write("\u00c7\u00c8\3\2\2\2\u00c8\u00d1\7u\2\2\u00c9\u00cb\7") buf.write("p\2\2\u00ca\u00cc\5 \21\2\u00cb\u00ca\3\2\2\2\u00cb\u00cc") @@ -123,9 +123,9 @@ def serializedATN(): buf.write("\2\2\2\u00d0\u00ba\3\2\2\2\u00d0\u00bb\3\2\2\2\u00d0\u00bc") buf.write("\3\2\2\2\u00d0\u00c1\3\2\2\2\u00d0\u00c4\3\2\2\2\u00d0") buf.write("\u00c9\3\2\2\2\u00d0\u00ce\3\2\2\2\u00d1\27\3\2\2\2\u00d2") - buf.write("\u00ec\5\"\22\2\u00d3\u00d4\7f\2\2\u00d4\u00e0\5\"\22") + buf.write("\u00ec\5\"\22\2\u00d3\u00d4\7g\2\2\u00d4\u00e0\5\"\22") buf.write("\2\u00d5\u00e1\5\32\16\2\u00d6\u00d7\7M\2\2\u00d7\u00d8") - buf.write("\5\"\22\2\u00d8\u00d9\7f\2\2\u00d9\u00da\5\"\22\2\u00da") + buf.write("\5\"\22\2\u00d8\u00d9\7g\2\2\u00d9\u00da\5\"\22\2\u00da") buf.write("\u00dc\3\2\2\2\u00db\u00d6\3\2\2\2\u00dc\u00df\3\2\2\2") buf.write("\u00dd\u00db\3\2\2\2\u00dd\u00de\3\2\2\2\u00de\u00e1\3") buf.write("\2\2\2\u00df\u00dd\3\2\2\2\u00e0\u00d5\3\2\2\2\u00e0\u00dd") @@ -140,7 +140,7 @@ def serializedATN(): buf.write("\u00f0\3\2\2\2\u00f2\u00f5\3\2\2\2\u00f3\u00f1\3\2\2\2") buf.write("\u00f3\u00f4\3\2\2\2\u00f4\33\3\2\2\2\u00f5\u00f3\3\2") buf.write("\2\2\u00f6\u00fc\7d\2\2\u00f7\u00fd\5\16\b\2\u00f8\u00f9") - buf.write("\5\16\b\2\u00f9\u00fa\7f\2\2\u00fa\u00fb\5\16\b\2\u00fb") + buf.write("\5\16\b\2\u00f9\u00fa\7g\2\2\u00fa\u00fb\5\16\b\2\u00fb") buf.write("\u00fd\3\2\2\2\u00fc\u00f7\3\2\2\2\u00fc\u00f8\3\2\2\2") buf.write("\u00fd\u00fe\3\2\2\2\u00fe\u00ff\7e\2\2\u00ff\u0100\5") buf.write("\"\22\2\u0100\35\3\2\2\2\u0101\u0102\7b\2\2\u0102\u0103") @@ -164,7 +164,7 @@ def serializedATN(): buf.write("\2\2\2\u012b\u012e\3\2\2\2\u012c\u012a\3\2\2\2\u012d\u0114") buf.write("\3\2\2\2\u012d\u011d\3\2\2\2\u012d\u0120\3\2\2\2\u012d") buf.write("\u012a\3\2\2\2\u012e#\3\2\2\2\u012f\u0130\7J\2\2\u0130") - buf.write("\u0131\5\16\b\2\u0131\u0132\7f\2\2\u0132\u0133\5\"\22") + buf.write("\u0131\5\16\b\2\u0131\u0132\7g\2\2\u0132\u0133\5\"\22") buf.write("\2\u0133\u0134\7)\2\2\u0134\u0142\3\2\2\2\u0135\u0136") buf.write("\7F\2\2\u0136\u0142\5$\23\2\u0137\u0138\7H\2\2\u0138\u0142") buf.write("\5$\23\2\u0139\u013a\7I\2\2\u013a\u0142\5$\23\2\u013b") @@ -196,7 +196,7 @@ def serializedATN(): buf.write("\5(\25\2\u0178;\3\2\2\2\u0179\u017a\7S\2\2\u017a=\3\2") buf.write("\2\2\u017b\u017c\7V\2\2\u017c\u017d\5(\25\2\u017d?\3\2") buf.write("\2\2\u017e\u017f\7T\2\2\u017f\u0180\5(\25\2\u0180A\3\2") - buf.write("\2\2\u0181\u0183\7U\2\2\u0182\u0184\7j\2\2\u0183\u0182") + buf.write("\2\2\u0181\u0183\7U\2\2\u0182\u0184\7k\2\2\u0183\u0182") buf.write("\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u0185\3\2\2\2\u0185") buf.write("\u0186\5(\25\2\u0186C\3\2\2\2\u0187\u0188\7W\2\2\u0188") buf.write("\u0189\5(\25\2\u0189\u018a\5(\25\2\u018aE\3\2\2\2\u018b") @@ -204,9 +204,9 @@ def serializedATN(): buf.write("\u018f\7X\2\2\u018f\u0194\5(\25\2\u0190\u0191\7M\2\2\u0191") buf.write("\u0193\5(\25\2\u0192\u0190\3\2\2\2\u0193\u0196\3\2\2\2") buf.write("\u0194\u0192\3\2\2\2\u0194\u0195\3\2\2\2\u0195I\3\2\2") - buf.write("\2\u0196\u0194\3\2\2\2\u0197\u0198\7h\2\2\u0198\u0199") - buf.write("\7f\2\2\u0199\u019a\5f\64\2\u019aK\3\2\2\2\u019b\u019c") - buf.write("\5\32\16\2\u019c\u019d\7f\2\2\u019d\u019e\5f\64\2\u019e") + buf.write("\2\u0196\u0194\3\2\2\2\u0197\u0198\7i\2\2\u0198\u0199") + buf.write("\7g\2\2\u0199\u019a\5f\64\2\u019aK\3\2\2\2\u019b\u019c") + buf.write("\5\32\16\2\u019c\u019d\7g\2\2\u019d\u019e\5f\64\2\u019e") buf.write("M\3\2\2\2\u019f\u01a0\7Z\2\2\u01a0\u01a1\5\16\b\2\u01a1") buf.write("\u01a2\7c\2\2\u01a2\u01a4\5 \21\2\u01a3\u01a5\79\2\2\u01a4") buf.write("\u01a3\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5O\3\2\2\2\u01a6") @@ -218,75 +218,75 @@ def serializedATN(): buf.write("\u01b5\5N(\2\u01b3\u01b5\5P)\2\u01b4\u01b2\3\2\2\2\u01b4") buf.write("\u01b3\3\2\2\2\u01b5\u01b7\3\2\2\2\u01b6\u01b8\5R*\2\u01b7") buf.write("\u01b6\3\2\2\2\u01b7\u01b8\3\2\2\2\u01b8S\3\2\2\2\u01b9") - buf.write("\u01ba\5R*\2\u01ba\u01bb\7f\2\2\u01bb\u01bc\5f\64\2\u01bc") + buf.write("\u01ba\5R*\2\u01ba\u01bb\7g\2\2\u01bb\u01bc\5f\64\2\u01bc") buf.write("U\3\2\2\2\u01bd\u01be\7`\2\2\u01be\u01bf\7m\2\2\u01bf") - buf.write("\u01c0\5\16\b\2\u01c0\u01c1\7f\2\2\u01c1\u01c2\5f\64\2") + buf.write("\u01c0\5\16\b\2\u01c0\u01c1\7g\2\2\u01c1\u01c2\5f\64\2") buf.write("\u01c2W\3\2\2\2\u01c3\u01c4\7_\2\2\u01c4\u01c5\5(\25\2") - buf.write("\u01c5\u01c6\7f\2\2\u01c6\u01c7\5f\64\2\u01c7Y\3\2\2\2") + buf.write("\u01c5\u01c6\7g\2\2\u01c6\u01c7\5f\64\2\u01c7Y\3\2\2\2") buf.write("\u01c8\u01c9\7\\\2\2\u01c9\u01ca\5(\25\2\u01ca\u01cb\7") - buf.write("f\2\2\u01cb\u01cc\5f\64\2\u01cc[\3\2\2\2\u01cd\u01ce\7") - buf.write("]\2\2\u01ce\u01cf\7f\2\2\u01cf\u01d0\5f\64\2\u01d0]\3") + buf.write("g\2\2\u01cb\u01cc\5f\64\2\u01cc[\3\2\2\2\u01cd\u01ce\7") + buf.write("]\2\2\u01ce\u01cf\7g\2\2\u01cf\u01d0\5f\64\2\u01d0]\3") buf.write("\2\2\2\u01d1\u01d2\7[\2\2\u01d2\u01d3\5(\25\2\u01d3\u01d4") - buf.write("\7f\2\2\u01d4\u01d8\5f\64\2\u01d5\u01d7\5Z.\2\u01d6\u01d5") + buf.write("\7g\2\2\u01d4\u01d8\5f\64\2\u01d5\u01d7\5Z.\2\u01d6\u01d5") buf.write("\3\2\2\2\u01d7\u01da\3\2\2\2\u01d8\u01d6\3\2\2\2\u01d8") buf.write("\u01d9\3\2\2\2\u01d9\u01dc\3\2\2\2\u01da\u01d8\3\2\2\2") buf.write("\u01db\u01dd\5\\/\2\u01dc\u01db\3\2\2\2\u01dc\u01dd\3") - buf.write("\2\2\2\u01dd_\3\2\2\2\u01de\u01df\7\32\2\2\u01df\u01e0") - buf.write("\7m\2\2\u01e0a\3\2\2\2\u01e1\u01e2\7k\2\2\u01e2\u01e3") - buf.write("\7t\2\2\u01e3\u01e4\5`\61\2\u01e4\u01e5\7u\2\2\u01e5\u01e6") - buf.write("\5\22\n\2\u01e6\u01e7\5(\25\2\u01e7c\3\2\2\2\u01e8\u01ea") - buf.write("\5r:\2\u01e9\u01e8\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb\u01e9") - buf.write("\3\2\2\2\u01eb\u01ec\3\2\2\2\u01ece\3\2\2\2\u01ed\u01f0") - buf.write("\5h\65\2\u01ee\u01f0\5n8\2\u01ef\u01ed\3\2\2\2\u01ef\u01ee") - buf.write("\3\2\2\2\u01f0g\3\2\2\2\u01f1\u01f5\7x\2\2\u01f2\u01f6") - buf.write("\5d\63\2\u01f3\u01f4\7x\2\2\u01f4\u01f6\5f\64\2\u01f5") - buf.write("\u01f2\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01f7\3\2\2\2") - buf.write("\u01f7\u01fa\7y\2\2\u01f8\u01f9\7v\2\2\u01f9\u01fb\79") - buf.write("\2\2\u01fa\u01f8\3\2\2\2\u01fa\u01fb\3\2\2\2\u01fbi\3") - buf.write("\2\2\2\u01fc\u01fe\7h\2\2\u01fd\u01fc\3\2\2\2\u01fd\u01fe") - buf.write("\3\2\2\2\u01fe\u020e\3\2\2\2\u01ff\u020f\5.\30\2\u0200") - buf.write("\u020f\5\62\32\2\u0201\u020f\5\66\34\2\u0202\u020f\58") - buf.write("\35\2\u0203\u020f\5> \2\u0204\u020f\5@!\2\u0205\u020f") - buf.write("\5B\"\2\u0206\u020f\5:\36\2\u0207\u020f\5D#\2\u0208\u020f") - buf.write("\5F$\2\u0209\u020f\5<\37\2\u020a\u020f\5H%\2\u020b\u020f") - buf.write("\5\64\33\2\u020c\u020f\5\60\31\2\u020d\u020f\5,\27\2\u020e") - buf.write("\u01ff\3\2\2\2\u020e\u0200\3\2\2\2\u020e\u0201\3\2\2\2") - buf.write("\u020e\u0202\3\2\2\2\u020e\u0203\3\2\2\2\u020e\u0204\3") - buf.write("\2\2\2\u020e\u0205\3\2\2\2\u020e\u0206\3\2\2\2\u020e\u0207") - buf.write("\3\2\2\2\u020e\u0208\3\2\2\2\u020e\u0209\3\2\2\2\u020e") - buf.write("\u020a\3\2\2\2\u020e\u020b\3\2\2\2\u020e\u020c\3\2\2\2") - buf.write("\u020e\u020d\3\2\2\2\u020fk\3\2\2\2\u0210\u0212\7h\2\2") - buf.write("\u0211\u0210\3\2\2\2\u0211\u0212\3\2\2\2\u0212\u0219\3") - buf.write("\2\2\2\u0213\u021a\5^\60\2\u0214\u021a\5X-\2\u0215\u021a") - buf.write("\5L\'\2\u0216\u021a\5T+\2\u0217\u021a\5J&\2\u0218\u021a") - buf.write("\5V,\2\u0219\u0213\3\2\2\2\u0219\u0214\3\2\2\2\u0219\u0215") - buf.write("\3\2\2\2\u0219\u0216\3\2\2\2\u0219\u0217\3\2\2\2\u0219") - buf.write("\u0218\3\2\2\2\u021am\3\2\2\2\u021b\u0222\5j\66\2\u021c") - buf.write("\u021e\7v\2\2\u021d\u021c\3\2\2\2\u021d\u021e\3\2\2\2") - buf.write("\u021e\u021f\3\2\2\2\u021f\u0223\79\2\2\u0220\u0221\7") - buf.write("v\2\2\u0221\u0223\5n8\2\u0222\u021d\3\2\2\2\u0222\u0220") - buf.write("\3\2\2\2\u0223o\3\2\2\2\u0224\u0225\7m\2\2\u0225\u0227") - buf.write("\7f\2\2\u0226\u0224\3\2\2\2\u0227\u0228\3\2\2\2\u0228") - buf.write("\u0226\3\2\2\2\u0228\u0229\3\2\2\2\u0229q\3\2\2\2\u022a") - buf.write("\u022c\5p9\2\u022b\u022a\3\2\2\2\u022b\u022c\3\2\2\2\u022c") - buf.write("\u022f\3\2\2\2\u022d\u022f\7f\2\2\u022e\u022b\3\2\2\2") - buf.write("\u022e\u022d\3\2\2\2\u022f\u023b\3\2\2\2\u0230\u0232\7") - buf.write("v\2\2\u0231\u0230\3\2\2\2\u0232\u0235\3\2\2\2\u0233\u0231") - buf.write("\3\2\2\2\u0233\u0234\3\2\2\2\u0234\u0236\3\2\2\2\u0235") - buf.write("\u0233\3\2\2\2\u0236\u023c\79\2\2\u0237\u023c\5n8\2\u0238") - buf.write("\u023c\5l\67\2\u0239\u023c\5\4\3\2\u023a\u023c\5b\62\2") - buf.write("\u023b\u0233\3\2\2\2\u023b\u0237\3\2\2\2\u023b\u0238\3") - buf.write("\2\2\2\u023b\u0239\3\2\2\2\u023b\u023a\3\2\2\2\u023c\u0243") - buf.write("\3\2\2\2\u023d\u0240\5p9\2\u023e\u0240\7f\2\2\u023f\u023d") - buf.write("\3\2\2\2\u023f\u023e\3\2\2\2\u0240\u0241\3\2\2\2\u0241") - buf.write("\u0243\5h\65\2\u0242\u022e\3\2\2\2\u0242\u023f\3\2\2\2") - buf.write("\u0243s\3\2\2\2:w~\u0081\u008d\u0094\u00a4\u00ab\u00be") + buf.write("\2\2\2\u01dd_\3\2\2\2\u01de\u01df\7m\2\2\u01dfa\3\2\2") + buf.write("\2\u01e0\u01e1\7f\2\2\u01e1\u01e2\7t\2\2\u01e2\u01e3\5") + buf.write("`\61\2\u01e3\u01e4\7u\2\2\u01e4\u01e5\5\22\n\2\u01e5\u01e6") + buf.write("\5(\25\2\u01e6c\3\2\2\2\u01e7\u01e9\5r:\2\u01e8\u01e7") + buf.write("\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01e8\3\2\2\2\u01ea") + buf.write("\u01eb\3\2\2\2\u01ebe\3\2\2\2\u01ec\u01ef\5h\65\2\u01ed") + buf.write("\u01ef\5n8\2\u01ee\u01ec\3\2\2\2\u01ee\u01ed\3\2\2\2\u01ef") + buf.write("g\3\2\2\2\u01f0\u01f4\7x\2\2\u01f1\u01f5\5d\63\2\u01f2") + buf.write("\u01f3\7x\2\2\u01f3\u01f5\5f\64\2\u01f4\u01f1\3\2\2\2") + buf.write("\u01f4\u01f2\3\2\2\2\u01f5\u01f6\3\2\2\2\u01f6\u01f9\7") + buf.write("y\2\2\u01f7\u01f8\7v\2\2\u01f8\u01fa\79\2\2\u01f9\u01f7") + buf.write("\3\2\2\2\u01f9\u01fa\3\2\2\2\u01fai\3\2\2\2\u01fb\u01fd") + buf.write("\7i\2\2\u01fc\u01fb\3\2\2\2\u01fc\u01fd\3\2\2\2\u01fd") + buf.write("\u020d\3\2\2\2\u01fe\u020e\5.\30\2\u01ff\u020e\5\62\32") + buf.write("\2\u0200\u020e\5\66\34\2\u0201\u020e\58\35\2\u0202\u020e") + buf.write("\5> \2\u0203\u020e\5@!\2\u0204\u020e\5B\"\2\u0205\u020e") + buf.write("\5:\36\2\u0206\u020e\5D#\2\u0207\u020e\5F$\2\u0208\u020e") + buf.write("\5<\37\2\u0209\u020e\5H%\2\u020a\u020e\5\64\33\2\u020b") + buf.write("\u020e\5\60\31\2\u020c\u020e\5,\27\2\u020d\u01fe\3\2\2") + buf.write("\2\u020d\u01ff\3\2\2\2\u020d\u0200\3\2\2\2\u020d\u0201") + buf.write("\3\2\2\2\u020d\u0202\3\2\2\2\u020d\u0203\3\2\2\2\u020d") + buf.write("\u0204\3\2\2\2\u020d\u0205\3\2\2\2\u020d\u0206\3\2\2\2") + buf.write("\u020d\u0207\3\2\2\2\u020d\u0208\3\2\2\2\u020d\u0209\3") + buf.write("\2\2\2\u020d\u020a\3\2\2\2\u020d\u020b\3\2\2\2\u020d\u020c") + buf.write("\3\2\2\2\u020ek\3\2\2\2\u020f\u0211\7i\2\2\u0210\u020f") + buf.write("\3\2\2\2\u0210\u0211\3\2\2\2\u0211\u0218\3\2\2\2\u0212") + buf.write("\u0219\5^\60\2\u0213\u0219\5X-\2\u0214\u0219\5L\'\2\u0215") + buf.write("\u0219\5T+\2\u0216\u0219\5J&\2\u0217\u0219\5V,\2\u0218") + buf.write("\u0212\3\2\2\2\u0218\u0213\3\2\2\2\u0218\u0214\3\2\2\2") + buf.write("\u0218\u0215\3\2\2\2\u0218\u0216\3\2\2\2\u0218\u0217\3") + buf.write("\2\2\2\u0219m\3\2\2\2\u021a\u0221\5j\66\2\u021b\u021d") + buf.write("\7v\2\2\u021c\u021b\3\2\2\2\u021c\u021d\3\2\2\2\u021d") + buf.write("\u021e\3\2\2\2\u021e\u0222\79\2\2\u021f\u0220\7v\2\2\u0220") + buf.write("\u0222\5n8\2\u0221\u021c\3\2\2\2\u0221\u021f\3\2\2\2\u0222") + buf.write("o\3\2\2\2\u0223\u0224\7m\2\2\u0224\u0226\7g\2\2\u0225") + buf.write("\u0223\3\2\2\2\u0226\u0227\3\2\2\2\u0227\u0225\3\2\2\2") + buf.write("\u0227\u0228\3\2\2\2\u0228q\3\2\2\2\u0229\u022b\5p9\2") + buf.write("\u022a\u0229\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u022e\3") + buf.write("\2\2\2\u022c\u022e\7g\2\2\u022d\u022a\3\2\2\2\u022d\u022c") + buf.write("\3\2\2\2\u022e\u023a\3\2\2\2\u022f\u0231\7v\2\2\u0230") + buf.write("\u022f\3\2\2\2\u0231\u0234\3\2\2\2\u0232\u0230\3\2\2\2") + buf.write("\u0232\u0233\3\2\2\2\u0233\u0235\3\2\2\2\u0234\u0232\3") + buf.write("\2\2\2\u0235\u023b\79\2\2\u0236\u023b\5n8\2\u0237\u023b") + buf.write("\5l\67\2\u0238\u023b\5\4\3\2\u0239\u023b\5b\62\2\u023a") + buf.write("\u0232\3\2\2\2\u023a\u0236\3\2\2\2\u023a\u0237\3\2\2\2") + buf.write("\u023a\u0238\3\2\2\2\u023a\u0239\3\2\2\2\u023b\u0242\3") + buf.write("\2\2\2\u023c\u023f\5p9\2\u023d\u023f\7g\2\2\u023e\u023c") + buf.write("\3\2\2\2\u023e\u023d\3\2\2\2\u023f\u0240\3\2\2\2\u0240") + buf.write("\u0242\5h\65\2\u0241\u022d\3\2\2\2\u0241\u023e\3\2\2\2") + buf.write("\u0242s\3\2\2\2:w~\u0081\u008d\u0094\u00a4\u00ab\u00be") buf.write("\u00c6\u00cb\u00d0\u00dd\u00e0\u00e9\u00ec\u00f1\u00f3") buf.write("\u00fc\u010a\u010e\u0110\u0114\u011d\u012a\u012d\u0141") buf.write("\u014b\u014d\u015b\u016c\u0183\u0194\u01a4\u01ad\u01b0") - buf.write("\u01b4\u01b7\u01d8\u01dc\u01eb\u01ef\u01f5\u01fa\u01fd") - buf.write("\u020e\u0211\u0219\u021d\u0222\u0228\u022b\u022e\u0233") - buf.write("\u023b\u023f\u0242") + buf.write("\u01b4\u01b7\u01d8\u01dc\u01ea\u01ee\u01f4\u01f9\u01fc") + buf.write("\u020d\u0210\u0218\u021c\u0221\u0227\u022a\u022d\u0232") + buf.write("\u023a\u023e\u0241") return buf.getvalue() @@ -317,8 +317,8 @@ class HarmonyParser ( Parser ): "'del'", "'spawn'", "'invariant'", "'go'", "'sequential'", "'when'", "'let'", "'if'", "'elif'", "'else'", "'@'", "'while'", "'def'", "'exists'", "'where'", "'='", "'for'", - "'in'", "':'", "'None'", "'atomically'", "", - "'eternal'", "'hyper_assert'", "", "", + "'in'", "'hyper_assert'", "':'", "'None'", "'atomically'", + "", "'eternal'", "", "", "", "", "'['", "']'", "'{'", "'}'", "'('", "')'", "';'" ] @@ -343,8 +343,8 @@ class HarmonyParser ( Parser ): "ASSERT", "VAR", "TRAP", "PASS", "DEL", "SPAWN", "INVARIANT", "GO", "SEQUENTIAL", "WHEN", "LET", "IF", "ELIF", "ELSE", "AT", "WHILE", "DEF", "EXISTS", "WHERE", "EQ", "FOR", - "IN", "COLON", "NONE", "ATOMICALLY", "BOOL", "ETERNAL", - "HYPER", "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", + "IN", "HYPER", "COLON", "NONE", "ATOMICALLY", "BOOL", + "ETERNAL", "INT", "NAME", "ATOM", "HEX_INTEGER", "OPEN_BRACK", "CLOSE_BRACK", "OPEN_BRACES", "CLOSE_BRACES", "OPEN_PAREN", "CLOSE_PAREN", "SEMI_COLON", "STRING", "INDENT", "DEDENT" ] @@ -521,12 +521,12 @@ class HarmonyParser ( Parser ): EQ=97 FOR=98 IN=99 - COLON=100 - NONE=101 - ATOMICALLY=102 - BOOL=103 - ETERNAL=104 - HYPER=105 + HYPER=100 + COLON=101 + NONE=102 + ATOMICALLY=103 + BOOL=104 + ETERNAL=105 INT=106 NAME=107 ATOM=108 @@ -590,7 +590,7 @@ def program(self): self.state = 117 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.HYPER - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.HYPER - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0): self.state = 114 self.stmt() self.state = 119 @@ -3829,8 +3829,6 @@ def hyper_condition(self): try: self.enterOuterAlt(localctx, 1) self.state = 476 - self.match(HarmonyParser.T__23) - self.state = 477 self.match(HarmonyParser.NAME) except RecognitionException as re: localctx.exception = re @@ -3887,17 +3885,17 @@ def hyperassert_stmt(self): self.enterRule(localctx, 96, self.RULE_hyperassert_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 479 + self.state = 478 self.match(HarmonyParser.HYPER) - self.state = 480 + self.state = 479 self.match(HarmonyParser.OPEN_PAREN) - self.state = 481 + self.state = 480 self.hyper_condition() - self.state = 482 + self.state = 481 self.match(HarmonyParser.CLOSE_PAREN) - self.state = 483 + self.state = 482 self.comp_op() - self.state = 484 + self.state = 483 self.expr() except RecognitionException as re: localctx.exception = re @@ -3941,16 +3939,16 @@ def block_stmts(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 487 + self.state = 486 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 486 + self.state = 485 self.stmt() - self.state = 489 + self.state = 488 self._errHandler.sync(self) _la = self._input.LA(1) - if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.HYPER - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0)): + if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << HarmonyParser.T__6) | (1 << HarmonyParser.T__21) | (1 << HarmonyParser.T__22) | (1 << HarmonyParser.T__23) | (1 << HarmonyParser.T__24) | (1 << HarmonyParser.T__25) | (1 << HarmonyParser.T__26) | (1 << HarmonyParser.T__27) | (1 << HarmonyParser.T__28) | (1 << HarmonyParser.T__29) | (1 << HarmonyParser.T__30) | (1 << HarmonyParser.T__31) | (1 << HarmonyParser.T__32) | (1 << HarmonyParser.T__33) | (1 << HarmonyParser.T__34) | (1 << HarmonyParser.T__35) | (1 << HarmonyParser.T__36) | (1 << HarmonyParser.T__37) | (1 << HarmonyParser.NL) | (1 << HarmonyParser.POINTER_OF))) != 0) or ((((_la - 64)) & ~0x3f) == 0 and ((1 << (_la - 64)) & ((1 << (HarmonyParser.IMPORT - 64)) | (1 << (HarmonyParser.PRINT - 64)) | (1 << (HarmonyParser.FROM - 64)) | (1 << (HarmonyParser.SETINTLEVEL - 64)) | (1 << (HarmonyParser.SAVE - 64)) | (1 << (HarmonyParser.STOP - 64)) | (1 << (HarmonyParser.LAMBDA - 64)) | (1 << (HarmonyParser.ADDRESS_OF - 64)) | (1 << (HarmonyParser.NOT - 64)) | (1 << (HarmonyParser.CONST - 64)) | (1 << (HarmonyParser.AWAIT - 64)) | (1 << (HarmonyParser.ASSERT - 64)) | (1 << (HarmonyParser.VAR - 64)) | (1 << (HarmonyParser.TRAP - 64)) | (1 << (HarmonyParser.PASS - 64)) | (1 << (HarmonyParser.DEL - 64)) | (1 << (HarmonyParser.SPAWN - 64)) | (1 << (HarmonyParser.INVARIANT - 64)) | (1 << (HarmonyParser.GO - 64)) | (1 << (HarmonyParser.SEQUENTIAL - 64)) | (1 << (HarmonyParser.WHEN - 64)) | (1 << (HarmonyParser.LET - 64)) | (1 << (HarmonyParser.IF - 64)) | (1 << (HarmonyParser.WHILE - 64)) | (1 << (HarmonyParser.DEF - 64)) | (1 << (HarmonyParser.FOR - 64)) | (1 << (HarmonyParser.HYPER - 64)) | (1 << (HarmonyParser.COLON - 64)) | (1 << (HarmonyParser.NONE - 64)) | (1 << (HarmonyParser.ATOMICALLY - 64)) | (1 << (HarmonyParser.BOOL - 64)) | (1 << (HarmonyParser.INT - 64)) | (1 << (HarmonyParser.NAME - 64)) | (1 << (HarmonyParser.ATOM - 64)) | (1 << (HarmonyParser.OPEN_BRACK - 64)) | (1 << (HarmonyParser.OPEN_BRACES - 64)) | (1 << (HarmonyParser.OPEN_PAREN - 64)) | (1 << (HarmonyParser.SEMI_COLON - 64)) | (1 << (HarmonyParser.STRING - 64)))) != 0)): break except RecognitionException as re: @@ -3994,17 +3992,17 @@ def block(self): localctx = HarmonyParser.BlockContext(self, self._ctx, self.state) self.enterRule(localctx, 100, self.RULE_block) try: - self.state = 493 + self.state = 492 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.INDENT]: self.enterOuterAlt(localctx, 1) - self.state = 491 + self.state = 490 self.normal_block() pass elif token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.POINTER_OF, HarmonyParser.PRINT, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.STRING]: self.enterOuterAlt(localctx, 2) - self.state = 492 + self.state = 491 self.one_line_stmt() pass else: @@ -4067,33 +4065,33 @@ def normal_block(self): self.enterRule(localctx, 102, self.RULE_normal_block) try: self.enterOuterAlt(localctx, 1) - self.state = 495 + self.state = 494 self.match(HarmonyParser.INDENT) - self.state = 499 + self.state = 498 self._errHandler.sync(self) token = self._input.LA(1) - if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.COLON, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.HYPER, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: - self.state = 496 + if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.HYPER, HarmonyParser.COLON, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: + self.state = 495 self.block_stmts() pass elif token in [HarmonyParser.INDENT]: - self.state = 497 + self.state = 496 self.match(HarmonyParser.INDENT) - self.state = 498 + self.state = 497 self.block() pass else: raise NoViableAltException(self) - self.state = 501 + self.state = 500 self.match(HarmonyParser.DEDENT) - self.state = 504 + self.state = 503 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,42,self._ctx) if la_ == 1: - self.state = 502 + self.state = 501 self.match(HarmonyParser.SEMI_COLON) - self.state = 503 + self.state = 502 self.match(HarmonyParser.NL) @@ -4195,89 +4193,89 @@ def simple_stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 507 + self.state = 506 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.ATOMICALLY: - self.state = 506 + self.state = 505 self.match(HarmonyParser.ATOMICALLY) - self.state = 524 + self.state = 523 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,44,self._ctx) if la_ == 1: - self.state = 509 + self.state = 508 self.assign_stmt() pass elif la_ == 2: - self.state = 510 + self.state = 509 self.const_assign_stmt() pass elif la_ == 3: - self.state = 511 + self.state = 510 self.await_stmt() pass elif la_ == 4: - self.state = 512 + self.state = 511 self.var_stmt() pass elif la_ == 5: - self.state = 513 + self.state = 512 self.invariant_stmt() pass elif la_ == 6: - self.state = 514 + self.state = 513 self.del_stmt() pass elif la_ == 7: - self.state = 515 + self.state = 514 self.spawn_stmt() pass elif la_ == 8: - self.state = 516 + self.state = 515 self.trap_stmt() pass elif la_ == 9: - self.state = 517 + self.state = 516 self.go_stmt() pass elif la_ == 10: - self.state = 518 + self.state = 517 self.print_stmt() pass elif la_ == 11: - self.state = 519 + self.state = 518 self.pass_stmt() pass elif la_ == 12: - self.state = 520 + self.state = 519 self.sequential_stmt() pass elif la_ == 13: - self.state = 521 + self.state = 520 self.assert_stmt() pass elif la_ == 14: - self.state = 522 + self.state = 521 self.aug_assign_stmt() pass elif la_ == 15: - self.state = 523 + self.state = 522 self.expr_stmt() pass @@ -4343,39 +4341,39 @@ def compound_stmt(self): self.enterRule(localctx, 106, self.RULE_compound_stmt) try: self.enterOuterAlt(localctx, 1) - self.state = 527 + self.state = 526 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,45,self._ctx) if la_ == 1: - self.state = 526 + self.state = 525 self.match(HarmonyParser.ATOMICALLY) - self.state = 535 + self.state = 534 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.IF]: - self.state = 529 + self.state = 528 self.if_block() pass elif token in [HarmonyParser.WHILE]: - self.state = 530 + self.state = 529 self.while_block() pass elif token in [HarmonyParser.FOR]: - self.state = 531 + self.state = 530 self.for_block() pass elif token in [HarmonyParser.WHEN, HarmonyParser.LET]: - self.state = 532 + self.state = 531 self.let_when_block() pass elif token in [HarmonyParser.ATOMICALLY]: - self.state = 533 + self.state = 532 self.atomic_block() pass elif token in [HarmonyParser.DEF]: - self.state = 534 + self.state = 533 self.method_decl() pass else: @@ -4430,28 +4428,28 @@ def one_line_stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 537 + self.state = 536 self.simple_stmt() - self.state = 544 + self.state = 543 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,48,self._ctx) if la_ == 1: - self.state = 539 + self.state = 538 self._errHandler.sync(self) _la = self._input.LA(1) if _la==HarmonyParser.SEMI_COLON: - self.state = 538 + self.state = 537 self.match(HarmonyParser.SEMI_COLON) - self.state = 541 + self.state = 540 self.match(HarmonyParser.NL) pass elif la_ == 2: - self.state = 542 + self.state = 541 self.match(HarmonyParser.SEMI_COLON) - self.state = 543 + self.state = 542 self.one_line_stmt() pass @@ -4502,19 +4500,19 @@ def label(self): self.enterRule(localctx, 110, self.RULE_label) try: self.enterOuterAlt(localctx, 1) - self.state = 548 + self.state = 547 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 546 + self.state = 545 self.match(HarmonyParser.NAME) - self.state = 547 + self.state = 546 self.match(HarmonyParser.COLON) else: raise NoViableAltException(self) - self.state = 550 + self.state = 549 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,49,self._ctx) @@ -4589,65 +4587,65 @@ def stmt(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 576 + self.state = 575 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,55,self._ctx) if la_ == 1: - self.state = 556 + self.state = 555 self._errHandler.sync(self) token = self._input.LA(1) - if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.HYPER, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: - self.state = 553 + if token in [HarmonyParser.T__6, HarmonyParser.T__21, HarmonyParser.T__22, HarmonyParser.T__23, HarmonyParser.T__24, HarmonyParser.T__25, HarmonyParser.T__26, HarmonyParser.T__27, HarmonyParser.T__28, HarmonyParser.T__29, HarmonyParser.T__30, HarmonyParser.T__31, HarmonyParser.T__32, HarmonyParser.T__33, HarmonyParser.T__34, HarmonyParser.T__35, HarmonyParser.T__36, HarmonyParser.T__37, HarmonyParser.NL, HarmonyParser.POINTER_OF, HarmonyParser.IMPORT, HarmonyParser.PRINT, HarmonyParser.FROM, HarmonyParser.SETINTLEVEL, HarmonyParser.SAVE, HarmonyParser.STOP, HarmonyParser.LAMBDA, HarmonyParser.ADDRESS_OF, HarmonyParser.NOT, HarmonyParser.CONST, HarmonyParser.AWAIT, HarmonyParser.ASSERT, HarmonyParser.VAR, HarmonyParser.TRAP, HarmonyParser.PASS, HarmonyParser.DEL, HarmonyParser.SPAWN, HarmonyParser.INVARIANT, HarmonyParser.GO, HarmonyParser.SEQUENTIAL, HarmonyParser.WHEN, HarmonyParser.LET, HarmonyParser.IF, HarmonyParser.WHILE, HarmonyParser.DEF, HarmonyParser.FOR, HarmonyParser.HYPER, HarmonyParser.NONE, HarmonyParser.ATOMICALLY, HarmonyParser.BOOL, HarmonyParser.INT, HarmonyParser.NAME, HarmonyParser.ATOM, HarmonyParser.OPEN_BRACK, HarmonyParser.OPEN_BRACES, HarmonyParser.OPEN_PAREN, HarmonyParser.SEMI_COLON, HarmonyParser.STRING]: + self.state = 552 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,50,self._ctx) if la_ == 1: - self.state = 552 + self.state = 551 self.label() pass elif token in [HarmonyParser.COLON]: - self.state = 555 + self.state = 554 self.match(HarmonyParser.COLON) pass else: raise NoViableAltException(self) - self.state = 569 + self.state = 568 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,53,self._ctx) if la_ == 1: - self.state = 561 + self.state = 560 self._errHandler.sync(self) _la = self._input.LA(1) while _la==HarmonyParser.SEMI_COLON: - self.state = 558 + self.state = 557 self.match(HarmonyParser.SEMI_COLON) - self.state = 563 + self.state = 562 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 564 + self.state = 563 self.match(HarmonyParser.NL) pass elif la_ == 2: - self.state = 565 + self.state = 564 self.one_line_stmt() pass elif la_ == 3: - self.state = 566 + self.state = 565 self.compound_stmt() pass elif la_ == 4: - self.state = 567 + self.state = 566 self.import_stmt() pass elif la_ == 5: - self.state = 568 + self.state = 567 self.hyperassert_stmt() pass @@ -4655,21 +4653,21 @@ def stmt(self): pass elif la_ == 2: - self.state = 573 + self.state = 572 self._errHandler.sync(self) token = self._input.LA(1) if token in [HarmonyParser.NAME]: - self.state = 571 + self.state = 570 self.label() pass elif token in [HarmonyParser.COLON]: - self.state = 572 + self.state = 571 self.match(HarmonyParser.COLON) pass else: raise NoViableAltException(self) - self.state = 575 + self.state = 574 self.normal_block() pass diff --git a/harmony_model_checker/parser/antlr_rule_visitor.py b/harmony_model_checker/parser/antlr_rule_visitor.py index ca1af9f4..594914b8 100644 --- a/harmony_model_checker/parser/antlr_rule_visitor.py +++ b/harmony_model_checker/parser/antlr_rule_visitor.py @@ -1,4 +1,4 @@ - + from typing import Any, Union from antlr4.Token import CommonToken @@ -633,12 +633,18 @@ def visitExpr_rule(self, ctx:HarmonyParser.Expr_ruleContext): ) def visitHyperassert_stmt(self, ctx): - # Does nothing for now - return [] + start_tkn = self.get_token(ctx.start, ctx.start.text) + tkn = (ctx.getText(), *start_tkn[1:]) + condition = self.visit(ctx.hyper_condition()) + compare_op = ctx.comp_op().getText() + expected = ctx.expr().getText() + return [HyperassertAST(tkn, condition, compare_op, expected)] + # TODO: Make this more extensible def visitHyper_condition(self, ctx): - # Does nothing for now - return [] + tkn = self.get_token(ctx.start, ctx.start.text) + i = self.get_token(ctx.NAME().symbol, str(ctx.NAME())) + return HyperConditionAST(tkn, i) # Visit a parse tree produced by HarmonyParser#application. From 5297eb094e4fdb4bf5ad8af1e279c18e0fd6ff28 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Tue, 12 Apr 2022 15:36:15 -0400 Subject: [PATCH 09/12] free vector after use --- harmony_model_checker/charm/charm.c | 4 +++- harmony_model_checker/charm/vector.c | 5 +++++ harmony_model_checker/charm/vector.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 0cb86a9d..56b271d9 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -244,7 +244,7 @@ static bool onestep( bool rollback = false, failure = false, stopped = false; bool terminated = false; int choice_size = 1; // Number of choices to make. It is 1 - struct int_vector filterstates = int_vector_init(20); + struct int_vector filterstates = int_vector_init(5); for (;;) { int pc = step->ctx->pc; @@ -2304,6 +2304,8 @@ int main(int argc, char **argv){ i ); } + + int_vector_free(&node->filter_states); } fprintf(out, "\n"); fprintf(out, " ],\n"); diff --git a/harmony_model_checker/charm/vector.c b/harmony_model_checker/charm/vector.c index e78f8d04..806b1442 100644 --- a/harmony_model_checker/charm/vector.c +++ b/harmony_model_checker/charm/vector.c @@ -24,3 +24,8 @@ int int_vector_get(struct int_vector* vec, int i) { assert(i < vec->len); return vec->v[i]; } + + +void int_vector_free(struct int_vector* vec) { + free(vec); +} diff --git a/harmony_model_checker/charm/vector.h b/harmony_model_checker/charm/vector.h index dfb80a77..30689873 100644 --- a/harmony_model_checker/charm/vector.h +++ b/harmony_model_checker/charm/vector.h @@ -15,4 +15,6 @@ void int_vector_push(struct int_vector*, int); int int_vector_get(struct int_vector*, int); +void int_vector_free(struct int_vector*); + #endif From 310bbeaf536b2722bb230b123bd5c6ef995d9b9f Mon Sep 17 00:00:00 2001 From: attilusleung Date: Wed, 25 May 2022 02:36:34 -0400 Subject: [PATCH 10/12] final version before rebase --- harmony_model_checker/charm/vector.c | 2 +- harmony_model_checker/harmony/code.py | 1 - harmony_model_checker/harmony/harmony.py | 3 --- harmony_model_checker/harmony/probabilities.py | 9 ++++----- harmony_model_checker/modules/set.hny | 4 ++-- requirements.txt | 1 + 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/harmony_model_checker/charm/vector.c b/harmony_model_checker/charm/vector.c index 806b1442..7c451a16 100644 --- a/harmony_model_checker/charm/vector.c +++ b/harmony_model_checker/charm/vector.c @@ -27,5 +27,5 @@ int int_vector_get(struct int_vector* vec, int i) { void int_vector_free(struct int_vector* vec) { - free(vec); + free(vec->v); } diff --git a/harmony_model_checker/harmony/code.py b/harmony_model_checker/harmony/code.py index 350efafd..53d04ef4 100644 --- a/harmony_model_checker/harmony/code.py +++ b/harmony_model_checker/harmony/code.py @@ -128,7 +128,6 @@ def link(self): map[label] = PcValue(pc) for lop in self.labeled_ops: lop.op.substitute(map) - print(self.hypers) for h in self.hypers: if "pc" in h[1]: h[1]["pc"] = h[1]["pc"].substitute(map).pc diff --git a/harmony_model_checker/harmony/harmony.py b/harmony_model_checker/harmony/harmony.py index 099a8ca6..2bce5e7a 100644 --- a/harmony_model_checker/harmony/harmony.py +++ b/harmony_model_checker/harmony/harmony.py @@ -1173,13 +1173,10 @@ def htmldump(nodes, code, scope, node, fulldump, verbose): def dumpCode(printCode, code, scope, f=sys.stdout): lastloc = None - print(code.hypers) if printCode == "json": print("{", file=f) print(" \"filter\": [", file=f) for d in code.hypers: - print("excuse") - print(d) print(f" {json.dumps(d[1])},", file=f) print(" ],", file=f) print(' "labels": {', file=f) diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py index 1813733b..d74fd5d0 100644 --- a/harmony_model_checker/harmony/probabilities.py +++ b/harmony_model_checker/harmony/probabilities.py @@ -1,6 +1,8 @@ from collections import defaultdict import math import numpy as np +from scipy.sparse import csr_array +from scipy.sparse.linalg import spsolve as solve import json # TODO: This is just a simple port of charmpp. We probably want extended @@ -20,9 +22,8 @@ def find_probabilities(top, outputfiles, code, scope): for p in top['probabilities']: assert p['probability']['denominator'] != 0 assert p['probability']['numerator'] != 0 - matrix[p['from']][p['to']] = p['probability']['numerator'] / p['probability']['denominator'] + matrix[p['from'], p['to']] = p['probability']['numerator'] / p['probability']['denominator'] transitions[p['from']].append(p['to']) - # print(transitions) ret = [] @@ -115,10 +116,8 @@ def gen_prob(states, total_states, transitions, matrix): return {} reachable_states = np.array(reachable_states) - print(reachable_states) matrix_a = np.identity(len(reachable_states)) - matrix[np.ix_(reachable_states, reachable_states)] - print(matrix_a, list_b) - probabilities = np.linalg.solve(matrix_a, list_b) + probabilities = solve(csr_array(matrix_a), list_b) # print(reachable_states, probabilities) return dict(zip(reachable_states, probabilities)) diff --git a/harmony_model_checker/modules/set.hny b/harmony_model_checker/modules/set.hny index b43e48fb..2db41218 100644 --- a/harmony_model_checker/modules/set.hny +++ b/harmony_model_checker/modules/set.hny @@ -5,10 +5,10 @@ def issuperset(s, t): result = (s & t) == t def add(s, elt): - return s | {elt} + result = s | {elt} def remove(s, elt): - return s - {elt} + result = s - {elt} # Return set of all subsets of s of length k def combinations(s, k): diff --git a/requirements.txt b/requirements.txt index 18c45f5e..24f562e5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ pydot==1.4.2 requests==2.27.1 twine==3.7.1 numpy==1.22.0 +scipy==1.8.0 From 2e40bbdbf83e08a8480506cf65d7b204c6cacf31 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Wed, 25 May 2022 02:51:29 -0400 Subject: [PATCH 11/12] slight refactor before pr --- harmony_model_checker/harmony/brief.py | 1 - harmony_model_checker/harmony/probabilities.py | 7 ++----- harmony_model_checker/main.py | 10 +++++++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/harmony_model_checker/harmony/brief.py b/harmony_model_checker/harmony/brief.py index dfd20a69..aeb091a9 100644 --- a/harmony_model_checker/harmony/brief.py +++ b/harmony_model_checker/harmony/brief.py @@ -138,7 +138,6 @@ def run(self, outputfiles, behavior, code, scope): assert isinstance(top, dict) if top["issue"] == "No issues": behavior_parse(top, True, outputfiles, behavior) - find_probabilities(top, outputfiles, code, scope) return True # print("Issue:", top["issue"]) diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py index d74fd5d0..adfa669c 100644 --- a/harmony_model_checker/harmony/probabilities.py +++ b/harmony_model_checker/harmony/probabilities.py @@ -5,8 +5,6 @@ from scipy.sparse.linalg import spsolve as solve import json -# TODO: This is just a simple port of charmpp. We probably want extended -# functionality here. def find_probabilities(top, outputfiles, code, scope): if outputfiles['hpo'] is None: return @@ -27,7 +25,6 @@ def find_probabilities(top, outputfiles, code, scope): ret = [] - # TODO: Make this more clear instead of using an arbitary id for i in range(len(code.hypers)): s = set(states[i]) @@ -38,7 +35,7 @@ def find_probabilities(top, outputfiles, code, scope): if code is not None: try: - # This might throw an error, because it is an arbitary harmony + # TODO: This might throw an error, because it is an arbitary harmony # expression. Might want to change this in the future. expected_prob = eval(code.hypers[i][2][1]) except SyntaxError: @@ -95,6 +92,7 @@ def find_probabilities(top, outputfiles, code, scope): "probability": got_prob, }) else: + print("Ignoring probability assertions as no hny file is provided") ret.append(got_prob) with open(outputfiles['hpo'], 'w') as f: @@ -119,7 +117,6 @@ def gen_prob(states, total_states, transitions, matrix): matrix_a = np.identity(len(reachable_states)) - matrix[np.ix_(reachable_states, reachable_states)] probabilities = solve(csr_array(matrix_a), list_b) - # print(reachable_states, probabilities) return dict(zip(reachable_states, probabilities)) diff --git a/harmony_model_checker/main.py b/harmony_model_checker/main.py index fcf81564..4c5c2038 100644 --- a/harmony_model_checker/main.py +++ b/harmony_model_checker/main.py @@ -15,6 +15,7 @@ import harmony_model_checker.harmony.harmony as legacy_harmony from harmony_model_checker.harmony.genhtml import GenHTML from harmony_model_checker.harmony.brief import Brief +from harmony_model_checker.harmony.probabilities import find_probabilities from harmony_model_checker.compile import do_compile @@ -146,13 +147,20 @@ def handle_hco(ns, output_files, code=None, scope=None): b.run(output_files, behavior, code, scope) gh = GenHTML() gh.run(output_files) + + with open(output_files["hco"], encoding='utf-8') as f: + top = json.load(f) + if top["issue"] == "No issues": + find_probabilities(top, output_files, code, scope) + if not suppress_output: p = pathlib.Path(output_files["htm"]).resolve() url = "file://" + str(p) print("open " + url + " for more information", file=sys.stderr) if not disable_browser: webbrowser.open(url) - + + def handle_version(_: argparse.Namespace): print("Version:", harmony_model_checker.__package__, harmony_model_checker.__version__) From aed5be4fafb131dd1fa962731e569691efcdc180 Mon Sep 17 00:00:00 2001 From: attilusleung Date: Wed, 25 May 2022 04:02:58 -0400 Subject: [PATCH 12/12] fixed filter not updating on certain conditions --- harmony_model_checker/charm/charm.c | 11 +++++++---- harmony_model_checker/harmony/probabilities.py | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/harmony_model_checker/charm/charm.c b/harmony_model_checker/charm/charm.c index 56b271d9..c475bb1b 100644 --- a/harmony_model_checker/charm/charm.c +++ b/harmony_model_checker/charm/charm.c @@ -490,10 +490,6 @@ static bool onestep( edge->ai = step->ai; edge->log = step->log; edge->nlog = step->nlog; - // Assume uniform distribution for now - edge->probability_numerator = 1; - // TODO: Is this right? - edge->probability_denominator = choice_size; // See if this state has been computed before struct keynode *k = dict_find_lock(w->visited, &w->allocator, @@ -525,6 +521,7 @@ static bool onestep( next->len = node->len + weight; next->steps = node->steps + instrcnt; next->choice_size = choice_size; + next->filter_states = filterstates; *w->last = next; w->last = &next->next; k->value = next; @@ -558,6 +555,12 @@ static bool onestep( edge->bwdnext = next->bwd; next->bwd = edge; + // Fill in probabilities of edges + // Assume uniform distribution for now + edge->probability_numerator = 1; + // TODO: Is this right? + edge->probability_denominator = node->choice_size; + dict_find_release(w->visited, k); // We stole the access info and log diff --git a/harmony_model_checker/harmony/probabilities.py b/harmony_model_checker/harmony/probabilities.py index adfa669c..143656c1 100644 --- a/harmony_model_checker/harmony/probabilities.py +++ b/harmony_model_checker/harmony/probabilities.py @@ -23,6 +23,8 @@ def find_probabilities(top, outputfiles, code, scope): matrix[p['from'], p['to']] = p['probability']['numerator'] / p['probability']['denominator'] transitions[p['from']].append(p['to']) + print(matrix) + ret = [] for i in range(len(code.hypers)):