From d3fbbbb73d57762b08d6fe181869dd3eeb2a048c Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 16:44:00 +0100 Subject: [PATCH 001/189] add outside subdir --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 0964d60d5..72ef7e9f5 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ CXXFILES = $(wildcard src/*.cc) \ $(wildcard src/util/*.cc) \ $(wildcard src/printer/*.cc) \ $(wildcard src/specialize_grammar/*.cc) \ + $(wildcard src/outside/*.cc) \ $(UNITTEST_CXX) \ $(MODTESTS_CXX) \ $(wildcard testdata/test/*.cc) \ From 2e17ec2c05e4bee3bdc8c18524fa3064e7bbb3d6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 17:10:45 +0100 Subject: [PATCH 002/189] set up test suite for outside --- Makefile | 12 +- testdata/grammar_outside/RF00005.gap | 1550 +++++++++++++++++ testdata/grammar_outside/RFmini.gap | 155 ++ .../grammar_outside/acmsearch_RF00005.gap | 244 +++ testdata/grammar_outside/adpf.gap | 1 + testdata/grammar_outside/adpf.new | 1 + testdata/grammar_outside/adpf_hl.gap | 1 + testdata/grammar_outside/adpf_index.gap | 1 + testdata/grammar_outside/adpf_multi.gap | 1 + testdata/grammar_outside/adpf_nonamb.gap | 1 + testdata/grammar_outside/alignments.gap | 114 ++ testdata/grammar_outside/constAxiom.gap | 35 + testdata/grammar_outside/elm_filter.gap | 1 + testdata/grammar_outside/elmamun.gap | 202 +++ .../grammar_outside/elmamun_derivatives.gap | 73 + testdata/grammar_outside/g3pl.gap | 1 + testdata/grammar_outside/helene.gap | 1 + testdata/grammar_outside/hmm_cpg.gap | 302 ++++ testdata/grammar_outside/hmm_sonneregen.gap | 251 +++ .../hmm_sonneregen_properEnd.gap | 526 ++++++ testdata/grammar_outside/loco3stem.gap | 1 + testdata/grammar_outside/mini1.gap | 61 + testdata/grammar_outside/mini_bl.gap | 56 + testdata/grammar_outside/mini_complexIL.gap | 60 + testdata/grammar_outside/mini_largeIL.gap | 56 + testdata/grammar_outside/mini_twoLevelIL.gap | 39 + testdata/grammar_outside/nodangle.gap | 236 +++ .../nodangle_caddinclissue.gap | 169 ++ .../nodangle_emptyanswerissue.gap | 217 +++ .../grammar_outside/nodangle_filterempty.gap | 217 +++ testdata/grammar_outside/nodangle_issue.gap | 167 ++ testdata/grammar_outside/nodangle_issue2.gap | 170 ++ testdata/grammar_outside/nodangle_mlIssue.gap | 169 ++ .../nodangle_noNTrhs_issue.gap | 167 ++ .../grammar_outside/nodangle_tooManyLoops.gap | 212 +++ .../grammar_outside/nodangle_withoverlay.gap | 237 +++ .../grammar_outside/nonzero_constsize.gap | 51 + testdata/grammar_outside/pknotsRG.gap | 1 + testdata/grammar_outside/rnashapes2wip.gap | 1 + testdata/grammar_outside/rnashapesmfe.gap | 1 + testdata/grammar_outside/rnashapespf.gap | 1 + testdata/grammar_outside/single_block.gap | 1 + testdata/grammar_outside/stefan3.gap | 1 + testdata/grammar_outside/stefan4.gap | 1 + testdata/grammar_outside/tdm2hp.gap | 1 + testdata/grammar_outside/tdm2hporig.gap | 1 + testdata/grammar_outside/tmhmm.gap | 951 ++++++++++ testdata/grammar_outside/tmhmm_debug.gap | 160 ++ testdata/grammar_outside/unblock_alot.gap | 239 +++ .../unblock_multialt_parentNT.gap | 39 + .../unblock_multialt_parentSimple.gap | 39 + .../unblock_onealt_parentNT.gap | 39 + .../unblock_onealt_parentSimple.gap | 39 + testdata/modtest/outside_checksemantics.cc | 69 + testdata/modtest/run_outside.sh | 67 + 55 files changed, 7406 insertions(+), 3 deletions(-) create mode 100644 testdata/grammar_outside/RF00005.gap create mode 100644 testdata/grammar_outside/RFmini.gap create mode 100644 testdata/grammar_outside/acmsearch_RF00005.gap create mode 120000 testdata/grammar_outside/adpf.gap create mode 120000 testdata/grammar_outside/adpf.new create mode 120000 testdata/grammar_outside/adpf_hl.gap create mode 120000 testdata/grammar_outside/adpf_index.gap create mode 120000 testdata/grammar_outside/adpf_multi.gap create mode 120000 testdata/grammar_outside/adpf_nonamb.gap create mode 100644 testdata/grammar_outside/alignments.gap create mode 100644 testdata/grammar_outside/constAxiom.gap create mode 120000 testdata/grammar_outside/elm_filter.gap create mode 100644 testdata/grammar_outside/elmamun.gap create mode 100644 testdata/grammar_outside/elmamun_derivatives.gap create mode 120000 testdata/grammar_outside/g3pl.gap create mode 120000 testdata/grammar_outside/helene.gap create mode 100644 testdata/grammar_outside/hmm_cpg.gap create mode 100644 testdata/grammar_outside/hmm_sonneregen.gap create mode 100644 testdata/grammar_outside/hmm_sonneregen_properEnd.gap create mode 120000 testdata/grammar_outside/loco3stem.gap create mode 100644 testdata/grammar_outside/mini1.gap create mode 100644 testdata/grammar_outside/mini_bl.gap create mode 100644 testdata/grammar_outside/mini_complexIL.gap create mode 100644 testdata/grammar_outside/mini_largeIL.gap create mode 100644 testdata/grammar_outside/mini_twoLevelIL.gap create mode 100644 testdata/grammar_outside/nodangle.gap create mode 100644 testdata/grammar_outside/nodangle_caddinclissue.gap create mode 100644 testdata/grammar_outside/nodangle_emptyanswerissue.gap create mode 100644 testdata/grammar_outside/nodangle_filterempty.gap create mode 100644 testdata/grammar_outside/nodangle_issue.gap create mode 100644 testdata/grammar_outside/nodangle_issue2.gap create mode 100644 testdata/grammar_outside/nodangle_mlIssue.gap create mode 100644 testdata/grammar_outside/nodangle_noNTrhs_issue.gap create mode 100644 testdata/grammar_outside/nodangle_tooManyLoops.gap create mode 100644 testdata/grammar_outside/nodangle_withoverlay.gap create mode 100644 testdata/grammar_outside/nonzero_constsize.gap create mode 120000 testdata/grammar_outside/pknotsRG.gap create mode 120000 testdata/grammar_outside/rnashapes2wip.gap create mode 120000 testdata/grammar_outside/rnashapesmfe.gap create mode 120000 testdata/grammar_outside/rnashapespf.gap create mode 120000 testdata/grammar_outside/single_block.gap create mode 120000 testdata/grammar_outside/stefan3.gap create mode 120000 testdata/grammar_outside/stefan4.gap create mode 120000 testdata/grammar_outside/tdm2hp.gap create mode 120000 testdata/grammar_outside/tdm2hporig.gap create mode 100644 testdata/grammar_outside/tmhmm.gap create mode 100644 testdata/grammar_outside/tmhmm_debug.gap create mode 100644 testdata/grammar_outside/unblock_alot.gap create mode 100644 testdata/grammar_outside/unblock_multialt_parentNT.gap create mode 100644 testdata/grammar_outside/unblock_multialt_parentSimple.gap create mode 100644 testdata/grammar_outside/unblock_onealt_parentNT.gap create mode 100644 testdata/grammar_outside/unblock_onealt_parentSimple.gap create mode 100644 testdata/modtest/outside_checksemantics.cc create mode 100644 testdata/modtest/run_outside.sh diff --git a/Makefile b/Makefile index 72ef7e9f5..76cae78e2 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ gapc: src/gapc.o $(MAIN_OBJ) src/version.o src/prefix.o stats \ test_rt_tab \ -multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser: src/version.o src/prefix.o +multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics: src/version.o src/prefix.o backtrack: src/version.o @@ -284,11 +284,13 @@ testdata/unittest/%: testdata/unittest/%.o # modtest -MODTESTS_CXX:= $(wildcard testdata/modtest/*.cc) +MODTESTS_CXX:= $(wildcard testdata/modtest/multi*.cc) +MODOUTSIDETESTS_CXX:= $(wildcard testdata/modtest/outside*.cc) MODTESTS:=$(sort $(subst testdata/modtest/,,$(MODTESTS_CXX:.cc=))) +MODOUTSIDETESTS:=$(sort $(subst testdata/modtest/,,$(MODOUTSIDETESTS_CXX:.cc=))) modtests: $(MODTESTS) - +outsidetests: $(MODOUTSIDETESTS) # paraltest @@ -308,6 +310,10 @@ test-mod: modtests cd testdata/modtest &&\ $(SHELL) run.sh $(TRUTH_DIR)/Mod$(TRUTH_SUFFIX) $(MODTESTS) +test-mod_outside: outsidetests + cd testdata/modtest &&\ + $(SHELL) run_outside.sh $(TRUTH_DIR)/Mod$(TRUTH_SUFFIX) $(MODOUTSIDETESTS) + gen-mod: modtests cd testdata/modtest &&\ $(SHELL) gen.sh $(TRUTH_DIR)/Mod$(TRUTH_SUFFIX) $(MODTESTS) diff --git a/testdata/grammar_outside/RF00005.gap b/testdata/grammar_outside/RF00005.gap new file mode 100644 index 000000000..cb9015c34 --- /dev/null +++ b/testdata/grammar_outside/RF00005.gap @@ -0,0 +1,1550 @@ +import "RF00005_data.hh" + +signature sig_cm(alphabet, answer) { + answer silent_transition(float, answer; int); + answer left_transition(float, alphabet, answer; int); + answer right_transition(float, answer, alphabet; int); + answer pair_transition(float, alphabet, answer, alphabet; int); + answer bifurcation_transition(float, float, answer, answer; int); + answer nil(float, void; int); + choice [answer] h([answer]); +} + + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_cyk implements sig_cm(alphabet=char, answer=float) { + float silent_transition(float tsc, float x; int pos) { + return tsc + x; + } + float left_transition(float tsc, alphabet a, float x; int pos) { + return tsc + getEmission(pos, a) + x; + } + float right_transition(float tsc, float x, alphabet a; int pos) { + return tsc + getEmission(pos, a) + x; + } + float pair_transition(float tsc, alphabet a, float x, alphabet b; int pos) { + return tsc + getPairEmission(pos, a, b) + x; + } + float bifurcation_transition(float tsc_left, float tsc_right, float left, float right; int pos) { + return tsc_left + tsc_right + left + right; + } + float nil(float tsc, void; int pos) { + return tsc; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_inside extends alg_cyk { + choice [float] h([float] candidates) { + return list(bitsum(candidates)); + } +} + +grammar gra_cm uses sig_cm(axiom = state_S_0) { + // node [ ROOT 0 ] + state_S_0 = silent_transition(CONST_FLOAT(-11.033000), state_IL_1; 0) + | silent_transition(CONST_FLOAT(-12.278000), state_IR_2; 0) + | silent_transition(CONST_FLOAT(-0.061000), state_MR_3; 0) + | silent_transition(CONST_FLOAT(-4.629000), state_D_4; 0) + # h; + + state_IL_1 = left_transition(CONST_FLOAT(-2.817000), CHAR, state_IL_1; 1) + | left_transition(CONST_FLOAT(-4.319000), CHAR, state_IR_2; 1) + | left_transition(CONST_FLOAT(-0.613000), CHAR, state_MR_3; 1) + | left_transition(CONST_FLOAT(-2.698000), CHAR, state_D_4; 1) + # h; + + state_IR_2 = right_transition(CONST_FLOAT(-1.925000), state_IR_2, CHAR; 2) + | right_transition(CONST_FLOAT(-0.554000), state_MR_3, CHAR; 2) + | right_transition(CONST_FLOAT(-4.164000), state_D_4, CHAR; 2) + # h; + + // node [ MATR 1 ] + state_MR_3 = right_transition(CONST_FLOAT(-11.036000), state_IR_5, CHAR; 3) + | right_transition(CONST_FLOAT(-0.003000), state_MP_6, CHAR; 3) + | right_transition(CONST_FLOAT(-10.852000), state_ML_7, CHAR; 3) + | right_transition(CONST_FLOAT(-11.064000), state_MR_8, CHAR; 3) + | right_transition(CONST_FLOAT(-11.956000), state_D_9, CHAR; 3) + # h; + + state_D_4 = silent_transition(CONST_FLOAT(-1.727000), state_IR_5; 4) + | silent_transition(CONST_FLOAT(-1.310000), state_MP_6; 4) + | silent_transition(CONST_FLOAT(-4.986000), state_ML_7; 4) + | silent_transition(CONST_FLOAT(-2.211000), state_MR_8; 4) + | silent_transition(CONST_FLOAT(-4.411000), state_D_9; 4) + # h; + + state_IR_5 = right_transition(CONST_FLOAT(-3.146000), state_IR_5, CHAR; 5) + | right_transition(CONST_FLOAT(-0.277000), state_MP_6, CHAR; 5) + | right_transition(CONST_FLOAT(-6.657000), state_ML_7, CHAR; 5) + | right_transition(CONST_FLOAT(-4.825000), state_MR_8, CHAR; 5) + | right_transition(CONST_FLOAT(-5.931000), state_D_9, CHAR; 5) + # h; + + // node [ MATP 2 ] + state_MP_6 = pair_transition(CONST_FLOAT(-12.104000), CHAR, state_IL_10, CHAR; 6) + | pair_transition(CONST_FLOAT(-12.043000), CHAR, state_IR_11, CHAR; 6) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_12, CHAR; 6) + | pair_transition(CONST_FLOAT(-10.819000), CHAR, state_ML_13, CHAR; 6) + | pair_transition(CONST_FLOAT(-11.099000), CHAR, state_MR_14, CHAR; 6) + | pair_transition(CONST_FLOAT(-11.494000), CHAR, state_D_15, CHAR; 6) + # h; + + state_ML_7 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_10; 7) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_11; 7) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_12; 7) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_13; 7) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_14; 7) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_15; 7) + # h; + + state_MR_8 = right_transition(CONST_FLOAT(-7.909000), state_IL_10, CHAR; 8) + | right_transition(CONST_FLOAT(-6.638000), state_IR_11, CHAR; 8) + | right_transition(CONST_FLOAT(-0.637000), state_MP_12, CHAR; 8) + | right_transition(CONST_FLOAT(-6.616000), state_ML_13, CHAR; 8) + | right_transition(CONST_FLOAT(-1.750000), state_MR_14, CHAR; 8) + | right_transition(CONST_FLOAT(-4.829000), state_D_15, CHAR; 8) + # h; + + state_D_9 = silent_transition(CONST_FLOAT(-9.049000), state_IL_10; 9) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_11; 9) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_12; 9) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_13; 9) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_14; 9) + | silent_transition(CONST_FLOAT(-0.319000), state_D_15; 9) + # h; + + state_IL_10 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_10; 10) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_11; 10) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_12; 10) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_13; 10) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_14; 10) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_15; 10) + # h; + + state_IR_11 = right_transition(CONST_FLOAT(-2.408000), state_IR_11, CHAR; 11) + | right_transition(CONST_FLOAT(-0.496000), state_MP_12, CHAR; 11) + | right_transition(CONST_FLOAT(-5.920000), state_ML_13, CHAR; 11) + | right_transition(CONST_FLOAT(-4.087000), state_MR_14, CHAR; 11) + | right_transition(CONST_FLOAT(-5.193000), state_D_15, CHAR; 11) + # h; + + // node [ MATP 3 ] + state_MP_12 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_16, CHAR; 12) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_17, CHAR; 12) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_18, CHAR; 12) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_19, CHAR; 12) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_20, CHAR; 12) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_21, CHAR; 12) + # h; + + state_ML_13 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_16; 13) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_17; 13) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_18; 13) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_19; 13) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_20; 13) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_21; 13) + # h; + + state_MR_14 = right_transition(CONST_FLOAT(-6.988000), state_IL_16, CHAR; 14) + | right_transition(CONST_FLOAT(-5.717000), state_IR_17, CHAR; 14) + | right_transition(CONST_FLOAT(-1.625000), state_MP_18, CHAR; 14) + | right_transition(CONST_FLOAT(-5.695000), state_ML_19, CHAR; 14) + | right_transition(CONST_FLOAT(-0.829000), state_MR_20, CHAR; 14) + | right_transition(CONST_FLOAT(-3.908000), state_D_21, CHAR; 14) + # h; + + state_D_15 = silent_transition(CONST_FLOAT(-9.049000), state_IL_16; 15) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_17; 15) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_18; 15) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_19; 15) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_20; 15) + | silent_transition(CONST_FLOAT(-0.319000), state_D_21; 15) + # h; + + state_IL_16 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_16; 16) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_17; 16) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_18; 16) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_19; 16) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_20; 16) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_21; 16) + # h; + + state_IR_17 = right_transition(CONST_FLOAT(-2.408000), state_IR_17, CHAR; 17) + | right_transition(CONST_FLOAT(-0.496000), state_MP_18, CHAR; 17) + | right_transition(CONST_FLOAT(-5.920000), state_ML_19, CHAR; 17) + | right_transition(CONST_FLOAT(-4.087000), state_MR_20, CHAR; 17) + | right_transition(CONST_FLOAT(-5.193000), state_D_21, CHAR; 17) + # h; + + // node [ MATP 4 ] + state_MP_18 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_22, CHAR; 18) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_23, CHAR; 18) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_24, CHAR; 18) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_25, CHAR; 18) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_26, CHAR; 18) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_27, CHAR; 18) + # h; + + state_ML_19 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_22; 19) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_23; 19) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_24; 19) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_25; 19) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_26; 19) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_27; 19) + # h; + + state_MR_20 = right_transition(CONST_FLOAT(-6.988000), state_IL_22, CHAR; 20) + | right_transition(CONST_FLOAT(-5.717000), state_IR_23, CHAR; 20) + | right_transition(CONST_FLOAT(-1.625000), state_MP_24, CHAR; 20) + | right_transition(CONST_FLOAT(-5.695000), state_ML_25, CHAR; 20) + | right_transition(CONST_FLOAT(-0.829000), state_MR_26, CHAR; 20) + | right_transition(CONST_FLOAT(-3.908000), state_D_27, CHAR; 20) + # h; + + state_D_21 = silent_transition(CONST_FLOAT(-9.049000), state_IL_22; 21) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_23; 21) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_24; 21) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_25; 21) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_26; 21) + | silent_transition(CONST_FLOAT(-0.319000), state_D_27; 21) + # h; + + state_IL_22 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_22; 22) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_23; 22) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_24; 22) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_25; 22) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_26; 22) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_27; 22) + # h; + + state_IR_23 = right_transition(CONST_FLOAT(-2.408000), state_IR_23, CHAR; 23) + | right_transition(CONST_FLOAT(-0.496000), state_MP_24, CHAR; 23) + | right_transition(CONST_FLOAT(-5.920000), state_ML_25, CHAR; 23) + | right_transition(CONST_FLOAT(-4.087000), state_MR_26, CHAR; 23) + | right_transition(CONST_FLOAT(-5.193000), state_D_27, CHAR; 23) + # h; + + // node [ MATP 5 ] + state_MP_24 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_28, CHAR; 24) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_29, CHAR; 24) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_30, CHAR; 24) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_31, CHAR; 24) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_32, CHAR; 24) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_33, CHAR; 24) + # h; + + state_ML_25 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_28; 25) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_29; 25) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_30; 25) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_31; 25) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_32; 25) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_33; 25) + # h; + + state_MR_26 = right_transition(CONST_FLOAT(-6.988000), state_IL_28, CHAR; 26) + | right_transition(CONST_FLOAT(-5.717000), state_IR_29, CHAR; 26) + | right_transition(CONST_FLOAT(-1.625000), state_MP_30, CHAR; 26) + | right_transition(CONST_FLOAT(-5.695000), state_ML_31, CHAR; 26) + | right_transition(CONST_FLOAT(-0.829000), state_MR_32, CHAR; 26) + | right_transition(CONST_FLOAT(-3.908000), state_D_33, CHAR; 26) + # h; + + state_D_27 = silent_transition(CONST_FLOAT(-9.049000), state_IL_28; 27) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_29; 27) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_30; 27) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_31; 27) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_32; 27) + | silent_transition(CONST_FLOAT(-0.319000), state_D_33; 27) + # h; + + state_IL_28 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_28; 28) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_29; 28) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_30; 28) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_31; 28) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_32; 28) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_33; 28) + # h; + + state_IR_29 = right_transition(CONST_FLOAT(-2.408000), state_IR_29, CHAR; 29) + | right_transition(CONST_FLOAT(-0.496000), state_MP_30, CHAR; 29) + | right_transition(CONST_FLOAT(-5.920000), state_ML_31, CHAR; 29) + | right_transition(CONST_FLOAT(-4.087000), state_MR_32, CHAR; 29) + | right_transition(CONST_FLOAT(-5.193000), state_D_33, CHAR; 29) + # h; + + // node [ MATP 6 ] + state_MP_30 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_34, CHAR; 30) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_35, CHAR; 30) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_36, CHAR; 30) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_37, CHAR; 30) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_38, CHAR; 30) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_39, CHAR; 30) + # h; + + state_ML_31 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_34; 31) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_35; 31) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_36; 31) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_37; 31) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_38; 31) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_39; 31) + # h; + + state_MR_32 = right_transition(CONST_FLOAT(-6.988000), state_IL_34, CHAR; 32) + | right_transition(CONST_FLOAT(-5.717000), state_IR_35, CHAR; 32) + | right_transition(CONST_FLOAT(-1.625000), state_MP_36, CHAR; 32) + | right_transition(CONST_FLOAT(-5.695000), state_ML_37, CHAR; 32) + | right_transition(CONST_FLOAT(-0.829000), state_MR_38, CHAR; 32) + | right_transition(CONST_FLOAT(-3.908000), state_D_39, CHAR; 32) + # h; + + state_D_33 = silent_transition(CONST_FLOAT(-9.049000), state_IL_34; 33) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_35; 33) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_36; 33) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_37; 33) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_38; 33) + | silent_transition(CONST_FLOAT(-0.319000), state_D_39; 33) + # h; + + state_IL_34 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_34; 34) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_35; 34) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_36; 34) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_37; 34) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_38; 34) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_39; 34) + # h; + + state_IR_35 = right_transition(CONST_FLOAT(-2.408000), state_IR_35, CHAR; 35) + | right_transition(CONST_FLOAT(-0.496000), state_MP_36, CHAR; 35) + | right_transition(CONST_FLOAT(-5.920000), state_ML_37, CHAR; 35) + | right_transition(CONST_FLOAT(-4.087000), state_MR_38, CHAR; 35) + | right_transition(CONST_FLOAT(-5.193000), state_D_39, CHAR; 35) + # h; + + // node [ MATP 7 ] + state_MP_36 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_40, CHAR; 36) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_41, CHAR; 36) + | pair_transition(CONST_FLOAT(-0.004000), CHAR, state_MP_42, CHAR; 36) + | pair_transition(CONST_FLOAT(-9.656000), CHAR, state_ML_43, CHAR; 36) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_44, CHAR; 36) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_45, CHAR; 36) + # h; + + state_ML_37 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_40; 37) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_41; 37) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_42; 37) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_43; 37) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_44; 37) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_45; 37) + # h; + + state_MR_38 = right_transition(CONST_FLOAT(-6.988000), state_IL_40, CHAR; 38) + | right_transition(CONST_FLOAT(-5.717000), state_IR_41, CHAR; 38) + | right_transition(CONST_FLOAT(-1.625000), state_MP_42, CHAR; 38) + | right_transition(CONST_FLOAT(-5.695000), state_ML_43, CHAR; 38) + | right_transition(CONST_FLOAT(-0.829000), state_MR_44, CHAR; 38) + | right_transition(CONST_FLOAT(-3.908000), state_D_45, CHAR; 38) + # h; + + state_D_39 = silent_transition(CONST_FLOAT(-9.049000), state_IL_40; 39) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_41; 39) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_42; 39) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_43; 39) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_44; 39) + | silent_transition(CONST_FLOAT(-0.319000), state_D_45; 39) + # h; + + state_IL_40 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_40; 40) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_41; 40) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_42; 40) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_43; 40) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_44; 40) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_45; 40) + # h; + + state_IR_41 = right_transition(CONST_FLOAT(-2.408000), state_IR_41, CHAR; 41) + | right_transition(CONST_FLOAT(-0.496000), state_MP_42, CHAR; 41) + | right_transition(CONST_FLOAT(-5.920000), state_ML_43, CHAR; 41) + | right_transition(CONST_FLOAT(-4.087000), state_MR_44, CHAR; 41) + | right_transition(CONST_FLOAT(-5.193000), state_D_45, CHAR; 41) + # h; + + // node [ MATP 8 ] + state_MP_42 = pair_transition(CONST_FLOAT(-11.232000), CHAR, state_IL_46, CHAR; 42) + | pair_transition(CONST_FLOAT(-6.672000), CHAR, state_IR_47, CHAR; 42) + | pair_transition(CONST_FLOAT(-0.016000), CHAR, state_ML_48, CHAR; 42) + | pair_transition(CONST_FLOAT(-9.853000), CHAR, state_D_49, CHAR; 42) + # h; + + state_ML_43 = left_transition(CONST_FLOAT(-3.836000), CHAR, state_IL_46; 43) + | left_transition(CONST_FLOAT(-4.018000), CHAR, state_IR_47; 43) + | left_transition(CONST_FLOAT(-0.475000), CHAR, state_ML_48; 43) + | left_transition(CONST_FLOAT(-2.747000), CHAR, state_D_49; 43) + # h; + + state_MR_44 = right_transition(CONST_FLOAT(-4.809000), state_IL_46, CHAR; 44) + | right_transition(CONST_FLOAT(-3.838000), state_IR_47, CHAR; 44) + | right_transition(CONST_FLOAT(-1.706000), state_ML_48, CHAR; 44) + | right_transition(CONST_FLOAT(-0.766000), state_D_49, CHAR; 44) + # h; + + state_D_45 = silent_transition(CONST_FLOAT(-4.568000), state_IL_46; 45) + | silent_transition(CONST_FLOAT(-4.250000), state_IR_47; 45) + | silent_transition(CONST_FLOAT(-2.265000), state_ML_48; 45) + | silent_transition(CONST_FLOAT(-0.520000), state_D_49; 45) + # h; + + state_IL_46 = left_transition(CONST_FLOAT(-1.686000), CHAR, state_IL_46; 46) + | left_transition(CONST_FLOAT(-2.369000), CHAR, state_IR_47; 46) + | left_transition(CONST_FLOAT(-1.117000), CHAR, state_ML_48; 46) + | left_transition(CONST_FLOAT(-4.855000), CHAR, state_D_49; 46) + # h; + + state_IR_47 = right_transition(CONST_FLOAT(-1.924000), state_IR_47, CHAR; 47) + | right_transition(CONST_FLOAT(-0.523000), state_ML_48, CHAR; 47) + | right_transition(CONST_FLOAT(-4.624000), state_D_49, CHAR; 47) + # h; + + // node [ MATL 9 ] + state_ML_48 = left_transition(CONST_FLOAT(-5.352000), CHAR, state_IL_50; 48) + | left_transition(CONST_FLOAT(-0.048000), CHAR, state_ML_51; 48) + | left_transition(CONST_FLOAT(-6.940000), CHAR, state_D_52; 48) + # h; + + state_D_49 = silent_transition(CONST_FLOAT(-6.174000), state_IL_50; 49) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_51; 49) + | silent_transition(CONST_FLOAT(-0.566000), state_D_52; 49) + # h; + + state_IL_50 = left_transition(CONST_FLOAT(-2.459000), CHAR, state_IL_50; 50) + | left_transition(CONST_FLOAT(-0.340000), CHAR, state_ML_51; 50) + | left_transition(CONST_FLOAT(-5.159000), CHAR, state_D_52; 50) + # h; + + // node [ MATL 10 ] + state_ML_51 = left_transition(CONST_FLOAT(-5.143000), CHAR, state_IL_53; 51) + | left_transition(CONST_FLOAT(-0.041000), CHAR, state_B_54; 51) + # h; + + state_D_52 = silent_transition(CONST_FLOAT(-8.552000), state_IL_53; 52) + | silent_transition(CONST_FLOAT(-0.004000), state_B_54; 52) + # h; + + state_IL_53 = left_transition(CONST_FLOAT(-3.425000), CHAR, state_IL_53; 53) + | left_transition(CONST_FLOAT(-0.141000), CHAR, state_B_54; 53) + # h; + + // node [ BIF 11 ] + state_B_54 = bifurcation_transition(CONST_FLOAT(0.000000), CONST_FLOAT(0.000000), state_S_121, state_S_55; 54) + # h; + + // node [ BEGR 42 ] + state_S_55 = silent_transition(CONST_FLOAT(-12.148000), state_IL_56; 55) + | silent_transition(CONST_FLOAT(-0.001000), state_ML_57; 55) + | silent_transition(CONST_FLOAT(-10.802000), state_D_58; 55) + # h; + + state_IL_56 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_56; 56) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_57; 56) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_58; 56) + # h; + + // node [ MATL 43 ] + state_ML_57 = left_transition(CONST_FLOAT(-12.148000), CHAR, state_IL_59; 57) + | left_transition(CONST_FLOAT(-0.425000), CHAR, state_ML_60; 57) + | left_transition(CONST_FLOAT(-1.972000), CHAR, state_D_61; 57) + # h; + + state_D_58 = silent_transition(CONST_FLOAT(-6.174000), state_IL_59; 58) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_60; 58) + | silent_transition(CONST_FLOAT(-0.566000), state_D_61; 58) + # h; + + state_IL_59 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_59; 59) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_60; 59) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_61; 59) + # h; + + // node [ MATL 44 ] + state_ML_60 = left_transition(CONST_FLOAT(-4.403000), CHAR, state_IL_62; 60) + | left_transition(CONST_FLOAT(-0.079000), CHAR, state_ML_63; 60) + | left_transition(CONST_FLOAT(-7.327000), CHAR, state_D_64; 60) + # h; + + state_D_61 = silent_transition(CONST_FLOAT(-0.051000), state_IL_62; 61) + | silent_transition(CONST_FLOAT(-5.676000), state_ML_63; 61) + | silent_transition(CONST_FLOAT(-6.016000), state_D_64; 61) + # h; + + state_IL_62 = left_transition(CONST_FLOAT(-0.113000), CHAR, state_IL_62; 62) + | left_transition(CONST_FLOAT(-4.469000), CHAR, state_ML_63; 62) + | left_transition(CONST_FLOAT(-5.038000), CHAR, state_D_64; 62) + # h; + + // node [ MATL 45 ] + state_ML_63 = left_transition(CONST_FLOAT(-1.234000), CHAR, state_IL_65; 63) + | left_transition(CONST_FLOAT(-0.803000), CHAR, state_ML_66; 63) + | left_transition(CONST_FLOAT(-9.120000), CHAR, state_D_67; 63) + # h; + + state_D_64 = silent_transition(CONST_FLOAT(-6.563000), state_IL_65; 64) + | silent_transition(CONST_FLOAT(-0.061000), state_ML_66; 64) + | silent_transition(CONST_FLOAT(-5.013000), state_D_67; 64) + # h; + + state_IL_65 = left_transition(CONST_FLOAT(-3.838000), CHAR, state_IL_65; 65) + | left_transition(CONST_FLOAT(-0.110000), CHAR, state_ML_66; 65) + | left_transition(CONST_FLOAT(-8.281000), CHAR, state_D_67; 65) + # h; + + // node [ MATL 46 ] + state_ML_66 = left_transition(CONST_FLOAT(-11.090000), CHAR, state_IL_68; 66) + | left_transition(CONST_FLOAT(-0.002000), CHAR, state_MP_69; 66) + | left_transition(CONST_FLOAT(-10.906000), CHAR, state_ML_70; 66) + | left_transition(CONST_FLOAT(-11.118000), CHAR, state_MR_71; 66) + | left_transition(CONST_FLOAT(-12.010000), CHAR, state_D_72; 66) + # h; + + state_D_67 = silent_transition(CONST_FLOAT(-5.092000), state_IL_68; 67) + | silent_transition(CONST_FLOAT(-0.712000), state_MP_69; 67) + | silent_transition(CONST_FLOAT(-4.353000), state_ML_70; 67) + | silent_transition(CONST_FLOAT(-2.728000), state_MR_71; 67) + | silent_transition(CONST_FLOAT(-2.640000), state_D_72; 67) + # h; + + state_IL_68 = left_transition(CONST_FLOAT(-2.408000), CHAR, state_IL_68; 68) + | left_transition(CONST_FLOAT(-0.496000), CHAR, state_MP_69; 68) + | left_transition(CONST_FLOAT(-4.087000), CHAR, state_ML_70; 68) + | left_transition(CONST_FLOAT(-5.920000), CHAR, state_MR_71; 68) + | left_transition(CONST_FLOAT(-5.193000), CHAR, state_D_72; 68) + # h; + + // node [ MATP 47 ] + state_MP_69 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_73, CHAR; 69) + | pair_transition(CONST_FLOAT(-6.010000), CHAR, state_IR_74, CHAR; 69) + | pair_transition(CONST_FLOAT(-0.025000), CHAR, state_MP_75, CHAR; 69) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_76, CHAR; 69) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_77, CHAR; 69) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_78, CHAR; 69) + # h; + + state_ML_70 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_73; 70) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_74; 70) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_75; 70) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_76; 70) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_77; 70) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_78; 70) + # h; + + state_MR_71 = right_transition(CONST_FLOAT(-6.988000), state_IL_73, CHAR; 71) + | right_transition(CONST_FLOAT(-5.717000), state_IR_74, CHAR; 71) + | right_transition(CONST_FLOAT(-1.625000), state_MP_75, CHAR; 71) + | right_transition(CONST_FLOAT(-5.695000), state_ML_76, CHAR; 71) + | right_transition(CONST_FLOAT(-0.829000), state_MR_77, CHAR; 71) + | right_transition(CONST_FLOAT(-3.908000), state_D_78, CHAR; 71) + # h; + + state_D_72 = silent_transition(CONST_FLOAT(-9.049000), state_IL_73; 72) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_74; 72) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_75; 72) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_76; 72) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_77; 72) + | silent_transition(CONST_FLOAT(-0.319000), state_D_78; 72) + # h; + + state_IL_73 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_73; 73) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_74; 73) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_75; 73) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_76; 73) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_77; 73) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_78; 73) + # h; + + state_IR_74 = right_transition(CONST_FLOAT(-3.202000), state_IR_74, CHAR; 74) + | right_transition(CONST_FLOAT(-0.265000), state_MP_75, CHAR; 74) + | right_transition(CONST_FLOAT(-6.713000), state_ML_76, CHAR; 74) + | right_transition(CONST_FLOAT(-4.881000), state_MR_77, CHAR; 74) + | right_transition(CONST_FLOAT(-5.987000), state_D_78, CHAR; 74) + # h; + + // node [ MATP 48 ] + state_MP_75 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_79, CHAR; 75) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_80, CHAR; 75) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_81, CHAR; 75) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_82, CHAR; 75) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_83, CHAR; 75) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_84, CHAR; 75) + # h; + + state_ML_76 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_79; 76) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_80; 76) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_81; 76) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_82; 76) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_83; 76) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_84; 76) + # h; + + state_MR_77 = right_transition(CONST_FLOAT(-6.988000), state_IL_79, CHAR; 77) + | right_transition(CONST_FLOAT(-5.717000), state_IR_80, CHAR; 77) + | right_transition(CONST_FLOAT(-1.625000), state_MP_81, CHAR; 77) + | right_transition(CONST_FLOAT(-5.695000), state_ML_82, CHAR; 77) + | right_transition(CONST_FLOAT(-0.829000), state_MR_83, CHAR; 77) + | right_transition(CONST_FLOAT(-3.908000), state_D_84, CHAR; 77) + # h; + + state_D_78 = silent_transition(CONST_FLOAT(-9.049000), state_IL_79; 78) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_80; 78) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_81; 78) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_82; 78) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_83; 78) + | silent_transition(CONST_FLOAT(-0.319000), state_D_84; 78) + # h; + + state_IL_79 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_79; 79) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_80; 79) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_81; 79) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_82; 79) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_83; 79) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_84; 79) + # h; + + state_IR_80 = right_transition(CONST_FLOAT(-2.408000), state_IR_80, CHAR; 80) + | right_transition(CONST_FLOAT(-0.496000), state_MP_81, CHAR; 80) + | right_transition(CONST_FLOAT(-5.920000), state_ML_82, CHAR; 80) + | right_transition(CONST_FLOAT(-4.087000), state_MR_83, CHAR; 80) + | right_transition(CONST_FLOAT(-5.193000), state_D_84, CHAR; 80) + # h; + + // node [ MATP 49 ] + state_MP_81 = pair_transition(CONST_FLOAT(-6.146000), CHAR, state_IL_85, CHAR; 81) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_86, CHAR; 81) + | pair_transition(CONST_FLOAT(-0.026000), CHAR, state_MP_87, CHAR; 81) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_88, CHAR; 81) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_89, CHAR; 81) + | pair_transition(CONST_FLOAT(-8.649000), CHAR, state_D_90, CHAR; 81) + # h; + + state_ML_82 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_85; 82) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_86; 82) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_87; 82) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_88; 82) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_89; 82) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_90; 82) + # h; + + state_MR_83 = right_transition(CONST_FLOAT(-6.988000), state_IL_85, CHAR; 83) + | right_transition(CONST_FLOAT(-5.717000), state_IR_86, CHAR; 83) + | right_transition(CONST_FLOAT(-1.625000), state_MP_87, CHAR; 83) + | right_transition(CONST_FLOAT(-5.695000), state_ML_88, CHAR; 83) + | right_transition(CONST_FLOAT(-0.829000), state_MR_89, CHAR; 83) + | right_transition(CONST_FLOAT(-3.908000), state_D_90, CHAR; 83) + # h; + + state_D_84 = silent_transition(CONST_FLOAT(-9.049000), state_IL_85; 84) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_86; 84) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_87; 84) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_88; 84) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_89; 84) + | silent_transition(CONST_FLOAT(-0.319000), state_D_90; 84) + # h; + + state_IL_85 = left_transition(CONST_FLOAT(-3.649000), CHAR, state_IL_85; 85) + | left_transition(CONST_FLOAT(-3.912000), CHAR, state_IR_86; 85) + | left_transition(CONST_FLOAT(-0.313000), CHAR, state_MP_87; 85) + | left_transition(CONST_FLOAT(-5.567000), CHAR, state_ML_88; 85) + | left_transition(CONST_FLOAT(-6.343000), CHAR, state_MR_89; 85) + | left_transition(CONST_FLOAT(-6.004000), CHAR, state_D_90; 85) + # h; + + state_IR_86 = right_transition(CONST_FLOAT(-2.408000), state_IR_86, CHAR; 86) + | right_transition(CONST_FLOAT(-0.496000), state_MP_87, CHAR; 86) + | right_transition(CONST_FLOAT(-5.920000), state_ML_88, CHAR; 86) + | right_transition(CONST_FLOAT(-4.087000), state_MR_89, CHAR; 86) + | right_transition(CONST_FLOAT(-5.193000), state_D_90, CHAR; 86) + # h; + + // node [ MATP 50 ] + state_MP_87 = pair_transition(CONST_FLOAT(-12.114000), CHAR, state_IL_91, CHAR; 87) + | pair_transition(CONST_FLOAT(-12.054000), CHAR, state_IR_92, CHAR; 87) + | pair_transition(CONST_FLOAT(-0.078000), CHAR, state_MP_93, CHAR; 87) + | pair_transition(CONST_FLOAT(-8.063000), CHAR, state_ML_94, CHAR; 87) + | pair_transition(CONST_FLOAT(-11.110000), CHAR, state_MR_95, CHAR; 87) + | pair_transition(CONST_FLOAT(-4.379000), CHAR, state_D_96, CHAR; 87) + # h; + + state_ML_88 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_91; 88) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_92; 88) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_93; 88) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_94; 88) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_95; 88) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_96; 88) + # h; + + state_MR_89 = right_transition(CONST_FLOAT(-6.988000), state_IL_91, CHAR; 89) + | right_transition(CONST_FLOAT(-5.717000), state_IR_92, CHAR; 89) + | right_transition(CONST_FLOAT(-1.625000), state_MP_93, CHAR; 89) + | right_transition(CONST_FLOAT(-5.695000), state_ML_94, CHAR; 89) + | right_transition(CONST_FLOAT(-0.829000), state_MR_95, CHAR; 89) + | right_transition(CONST_FLOAT(-3.908000), state_D_96, CHAR; 89) + # h; + + state_D_90 = silent_transition(CONST_FLOAT(-9.420000), state_IL_91; 90) + | silent_transition(CONST_FLOAT(-8.118000), state_IR_92; 90) + | silent_transition(CONST_FLOAT(-3.915000), state_MP_93; 90) + | silent_transition(CONST_FLOAT(-4.597000), state_ML_94; 90) + | silent_transition(CONST_FLOAT(-4.615000), state_MR_95; 90) + | silent_transition(CONST_FLOAT(-0.240000), state_D_96; 90) + # h; + + state_IL_91 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_91; 91) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_92; 91) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_93; 91) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_94; 91) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_95; 91) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_96; 91) + # h; + + state_IR_92 = right_transition(CONST_FLOAT(-2.408000), state_IR_92, CHAR; 92) + | right_transition(CONST_FLOAT(-0.496000), state_MP_93, CHAR; 92) + | right_transition(CONST_FLOAT(-5.920000), state_ML_94, CHAR; 92) + | right_transition(CONST_FLOAT(-4.087000), state_MR_95, CHAR; 92) + | right_transition(CONST_FLOAT(-5.193000), state_D_96, CHAR; 92) + # h; + + // node [ MATP 51 ] + state_MP_93 = pair_transition(CONST_FLOAT(-11.148000), CHAR, state_IL_97, CHAR; 93) + | pair_transition(CONST_FLOAT(-11.355000), CHAR, state_IR_98, CHAR; 93) + | pair_transition(CONST_FLOAT(-0.030000), CHAR, state_ML_99, CHAR; 93) + | pair_transition(CONST_FLOAT(-5.670000), CHAR, state_D_100, CHAR; 93) + # h; + + state_ML_94 = left_transition(CONST_FLOAT(-4.084000), CHAR, state_IL_97; 94) + | left_transition(CONST_FLOAT(-4.267000), CHAR, state_IR_98; 94) + | left_transition(CONST_FLOAT(-0.389000), CHAR, state_ML_99; 94) + | left_transition(CONST_FLOAT(-2.996000), CHAR, state_D_100; 94) + # h; + + state_MR_95 = right_transition(CONST_FLOAT(-4.809000), state_IL_97, CHAR; 95) + | right_transition(CONST_FLOAT(-3.838000), state_IR_98, CHAR; 95) + | right_transition(CONST_FLOAT(-1.706000), state_ML_99, CHAR; 95) + | right_transition(CONST_FLOAT(-0.766000), state_D_100, CHAR; 95) + # h; + + state_D_96 = silent_transition(CONST_FLOAT(-7.445000), state_IL_97; 96) + | silent_transition(CONST_FLOAT(-7.126000), state_IR_98; 96) + | silent_transition(CONST_FLOAT(-0.812000), state_ML_99; 96) + | silent_transition(CONST_FLOAT(-1.260000), state_D_100; 96) + # h; + + state_IL_97 = left_transition(CONST_FLOAT(-1.686000), CHAR, state_IL_97; 97) + | left_transition(CONST_FLOAT(-2.369000), CHAR, state_IR_98; 97) + | left_transition(CONST_FLOAT(-1.117000), CHAR, state_ML_99; 97) + | left_transition(CONST_FLOAT(-4.855000), CHAR, state_D_100; 97) + # h; + + state_IR_98 = right_transition(CONST_FLOAT(-1.442000), state_IR_98, CHAR; 98) + | right_transition(CONST_FLOAT(-0.798000), state_ML_99, CHAR; 98) + | right_transition(CONST_FLOAT(-4.142000), state_D_100, CHAR; 98) + # h; + + // node [ MATL 52 ] + state_ML_99 = left_transition(CONST_FLOAT(-6.272000), CHAR, state_IL_101; 99) + | left_transition(CONST_FLOAT(-0.020000), CHAR, state_ML_102; 99) + | left_transition(CONST_FLOAT(-10.747000), CHAR, state_D_103; 99) + # h; + + state_D_100 = silent_transition(CONST_FLOAT(-9.039000), state_IL_101; 100) + | silent_transition(CONST_FLOAT(-0.168000), state_ML_102; 100) + | silent_transition(CONST_FLOAT(-3.210000), state_D_103; 100) + # h; + + state_IL_101 = left_transition(CONST_FLOAT(-2.042000), CHAR, state_IL_101; 101) + | left_transition(CONST_FLOAT(-0.474000), CHAR, state_ML_102; 101) + | left_transition(CONST_FLOAT(-4.742000), CHAR, state_D_103; 101) + # h; + + // node [ MATL 53 ] + state_ML_102 = left_transition(CONST_FLOAT(-12.147000), CHAR, state_IL_104; 102) + | left_transition(CONST_FLOAT(-0.002000), CHAR, state_ML_105; 102) + | left_transition(CONST_FLOAT(-9.386000), CHAR, state_D_106; 102) + # h; + + state_D_103 = silent_transition(CONST_FLOAT(-6.327000), state_IL_104; 103) + | silent_transition(CONST_FLOAT(-1.396000), state_ML_105; 103) + | silent_transition(CONST_FLOAT(-0.719000), state_D_106; 103) + # h; + + state_IL_104 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_104; 104) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_105; 104) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_106; 104) + # h; + + // node [ MATL 54 ] + state_ML_105 = left_transition(CONST_FLOAT(-12.146000), CHAR, state_IL_107; 105) + | left_transition(CONST_FLOAT(-0.002000), CHAR, state_ML_108; 105) + | left_transition(CONST_FLOAT(-9.678000), CHAR, state_D_109; 105) + # h; + + state_D_106 = silent_transition(CONST_FLOAT(-6.384000), state_IL_107; 106) + | silent_transition(CONST_FLOAT(-1.897000), state_ML_108; 106) + | silent_transition(CONST_FLOAT(-0.475000), state_D_109; 106) + # h; + + state_IL_107 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_107; 107) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_108; 107) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_109; 107) + # h; + + // node [ MATL 55 ] + state_ML_108 = left_transition(CONST_FLOAT(-5.589000), CHAR, state_IL_110; 108) + | left_transition(CONST_FLOAT(-0.037000), CHAR, state_ML_111; 108) + | left_transition(CONST_FLOAT(-7.884000), CHAR, state_D_112; 108) + # h; + + state_D_109 = silent_transition(CONST_FLOAT(-6.516000), state_IL_110; 109) + | silent_transition(CONST_FLOAT(-1.133000), state_ML_111; 109) + | silent_transition(CONST_FLOAT(-0.908000), state_D_112; 109) + # h; + + state_IL_110 = left_transition(CONST_FLOAT(-2.342000), CHAR, state_IL_110; 110) + | left_transition(CONST_FLOAT(-0.373000), CHAR, state_ML_111; 110) + | left_transition(CONST_FLOAT(-5.042000), CHAR, state_D_112; 110) + # h; + + // node [ MATL 56 ] + state_ML_111 = left_transition(CONST_FLOAT(-12.142000), CHAR, state_IL_113; 111) + | left_transition(CONST_FLOAT(-0.043000), CHAR, state_ML_114; 111) + | left_transition(CONST_FLOAT(-5.107000), CHAR, state_D_115; 111) + # h; + + state_D_112 = silent_transition(CONST_FLOAT(-6.866000), state_IL_113; 112) + | silent_transition(CONST_FLOAT(-2.379000), state_ML_114; 112) + | silent_transition(CONST_FLOAT(-0.323000), state_D_115; 112) + # h; + + state_IL_113 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_113; 113) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_114; 113) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_115; 113) + # h; + + // node [ MATL 57 ] + state_ML_114 = left_transition(CONST_FLOAT(-4.739000), CHAR, state_IL_116; 114) + | left_transition(CONST_FLOAT(-0.155000), CHAR, state_ML_117; 114) + | left_transition(CONST_FLOAT(-3.959000), CHAR, state_D_118; 114) + # h; + + state_D_115 = silent_transition(CONST_FLOAT(-3.742000), state_IL_116; 115) + | silent_transition(CONST_FLOAT(-3.655000), state_ML_117; 115) + | silent_transition(CONST_FLOAT(-0.241000), state_D_118; 115) + # h; + + state_IL_116 = left_transition(CONST_FLOAT(-1.931000), CHAR, state_IL_116; 116) + | left_transition(CONST_FLOAT(-0.475000), CHAR, state_ML_117; 116) + | left_transition(CONST_FLOAT(-5.762000), CHAR, state_D_118; 116) + # h; + + // node [ MATL 58 ] + state_ML_117 = left_transition(CONST_FLOAT(0.000000), CHAR, state_E_120; 117) + # h; + + state_D_118 = silent_transition(CONST_FLOAT(0.000000), state_E_120; 118) + # h; + + state_IL_119 = left_transition(CONST_FLOAT(-1.823000), CHAR, state_IL_119; 119) + | left_transition(CONST_FLOAT(-0.479000), CHAR, state_E_120; 119) + # h; + + // node [ END 59 ] + state_E_120 = nil(CONST_FLOAT(0.000000), EMPTY; 120) + # h; + + // node [ BEGL 12 ] + state_S_121 = silent_transition(CONST_FLOAT(0.000000), state_B_122; 121) + # h; + + // node [ BIF 13 ] + state_B_122 = bifurcation_transition(CONST_FLOAT(0.000000), CONST_FLOAT(0.000000), state_S_123, state_S_170; 122) + # h; + + // node [ BEGL 14 ] + state_S_123 = silent_transition(CONST_FLOAT(-0.004000), state_MP_124; 123) + | silent_transition(CONST_FLOAT(-10.203000), state_ML_125; 123) + | silent_transition(CONST_FLOAT(-9.611000), state_MR_126; 123) + | silent_transition(CONST_FLOAT(-10.251000), state_D_127; 123) + # h; + + // node [ MATP 15 ] + state_MP_124 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_128, CHAR; 124) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_129, CHAR; 124) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_130, CHAR; 124) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_131, CHAR; 124) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_132, CHAR; 124) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_133, CHAR; 124) + # h; + + state_ML_125 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_128; 125) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_129; 125) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_130; 125) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_131; 125) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_132; 125) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_133; 125) + # h; + + state_MR_126 = right_transition(CONST_FLOAT(-6.988000), state_IL_128, CHAR; 126) + | right_transition(CONST_FLOAT(-5.717000), state_IR_129, CHAR; 126) + | right_transition(CONST_FLOAT(-1.625000), state_MP_130, CHAR; 126) + | right_transition(CONST_FLOAT(-5.695000), state_ML_131, CHAR; 126) + | right_transition(CONST_FLOAT(-0.829000), state_MR_132, CHAR; 126) + | right_transition(CONST_FLOAT(-3.908000), state_D_133, CHAR; 126) + # h; + + state_D_127 = silent_transition(CONST_FLOAT(-9.049000), state_IL_128; 127) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_129; 127) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_130; 127) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_131; 127) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_132; 127) + | silent_transition(CONST_FLOAT(-0.319000), state_D_133; 127) + # h; + + state_IL_128 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_128; 128) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_129; 128) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_130; 128) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_131; 128) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_132; 128) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_133; 128) + # h; + + state_IR_129 = right_transition(CONST_FLOAT(-2.408000), state_IR_129, CHAR; 129) + | right_transition(CONST_FLOAT(-0.496000), state_MP_130, CHAR; 129) + | right_transition(CONST_FLOAT(-5.920000), state_ML_131, CHAR; 129) + | right_transition(CONST_FLOAT(-4.087000), state_MR_132, CHAR; 129) + | right_transition(CONST_FLOAT(-5.193000), state_D_133, CHAR; 129) + # h; + + // node [ MATP 16 ] + state_MP_130 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_134, CHAR; 130) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_135, CHAR; 130) + | pair_transition(CONST_FLOAT(-0.004000), CHAR, state_MP_136, CHAR; 130) + | pair_transition(CONST_FLOAT(-9.619000), CHAR, state_ML_137, CHAR; 130) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_138, CHAR; 130) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_139, CHAR; 130) + # h; + + state_ML_131 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_134; 131) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_135; 131) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_136; 131) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_137; 131) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_138; 131) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_139; 131) + # h; + + state_MR_132 = right_transition(CONST_FLOAT(-6.988000), state_IL_134, CHAR; 132) + | right_transition(CONST_FLOAT(-5.717000), state_IR_135, CHAR; 132) + | right_transition(CONST_FLOAT(-1.625000), state_MP_136, CHAR; 132) + | right_transition(CONST_FLOAT(-5.695000), state_ML_137, CHAR; 132) + | right_transition(CONST_FLOAT(-0.829000), state_MR_138, CHAR; 132) + | right_transition(CONST_FLOAT(-3.908000), state_D_139, CHAR; 132) + # h; + + state_D_133 = silent_transition(CONST_FLOAT(-9.049000), state_IL_134; 133) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_135; 133) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_136; 133) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_137; 133) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_138; 133) + | silent_transition(CONST_FLOAT(-0.319000), state_D_139; 133) + # h; + + state_IL_134 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_134; 134) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_135; 134) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_136; 134) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_137; 134) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_138; 134) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_139; 134) + # h; + + state_IR_135 = right_transition(CONST_FLOAT(-2.408000), state_IR_135, CHAR; 135) + | right_transition(CONST_FLOAT(-0.496000), state_MP_136, CHAR; 135) + | right_transition(CONST_FLOAT(-5.920000), state_ML_137, CHAR; 135) + | right_transition(CONST_FLOAT(-4.087000), state_MR_138, CHAR; 135) + | right_transition(CONST_FLOAT(-5.193000), state_D_139, CHAR; 135) + # h; + + // node [ MATP 17 ] + state_MP_136 = pair_transition(CONST_FLOAT(-12.116000), CHAR, state_IL_140, CHAR; 136) + | pair_transition(CONST_FLOAT(-12.056000), CHAR, state_IR_141, CHAR; 136) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_142, CHAR; 136) + | pair_transition(CONST_FLOAT(-10.832000), CHAR, state_ML_143, CHAR; 136) + | pair_transition(CONST_FLOAT(-11.112000), CHAR, state_MR_144, CHAR; 136) + | pair_transition(CONST_FLOAT(-11.507000), CHAR, state_D_145, CHAR; 136) + # h; + + state_ML_137 = left_transition(CONST_FLOAT(-6.358000), CHAR, state_IL_140; 137) + | left_transition(CONST_FLOAT(-6.704000), CHAR, state_IR_141; 137) + | left_transition(CONST_FLOAT(-1.164000), CHAR, state_MP_142; 137) + | left_transition(CONST_FLOAT(-1.113000), CHAR, state_ML_143; 137) + | left_transition(CONST_FLOAT(-6.554000), CHAR, state_MR_144; 137) + | left_transition(CONST_FLOAT(-4.083000), CHAR, state_D_145; 137) + # h; + + state_MR_138 = right_transition(CONST_FLOAT(-6.988000), state_IL_140, CHAR; 138) + | right_transition(CONST_FLOAT(-5.717000), state_IR_141, CHAR; 138) + | right_transition(CONST_FLOAT(-1.625000), state_MP_142, CHAR; 138) + | right_transition(CONST_FLOAT(-5.695000), state_ML_143, CHAR; 138) + | right_transition(CONST_FLOAT(-0.829000), state_MR_144, CHAR; 138) + | right_transition(CONST_FLOAT(-3.908000), state_D_145, CHAR; 138) + # h; + + state_D_139 = silent_transition(CONST_FLOAT(-9.049000), state_IL_140; 139) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_141; 139) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_142; 139) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_143; 139) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_144; 139) + | silent_transition(CONST_FLOAT(-0.319000), state_D_145; 139) + # h; + + state_IL_140 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_140; 140) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_141; 140) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_142; 140) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_143; 140) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_144; 140) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_145; 140) + # h; + + state_IR_141 = right_transition(CONST_FLOAT(-2.408000), state_IR_141, CHAR; 141) + | right_transition(CONST_FLOAT(-0.496000), state_MP_142, CHAR; 141) + | right_transition(CONST_FLOAT(-5.920000), state_ML_143, CHAR; 141) + | right_transition(CONST_FLOAT(-4.087000), state_MR_144, CHAR; 141) + | right_transition(CONST_FLOAT(-5.193000), state_D_145, CHAR; 141) + # h; + + // node [ MATP 18 ] + state_MP_142 = pair_transition(CONST_FLOAT(-11.233000), CHAR, state_IL_146, CHAR; 142) + | pair_transition(CONST_FLOAT(-11.440000), CHAR, state_IR_147, CHAR; 142) + | pair_transition(CONST_FLOAT(-0.005000), CHAR, state_ML_148, CHAR; 142) + | pair_transition(CONST_FLOAT(-8.416000), CHAR, state_D_149, CHAR; 142) + # h; + + state_ML_143 = left_transition(CONST_FLOAT(-3.758000), CHAR, state_IL_146; 143) + | left_transition(CONST_FLOAT(-3.940000), CHAR, state_IR_147; 143) + | left_transition(CONST_FLOAT(-0.507000), CHAR, state_ML_148; 143) + | left_transition(CONST_FLOAT(-2.670000), CHAR, state_D_149; 143) + # h; + + state_MR_144 = right_transition(CONST_FLOAT(-4.809000), state_IL_146, CHAR; 144) + | right_transition(CONST_FLOAT(-3.838000), state_IR_147, CHAR; 144) + | right_transition(CONST_FLOAT(-1.706000), state_ML_148, CHAR; 144) + | right_transition(CONST_FLOAT(-0.766000), state_D_149, CHAR; 144) + # h; + + state_D_145 = silent_transition(CONST_FLOAT(-4.568000), state_IL_146; 145) + | silent_transition(CONST_FLOAT(-4.250000), state_IR_147; 145) + | silent_transition(CONST_FLOAT(-2.265000), state_ML_148; 145) + | silent_transition(CONST_FLOAT(-0.520000), state_D_149; 145) + # h; + + state_IL_146 = left_transition(CONST_FLOAT(-1.686000), CHAR, state_IL_146; 146) + | left_transition(CONST_FLOAT(-2.369000), CHAR, state_IR_147; 146) + | left_transition(CONST_FLOAT(-1.117000), CHAR, state_ML_148; 146) + | left_transition(CONST_FLOAT(-4.855000), CHAR, state_D_149; 146) + # h; + + state_IR_147 = right_transition(CONST_FLOAT(-1.442000), state_IR_147, CHAR; 147) + | right_transition(CONST_FLOAT(-0.798000), state_ML_148, CHAR; 147) + | right_transition(CONST_FLOAT(-4.142000), state_D_149, CHAR; 147) + # h; + + // node [ MATL 19 ] + state_ML_148 = left_transition(CONST_FLOAT(-12.145000), CHAR, state_IL_150; 148) + | left_transition(CONST_FLOAT(-0.014000), CHAR, state_ML_151; 148) + | left_transition(CONST_FLOAT(-6.756000), CHAR, state_D_152; 148) + # h; + + state_D_149 = silent_transition(CONST_FLOAT(-6.563000), state_IL_150; 149) + | silent_transition(CONST_FLOAT(-2.076000), state_ML_151; 149) + | silent_transition(CONST_FLOAT(-0.411000), state_D_152; 149) + # h; + + state_IL_150 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_150; 150) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_151; 150) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_152; 150) + # h; + + // node [ MATL 20 ] + state_ML_151 = left_transition(CONST_FLOAT(-12.132000), CHAR, state_IL_153; 151) + | left_transition(CONST_FLOAT(-0.253000), CHAR, state_ML_154; 151) + | left_transition(CONST_FLOAT(-2.636000), CHAR, state_D_155; 151) + # h; + + state_D_152 = silent_transition(CONST_FLOAT(-7.642000), state_IL_153; 152) + | silent_transition(CONST_FLOAT(-3.155000), state_ML_154; 152) + | silent_transition(CONST_FLOAT(-0.180000), state_D_155; 152) + # h; + + state_IL_153 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_153; 153) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_154; 153) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_155; 153) + # h; + + // node [ MATL 21 ] + state_ML_154 = left_transition(CONST_FLOAT(-1.470000), CHAR, state_IL_156; 154) + | left_transition(CONST_FLOAT(-0.709000), CHAR, state_ML_157; 154) + | left_transition(CONST_FLOAT(-5.191000), CHAR, state_D_158; 154) + # h; + + state_D_155 = silent_transition(CONST_FLOAT(-11.053000), state_IL_156; 155) + | silent_transition(CONST_FLOAT(-0.280000), state_ML_157; 155) + | silent_transition(CONST_FLOAT(-2.506000), state_D_158; 155) + # h; + + state_IL_156 = left_transition(CONST_FLOAT(-1.948000), CHAR, state_IL_156; 156) + | left_transition(CONST_FLOAT(-0.495000), CHAR, state_ML_157; 156) + | left_transition(CONST_FLOAT(-5.006000), CHAR, state_D_158; 156) + # h; + + // node [ MATL 22 ] + state_ML_157 = left_transition(CONST_FLOAT(-12.057000), CHAR, state_IL_159; 157) + | left_transition(CONST_FLOAT(-0.001000), CHAR, state_ML_160; 157) + | left_transition(CONST_FLOAT(-10.711000), CHAR, state_D_161; 157) + # h; + + state_D_158 = silent_transition(CONST_FLOAT(-9.663000), state_IL_159; 158) + | silent_transition(CONST_FLOAT(-5.176000), state_ML_160; 158) + | silent_transition(CONST_FLOAT(-0.042000), state_D_161; 158) + # h; + + state_IL_159 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_159; 159) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_160; 159) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_161; 159) + # h; + + // node [ MATL 23 ] + state_ML_160 = left_transition(CONST_FLOAT(-12.057000), CHAR, state_IL_162; 160) + | left_transition(CONST_FLOAT(-0.235000), CHAR, state_ML_163; 160) + | left_transition(CONST_FLOAT(-2.736000), CHAR, state_D_164; 160) + # h; + + state_D_161 = silent_transition(CONST_FLOAT(-9.663000), state_IL_162; 161) + | silent_transition(CONST_FLOAT(-5.176000), state_ML_163; 161) + | silent_transition(CONST_FLOAT(-0.042000), state_D_164; 161) + # h; + + state_IL_162 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_162; 162) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_163; 162) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_164; 162) + # h; + + // node [ MATL 24 ] + state_ML_163 = left_transition(CONST_FLOAT(-0.840000), CHAR, state_IL_165; 163) + | left_transition(CONST_FLOAT(-1.186000), CHAR, state_ML_166; 163) + | left_transition(CONST_FLOAT(-9.087000), CHAR, state_D_167; 163) + # h; + + state_D_164 = silent_transition(CONST_FLOAT(-8.061000), state_IL_165; 164) + | silent_transition(CONST_FLOAT(-0.048000), state_ML_166; 164) + | silent_transition(CONST_FLOAT(-5.093000), state_D_167; 164) + # h; + + state_IL_165 = left_transition(CONST_FLOAT(-1.693000), CHAR, state_IL_165; 165) + | left_transition(CONST_FLOAT(-0.554000), CHAR, state_ML_166; 165) + | left_transition(CONST_FLOAT(-6.680000), CHAR, state_D_167; 165) + # h; + + // node [ MATL 25 ] + state_ML_166 = left_transition(CONST_FLOAT(0.000000), CHAR, state_E_169; 166) + # h; + + state_D_167 = silent_transition(CONST_FLOAT(0.000000), state_E_169; 167) + # h; + + state_IL_168 = left_transition(CONST_FLOAT(-1.823000), CHAR, state_IL_168; 168) + | left_transition(CONST_FLOAT(-0.479000), CHAR, state_E_169; 168) + # h; + + // node [ END 26 ] + state_E_169 = nil(CONST_FLOAT(0.000000), EMPTY; 169) + # h; + + // node [ BEGR 27 ] + state_S_170 = silent_transition(CONST_FLOAT(-12.148000), state_IL_171; 170) + | silent_transition(CONST_FLOAT(-0.015000), state_ML_172; 170) + | silent_transition(CONST_FLOAT(-6.633000), state_D_173; 170) + # h; + + state_IL_171 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_171; 171) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_172; 171) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_173; 171) + # h; + + // node [ MATL 28 ] + state_ML_172 = left_transition(CONST_FLOAT(-5.513000), CHAR, state_IL_174; 172) + | left_transition(CONST_FLOAT(-0.041000), CHAR, state_MP_175; 172) + | left_transition(CONST_FLOAT(-7.499000), CHAR, state_ML_176; 172) + | left_transition(CONST_FLOAT(-11.106000), CHAR, state_MR_177; 172) + | left_transition(CONST_FLOAT(-11.997000), CHAR, state_D_178; 172) + # h; + + state_D_173 = silent_transition(CONST_FLOAT(-5.885000), state_IL_174; 173) + | silent_transition(CONST_FLOAT(-0.367000), state_MP_175; 173) + | silent_transition(CONST_FLOAT(-5.147000), state_ML_176; 173) + | silent_transition(CONST_FLOAT(-3.521000), state_MR_177; 173) + | silent_transition(CONST_FLOAT(-3.434000), state_D_178; 173) + # h; + + state_IL_174 = left_transition(CONST_FLOAT(-3.373000), CHAR, state_IL_174; 174) + | left_transition(CONST_FLOAT(-0.233000), CHAR, state_MP_175; 174) + | left_transition(CONST_FLOAT(-5.052000), CHAR, state_ML_176; 174) + | left_transition(CONST_FLOAT(-6.884000), CHAR, state_MR_177; 174) + | left_transition(CONST_FLOAT(-6.158000), CHAR, state_D_178; 174) + # h; + + // node [ MATP 29 ] + state_MP_175 = pair_transition(CONST_FLOAT(-6.814000), CHAR, state_IL_179, CHAR; 175) + | pair_transition(CONST_FLOAT(-6.792000), CHAR, state_IR_180, CHAR; 175) + | pair_transition(CONST_FLOAT(-0.028000), CHAR, state_MP_181, CHAR; 175) + | pair_transition(CONST_FLOAT(-10.827000), CHAR, state_ML_182, CHAR; 175) + | pair_transition(CONST_FLOAT(-11.106000), CHAR, state_MR_183, CHAR; 175) + | pair_transition(CONST_FLOAT(-11.501000), CHAR, state_D_184, CHAR; 175) + # h; + + state_ML_176 = left_transition(CONST_FLOAT(-6.831000), CHAR, state_IL_179; 176) + | left_transition(CONST_FLOAT(-7.177000), CHAR, state_IR_180; 176) + | left_transition(CONST_FLOAT(-0.735000), CHAR, state_MP_181; 176) + | left_transition(CONST_FLOAT(-1.586000), CHAR, state_ML_182; 176) + | left_transition(CONST_FLOAT(-7.027000), CHAR, state_MR_183; 176) + | left_transition(CONST_FLOAT(-4.556000), CHAR, state_D_184; 176) + # h; + + state_MR_177 = right_transition(CONST_FLOAT(-6.988000), state_IL_179, CHAR; 177) + | right_transition(CONST_FLOAT(-5.717000), state_IR_180, CHAR; 177) + | right_transition(CONST_FLOAT(-1.625000), state_MP_181, CHAR; 177) + | right_transition(CONST_FLOAT(-5.695000), state_ML_182, CHAR; 177) + | right_transition(CONST_FLOAT(-0.829000), state_MR_183, CHAR; 177) + | right_transition(CONST_FLOAT(-3.908000), state_D_184, CHAR; 177) + # h; + + state_D_178 = silent_transition(CONST_FLOAT(-9.049000), state_IL_179; 178) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_180; 178) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_181; 178) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_182; 178) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_183; 178) + | silent_transition(CONST_FLOAT(-0.319000), state_D_184; 178) + # h; + + state_IL_179 = left_transition(CONST_FLOAT(-3.329000), CHAR, state_IL_179; 179) + | left_transition(CONST_FLOAT(-3.592000), CHAR, state_IR_180; 179) + | left_transition(CONST_FLOAT(-0.403000), CHAR, state_MP_181; 179) + | left_transition(CONST_FLOAT(-5.247000), CHAR, state_ML_182; 179) + | left_transition(CONST_FLOAT(-6.023000), CHAR, state_MR_183; 179) + | left_transition(CONST_FLOAT(-5.684000), CHAR, state_D_184; 179) + # h; + + state_IR_180 = right_transition(CONST_FLOAT(-2.914000), state_IR_180, CHAR; 180) + | right_transition(CONST_FLOAT(-0.331000), state_MP_181, CHAR; 180) + | right_transition(CONST_FLOAT(-6.425000), state_ML_182, CHAR; 180) + | right_transition(CONST_FLOAT(-4.593000), state_MR_183, CHAR; 180) + | right_transition(CONST_FLOAT(-5.699000), state_D_184, CHAR; 180) + # h; + + // node [ MATP 30 ] + state_MP_181 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_185, CHAR; 181) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_186, CHAR; 181) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_187, CHAR; 181) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_188, CHAR; 181) + | pair_transition(CONST_FLOAT(-11.113000), CHAR, state_MR_189, CHAR; 181) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_190, CHAR; 181) + # h; + + state_ML_182 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_185; 182) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_186; 182) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_187; 182) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_188; 182) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_189; 182) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_190; 182) + # h; + + state_MR_183 = right_transition(CONST_FLOAT(-6.988000), state_IL_185, CHAR; 183) + | right_transition(CONST_FLOAT(-5.717000), state_IR_186, CHAR; 183) + | right_transition(CONST_FLOAT(-1.625000), state_MP_187, CHAR; 183) + | right_transition(CONST_FLOAT(-5.695000), state_ML_188, CHAR; 183) + | right_transition(CONST_FLOAT(-0.829000), state_MR_189, CHAR; 183) + | right_transition(CONST_FLOAT(-3.908000), state_D_190, CHAR; 183) + # h; + + state_D_184 = silent_transition(CONST_FLOAT(-9.049000), state_IL_185; 184) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_186; 184) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_187; 184) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_188; 184) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_189; 184) + | silent_transition(CONST_FLOAT(-0.319000), state_D_190; 184) + # h; + + state_IL_185 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_185; 185) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_186; 185) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_187; 185) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_188; 185) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_189; 185) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_190; 185) + # h; + + state_IR_186 = right_transition(CONST_FLOAT(-2.408000), state_IR_186, CHAR; 186) + | right_transition(CONST_FLOAT(-0.496000), state_MP_187, CHAR; 186) + | right_transition(CONST_FLOAT(-5.920000), state_ML_188, CHAR; 186) + | right_transition(CONST_FLOAT(-4.087000), state_MR_189, CHAR; 186) + | right_transition(CONST_FLOAT(-5.193000), state_D_190, CHAR; 186) + # h; + + // node [ MATP 31 ] + state_MP_187 = pair_transition(CONST_FLOAT(-12.117000), CHAR, state_IL_191, CHAR; 187) + | pair_transition(CONST_FLOAT(-12.057000), CHAR, state_IR_192, CHAR; 187) + | pair_transition(CONST_FLOAT(-0.004000), CHAR, state_MP_193, CHAR; 187) + | pair_transition(CONST_FLOAT(-10.833000), CHAR, state_ML_194, CHAR; 187) + | pair_transition(CONST_FLOAT(-9.718000), CHAR, state_MR_195, CHAR; 187) + | pair_transition(CONST_FLOAT(-11.508000), CHAR, state_D_196, CHAR; 187) + # h; + + state_ML_188 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_191; 188) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_192; 188) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_193; 188) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_194; 188) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_195; 188) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_196; 188) + # h; + + state_MR_189 = right_transition(CONST_FLOAT(-6.988000), state_IL_191, CHAR; 189) + | right_transition(CONST_FLOAT(-5.717000), state_IR_192, CHAR; 189) + | right_transition(CONST_FLOAT(-1.625000), state_MP_193, CHAR; 189) + | right_transition(CONST_FLOAT(-5.695000), state_ML_194, CHAR; 189) + | right_transition(CONST_FLOAT(-0.829000), state_MR_195, CHAR; 189) + | right_transition(CONST_FLOAT(-3.908000), state_D_196, CHAR; 189) + # h; + + state_D_190 = silent_transition(CONST_FLOAT(-9.049000), state_IL_191; 190) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_192; 190) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_193; 190) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_194; 190) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_195; 190) + | silent_transition(CONST_FLOAT(-0.319000), state_D_196; 190) + # h; + + state_IL_191 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_191; 191) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_192; 191) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_193; 191) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_194; 191) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_195; 191) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_196; 191) + # h; + + state_IR_192 = right_transition(CONST_FLOAT(-2.408000), state_IR_192, CHAR; 192) + | right_transition(CONST_FLOAT(-0.496000), state_MP_193, CHAR; 192) + | right_transition(CONST_FLOAT(-5.920000), state_ML_194, CHAR; 192) + | right_transition(CONST_FLOAT(-4.087000), state_MR_195, CHAR; 192) + | right_transition(CONST_FLOAT(-5.193000), state_D_196, CHAR; 192) + # h; + + // node [ MATP 32 ] + state_MP_193 = pair_transition(CONST_FLOAT(-12.116000), CHAR, state_IL_197, CHAR; 193) + | pair_transition(CONST_FLOAT(-12.056000), CHAR, state_IR_198, CHAR; 193) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_MP_199, CHAR; 193) + | pair_transition(CONST_FLOAT(-10.832000), CHAR, state_ML_200, CHAR; 193) + | pair_transition(CONST_FLOAT(-9.881000), CHAR, state_MR_201, CHAR; 193) + | pair_transition(CONST_FLOAT(-11.507000), CHAR, state_D_202, CHAR; 193) + # h; + + state_ML_194 = left_transition(CONST_FLOAT(-6.250000), CHAR, state_IL_197; 194) + | left_transition(CONST_FLOAT(-6.596000), CHAR, state_IR_198; 194) + | left_transition(CONST_FLOAT(-1.310000), CHAR, state_MP_199; 194) + | left_transition(CONST_FLOAT(-1.005000), CHAR, state_ML_200; 194) + | left_transition(CONST_FLOAT(-6.446000), CHAR, state_MR_201; 194) + | left_transition(CONST_FLOAT(-3.975000), CHAR, state_D_202; 194) + # h; + + state_MR_195 = right_transition(CONST_FLOAT(-7.083000), state_IL_197, CHAR; 195) + | right_transition(CONST_FLOAT(-5.812000), state_IR_198, CHAR; 195) + | right_transition(CONST_FLOAT(-1.444000), state_MP_199, CHAR; 195) + | right_transition(CONST_FLOAT(-5.790000), state_ML_200, CHAR; 195) + | right_transition(CONST_FLOAT(-0.924000), state_MR_201, CHAR; 195) + | right_transition(CONST_FLOAT(-4.004000), state_D_202, CHAR; 195) + # h; + + state_D_196 = silent_transition(CONST_FLOAT(-9.049000), state_IL_197; 196) + | silent_transition(CONST_FLOAT(-7.747000), state_IR_198; 196) + | silent_transition(CONST_FLOAT(-3.544000), state_MP_199; 196) + | silent_transition(CONST_FLOAT(-4.226000), state_ML_200; 196) + | silent_transition(CONST_FLOAT(-4.244000), state_MR_201; 196) + | silent_transition(CONST_FLOAT(-0.319000), state_D_202; 196) + # h; + + state_IL_197 = left_transition(CONST_FLOAT(-2.579000), CHAR, state_IL_197; 197) + | left_transition(CONST_FLOAT(-2.842000), CHAR, state_IR_198; 197) + | left_transition(CONST_FLOAT(-0.760000), CHAR, state_MP_199; 197) + | left_transition(CONST_FLOAT(-4.497000), CHAR, state_ML_200; 197) + | left_transition(CONST_FLOAT(-5.274000), CHAR, state_MR_201; 197) + | left_transition(CONST_FLOAT(-4.934000), CHAR, state_D_202; 197) + # h; + + state_IR_198 = right_transition(CONST_FLOAT(-2.408000), state_IR_198, CHAR; 198) + | right_transition(CONST_FLOAT(-0.496000), state_MP_199, CHAR; 198) + | right_transition(CONST_FLOAT(-5.920000), state_ML_200, CHAR; 198) + | right_transition(CONST_FLOAT(-4.087000), state_MR_201, CHAR; 198) + | right_transition(CONST_FLOAT(-5.193000), state_D_202, CHAR; 198) + # h; + + // node [ MATP 33 ] + state_MP_199 = pair_transition(CONST_FLOAT(-11.232000), CHAR, state_IL_203, CHAR; 199) + | pair_transition(CONST_FLOAT(-11.439000), CHAR, state_IR_204, CHAR; 199) + | pair_transition(CONST_FLOAT(-0.003000), CHAR, state_ML_205, CHAR; 199) + | pair_transition(CONST_FLOAT(-9.853000), CHAR, state_D_206, CHAR; 199) + # h; + + state_ML_200 = left_transition(CONST_FLOAT(-3.758000), CHAR, state_IL_203; 200) + | left_transition(CONST_FLOAT(-3.940000), CHAR, state_IR_204; 200) + | left_transition(CONST_FLOAT(-0.507000), CHAR, state_ML_205; 200) + | left_transition(CONST_FLOAT(-2.670000), CHAR, state_D_206; 200) + # h; + + state_MR_201 = right_transition(CONST_FLOAT(-4.901000), state_IL_203, CHAR; 201) + | right_transition(CONST_FLOAT(-3.930000), state_IR_204, CHAR; 201) + | right_transition(CONST_FLOAT(-1.519000), state_ML_205, CHAR; 201) + | right_transition(CONST_FLOAT(-0.858000), state_D_206, CHAR; 201) + # h; + + state_D_202 = silent_transition(CONST_FLOAT(-4.568000), state_IL_203; 202) + | silent_transition(CONST_FLOAT(-4.250000), state_IR_204; 202) + | silent_transition(CONST_FLOAT(-2.265000), state_ML_205; 202) + | silent_transition(CONST_FLOAT(-0.520000), state_D_206; 202) + # h; + + state_IL_203 = left_transition(CONST_FLOAT(-1.686000), CHAR, state_IL_203; 203) + | left_transition(CONST_FLOAT(-2.369000), CHAR, state_IR_204; 203) + | left_transition(CONST_FLOAT(-1.117000), CHAR, state_ML_205; 203) + | left_transition(CONST_FLOAT(-4.855000), CHAR, state_D_206; 203) + # h; + + state_IR_204 = right_transition(CONST_FLOAT(-1.442000), state_IR_204, CHAR; 204) + | right_transition(CONST_FLOAT(-0.798000), state_ML_205, CHAR; 204) + | right_transition(CONST_FLOAT(-4.142000), state_D_206, CHAR; 204) + # h; + + // node [ MATL 34 ] + state_ML_205 = left_transition(CONST_FLOAT(-6.418000), CHAR, state_IL_207; 205) + | left_transition(CONST_FLOAT(-0.018000), CHAR, state_ML_208; 205) + | left_transition(CONST_FLOAT(-10.802000), CHAR, state_D_209; 205) + # h; + + state_D_206 = silent_transition(CONST_FLOAT(-6.174000), state_IL_207; 206) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_208; 206) + | silent_transition(CONST_FLOAT(-0.566000), state_D_209; 206) + # h; + + state_IL_207 = left_transition(CONST_FLOAT(-2.011000), CHAR, state_IL_207; 207) + | left_transition(CONST_FLOAT(-0.486000), CHAR, state_ML_208; 207) + | left_transition(CONST_FLOAT(-4.712000), CHAR, state_D_209; 207) + # h; + + // node [ MATL 35 ] + state_ML_208 = left_transition(CONST_FLOAT(-12.148000), CHAR, state_IL_210; 208) + | left_transition(CONST_FLOAT(-0.001000), CHAR, state_ML_211; 208) + | left_transition(CONST_FLOAT(-10.802000), CHAR, state_D_212; 208) + # h; + + state_D_209 = silent_transition(CONST_FLOAT(-6.174000), state_IL_210; 209) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_211; 209) + | silent_transition(CONST_FLOAT(-0.566000), state_D_212; 209) + # h; + + state_IL_210 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_210; 210) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_211; 210) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_212; 210) + # h; + + // node [ MATL 36 ] + state_ML_211 = left_transition(CONST_FLOAT(-12.148000), CHAR, state_IL_213; 211) + | left_transition(CONST_FLOAT(-0.001000), CHAR, state_ML_214; 211) + | left_transition(CONST_FLOAT(-10.802000), CHAR, state_D_215; 211) + # h; + + state_D_212 = silent_transition(CONST_FLOAT(-6.174000), state_IL_213; 212) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_214; 212) + | silent_transition(CONST_FLOAT(-0.566000), state_D_215; 212) + # h; + + state_IL_213 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_213; 213) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_214; 213) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_215; 213) + # h; + + // node [ MATL 37 ] + state_ML_214 = left_transition(CONST_FLOAT(-12.148000), CHAR, state_IL_216; 214) + | left_transition(CONST_FLOAT(-0.001000), CHAR, state_ML_217; 214) + | left_transition(CONST_FLOAT(-10.802000), CHAR, state_D_218; 214) + # h; + + state_D_215 = silent_transition(CONST_FLOAT(-6.174000), state_IL_216; 215) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_217; 215) + | silent_transition(CONST_FLOAT(-0.566000), state_D_218; 215) + # h; + + state_IL_216 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_216; 216) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_217; 216) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_218; 216) + # h; + + // node [ MATL 38 ] + state_ML_217 = left_transition(CONST_FLOAT(-12.148000), CHAR, state_IL_219; 217) + | left_transition(CONST_FLOAT(-0.001000), CHAR, state_ML_220; 217) + | left_transition(CONST_FLOAT(-10.802000), CHAR, state_D_221; 217) + # h; + + state_D_218 = silent_transition(CONST_FLOAT(-6.174000), state_IL_219; 218) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_220; 218) + | silent_transition(CONST_FLOAT(-0.566000), state_D_221; 218) + # h; + + state_IL_219 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_219; 219) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_220; 219) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_221; 219) + # h; + + // node [ MATL 39 ] + state_ML_220 = left_transition(CONST_FLOAT(-12.148000), CHAR, state_IL_222; 220) + | left_transition(CONST_FLOAT(-0.001000), CHAR, state_ML_223; 220) + | left_transition(CONST_FLOAT(-10.802000), CHAR, state_D_224; 220) + # h; + + state_D_221 = silent_transition(CONST_FLOAT(-6.174000), state_IL_222; 221) + | silent_transition(CONST_FLOAT(-1.687000), state_ML_223; 221) + | silent_transition(CONST_FLOAT(-0.566000), state_D_224; 221) + # h; + + state_IL_222 = left_transition(CONST_FLOAT(-1.442000), CHAR, state_IL_222; 222) + | left_transition(CONST_FLOAT(-0.798000), CHAR, state_ML_223; 222) + | left_transition(CONST_FLOAT(-4.142000), CHAR, state_D_224; 222) + # h; + + // node [ MATL 40 ] + state_ML_223 = left_transition(CONST_FLOAT(0.000000), CHAR, state_E_226; 223) + # h; + + state_D_224 = silent_transition(CONST_FLOAT(0.000000), state_E_226; 224) + # h; + + state_IL_225 = left_transition(CONST_FLOAT(-1.823000), CHAR, state_IL_225; 225) + | left_transition(CONST_FLOAT(-0.479000), CHAR, state_E_226; 225) + # h; + + // node [ END 41 ] + state_E_226 = nil(CONST_FLOAT(0.000000), EMPTY; 226) + # h; + +} + +instance count = gra_cm(alg_count); +instance enumcyk = gra_cm(alg_enum * alg_cyk); +instance cykenum = gra_cm(alg_cyk * alg_enum); +instance inside = gra_cm(alg_inside); + \ No newline at end of file diff --git a/testdata/grammar_outside/RFmini.gap b/testdata/grammar_outside/RFmini.gap new file mode 100644 index 000000000..5999c6b3f --- /dev/null +++ b/testdata/grammar_outside/RFmini.gap @@ -0,0 +1,155 @@ + +import "RFmini_data.hh" + +signature sig_cm(alphabet, answer) { + answer silent_transition(float, answer); + answer left_transition(float, alphabet, answer; int); + answer right_transition(float, answer, alphabet; int); + answer pair_transition(float, alphabet, answer, alphabet; int); + answer bifurcation_transition(float, float, answer, answer; int); + answer nil(float, void; int); + choice [answer] h([answer]); +} + + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_cyk implements sig_cm(alphabet=char, answer=float) { + float silent_transition(float tsc, float x) { + return tsc + x; + } + float left_transition(float tsc, alphabet a, float x; int pos) { + return tsc + getEmission(pos, a) + x; + } + float right_transition(float tsc, float x, alphabet a; int pos) { + return tsc + getEmission(pos, a) + x; + } + float pair_transition(float tsc, alphabet a, float x, alphabet b; int pos) { + return tsc + getPairEmission(pos, a, b) + x; + } + float bifurcation_transition(float tsc_left, float tsc_right, float left, float right; int pos) { + return tsc_left + tsc_right + left + right; + } + float nil(float tsc, void; int pos) { + return tsc; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_inside extends alg_cyk { + choice [float] h([float] candidates) { + return list(bitsum(candidates)); + } +} + +grammar gra_cm uses sig_cm(axiom = state_S_0) { + // node [ ROOT 0 ] + state_S_0 = silent_transition(CONST_FLOAT(-9.486000), state_IL_1) + | silent_transition(CONST_FLOAT(-19.955000), state_IR_2) + | silent_transition(CONST_FLOAT(-0.002000), state_B_3) + # h; + + state_IL_1 = left_transition(CONST_FLOAT(-0.610000), CHAR, state_IL_1; 1) + | left_transition(CONST_FLOAT(-4.491000), CHAR, state_IR_2; 1) + | left_transition(CONST_FLOAT(-1.736000), CHAR, state_B_3; 1) + # h; + + state_IR_2 = right_transition(CONST_FLOAT(-1.823000), state_IR_2, CHAR; 2) + | right_transition(CONST_FLOAT(-0.479000), state_B_3, CHAR; 2) + # h; + + // node [ BIF 1 ] + state_B_3 = bifurcation_transition(CONST_FLOAT(0.000000), CONST_FLOAT(0.000000), state_S_4, state_S_12; 3) + # h; + + // node [ BEGL 2 ] + state_S_4 = silent_transition(CONST_FLOAT(-0.006000), state_MP_5) + | silent_transition(CONST_FLOAT(-9.761000), state_ML_6) + | silent_transition(CONST_FLOAT(-9.168000), state_MR_7) + | silent_transition(CONST_FLOAT(-9.808000), state_D_8) + # h; + + // node [ MATP 3 ] + state_MP_5 = pair_transition(CONST_FLOAT(-9.486000), CHAR, state_IL_9, CHAR; 5) + | pair_transition(CONST_FLOAT(-0.002000), CHAR, state_E_11, CHAR; 5) + # h; + + state_ML_6 = left_transition(CONST_FLOAT(-1.000000), CHAR, state_IL_9; 6) + | left_transition(CONST_FLOAT(-1.000000), CHAR, state_E_11; 6) + # h; + + state_MR_7 = right_transition(CONST_FLOAT(-1.000000), state_IL_9, CHAR; 7) + | right_transition(CONST_FLOAT(-1.000000), state_E_11, CHAR; 7) + # h; + + state_D_8 = silent_transition(CONST_FLOAT(-1.000000), state_IL_9) + | silent_transition(CONST_FLOAT(-1.000000), state_E_11) + # h; + + state_IL_9 = left_transition(CONST_FLOAT(-0.544000), CHAR, state_IL_9; 9) + | left_transition(CONST_FLOAT(-1.670000), CHAR, state_E_11; 9) + # h; + + state_IR_10 = right_transition(CONST_FLOAT(-1.823000), state_IR_10, CHAR; 10) + | right_transition(CONST_FLOAT(-0.479000), state_E_11, CHAR; 10) + # h; + + // node [ END 4 ] + state_E_11 = nil(CONST_FLOAT(0.000000), EMPTY; 11) + # h; + + // node [ BEGR 5 ] + state_S_12 = silent_transition(CONST_FLOAT(-10.630000), state_IL_13) + | silent_transition(CONST_FLOAT(-0.003000), state_MP_14) + | silent_transition(CONST_FLOAT(-10.445000), state_ML_15) + | silent_transition(CONST_FLOAT(-10.657000), state_MR_16) + | silent_transition(CONST_FLOAT(-11.549000), state_D_17) + # h; + + state_IL_13 = left_transition(CONST_FLOAT(-2.408000), CHAR, state_IL_13; 13) + | left_transition(CONST_FLOAT(-0.496000), CHAR, state_MP_14; 13) + | left_transition(CONST_FLOAT(-4.087000), CHAR, state_ML_15; 13) + | left_transition(CONST_FLOAT(-5.920000), CHAR, state_MR_16; 13) + | left_transition(CONST_FLOAT(-5.193000), CHAR, state_D_17; 13) + # h; + + // node [ MATP 6 ] + state_MP_14 = pair_transition(CONST_FLOAT(-9.486000), CHAR, state_IL_18, CHAR; 14) + | pair_transition(CONST_FLOAT(-0.002000), CHAR, state_E_20, CHAR; 14) + # h; + + state_ML_15 = left_transition(CONST_FLOAT(-1.000000), CHAR, state_IL_18; 15) + | left_transition(CONST_FLOAT(-1.000000), CHAR, state_E_20; 15) + # h; + + state_MR_16 = right_transition(CONST_FLOAT(-1.000000), state_IL_18, CHAR; 16) + | right_transition(CONST_FLOAT(-1.000000), state_E_20, CHAR; 16) + # h; + + state_D_17 = silent_transition(CONST_FLOAT(-1.000000), state_IL_18) + | silent_transition(CONST_FLOAT(-1.000000), state_E_20) + # h; + + state_IL_18 = left_transition(CONST_FLOAT(-0.544000), CHAR, state_IL_18; 18) + | left_transition(CONST_FLOAT(-1.670000), CHAR, state_E_20; 18) + # h; + + state_IR_19 = right_transition(CONST_FLOAT(-1.823000), state_IR_19, CHAR; 19) + | right_transition(CONST_FLOAT(-0.479000), state_E_20, CHAR; 19) + # h; + + // node [ END 7 ] + state_E_20 = nil(CONST_FLOAT(0.000000), EMPTY; 20) + # h; + +} + +instance count = gra_cm(alg_count); +instance enum = gra_cm(alg_enum); +instance enumcyk = gra_cm(alg_enum * alg_cyk); +instance cykenum = gra_cm(alg_cyk * alg_enum); +instance inside = gra_cm(alg_inside); diff --git a/testdata/grammar_outside/acmsearch_RF00005.gap b/testdata/grammar_outside/acmsearch_RF00005.gap new file mode 100644 index 000000000..7c0514ee5 --- /dev/null +++ b/testdata/grammar_outside/acmsearch_RF00005.gap @@ -0,0 +1,244 @@ +/* +(multiple) covariance model for the following 2 consensus structure(s): + default: <<<<-<<<*-*-<<<<***---***---*>>>>*-<-<<<<*-******>>>>->**------------*---------*<<<-<<*-***-**--*>>>>->->>>>>>>-* (as tree: 'P 1 (P 2 (P 3 (P 4 (P 6 (P 7 (P 8 (O 9 (O 11 (P 13 (P 14 (P 15 (P 16 (O 17 (O 18 (O 19 (O 23 (O 24 (O 25 (O 29 (E 30)))))))) (E 31)) (E 32)) (E 33)) (O 34 (P 36 (P 38 (P 39 (P 40 (P 41 (O 42 (O 44 (O 45 (O 46 (O 47 (O 48 (O 49 (E 50)))))))) (E 51)) (E 52)) (E 53)) (E 55)) (O 56 (O 57 (O 70 (O 80 (P 81 (P 82 (P 83 (P 85 (P 86 (O 87 (O 89 (O 90 (O 91 (O 93 (O 94 (O 97 (E 98)))))))) (E 99)) (E 100)) (E 101)) (E 103)) (E 105))))))))))) (E 106)) (E 107)) (E 108)) (E 109)) (E 110)) (E 111)) (O 113 (E 114))') + varloop: <<<<-<<<*-*-<<<<***---****--*>>>>*-<-<<<<*-******>>>>->*--<<<<<-<****->-->>>>>-*<<<-<<*-***-**--*>>>>->->>>>>>>-* (as tree: 'P 1 (P 2 (P 3 (P 4 (P 6 (P 7 (P 8 (O 9 (O 11 (P 13 (P 14 (P 15 (P 16 (O 17 (O 18 (O 19 (O 23 (O 24 (O 25 (O 26 (O 29 (E 30))))))))) (E 31)) (E 32)) (E 33)) (O 34 (P 36 (P 38 (P 39 (P 40 (P 41 (O 42 (O 44 (O 45 (O 46 (O 47 (O 48 (O 49 (E 50)))))))) (E 51)) (E 52)) (E 53)) (E 55)) (O 56 (P 59 (P 60 (P 61 (P 62 (P 63 (P 65 (O 66 (O 67 (O 68 (O 69 (E 71))))) (E 74)) (E 75)) (E 76)) (E 77)) (E 78)) (O 80 (P 81 (P 82 (P 83 (P 85 (P 86 (O 87 (O 89 (O 90 (O 91 (O 93 (O 94 (O 97 (E 98)))))))) (E 99)) (E 100)) (E 101)) (E 103)) (E 105)))))))))) (E 106)) (E 107)) (E 108)) (E 109)) (E 110)) (E 111)) (O 113 (E 114))') +forming the unifying tree: + [Pl 1 [Pl 2 [Pl 3 [Pl 4 [Pl 6 [Pl 7 [Pl 8 [Ol 9 [Ol 11 [Pl 13 [Pl 14 [Pl 15 [Pl 16 [Ol 17 [Ol 18 [Ol 19 [Ol 23 [Ol 24 [Ol 25 [Ol 26 [Ol 29 [El 30]],Ol 29 [El 30]]]]]]]] [El 31]] [El 32]] [El 33]] [Ol 34 [Pl 36 [Pl 38 [Pl 39 [Pl 40 [Pl 41 [Ol 42 [Ol 44 [Ol 45 [Ol 46 [Ol 47 [Ol 48 [Ol 49 [El 50]]]]]]]] [El 51]] [El 52]] [El 53]] [El 55]] [Ol 56 [Pl 59 [Pl 60 [Pl 61 [Pl 62 [Pl 63 [Pl 65 [Ol 66 [Ol 67 [Ol 68 [Ol 69 [El 71]]]]] [El 74]] [El 75]] [El 76]] [El 77]] [El 78]] [Ol 80 [Pl 81 [Pl 82 [Pl 83 [Pl 85 [Pl 86 [Ol 87 [Ol 89 [Ol 90 [Ol 91 [Ol 93 [Ol 94 [Ol 97 [El 98]]]]]]]] [El 99]] [El 100]] [El 101]] [El 103]] [El 105]]],Ol 57 [Ol 70 [Ol 80 [Pl 81 [Pl 82 [Pl 83 [Pl 85 [Pl 86 [Ol 87 [Ol 89 [Ol 90 [Ol 91 [Ol 93 [Ol 94 [Ol 97 [El 98]]]]]]]] [El 99]] [El 100]] [El 101]] [El 103]] [El 105]]]]]]]]]]] [El 106]] [El 107]] [El 108]] [El 109]] [El 110]] [El 111]] [Ol 113 [El 114]]] +*/ + +import "acmsearch_RF00005_probabilities.hh" +import isntimes + +type Rope = extern +type ali = (Rope model, Rope seq, Rope cons) + +signature sig_cm(alphabet, answer) { + answer INS(alphabet, answer; int); + answer NIL(void; int); + answer MAT(alphabet, answer; int); + answer DEL(answer; int); + answer PK(alphabet, answer, alphabet, answer; int); + answer Lr(alphabet, answer, answer; int); + answer lR( answer, alphabet, answer; int); + answer bg( answer, answer; int); + choice [answer] h([answer]); +} +algebra alg_count auto count; + +algebra alg_enum auto enum; + +algebra alg_cyk implements sig_cm(alphabet = char, answer = float) { + float NIL(void; int pos) { + return getTransition_NIL(pos); + } + float INS(char a, float x; int pos) { + return x + getTransition_INS(pos) + getEmission_INS(pos, a); + } + float MAT(char a, float x; int pos) { + return x + getTransition_MAT(pos) + getEmission_MAT(pos, a); + } + float DEL(float x; int pos) { + return x + getTransition_DEL(pos); + } + float PK (char a, float x, char b, float y; int pos) { + return x + y + getTransition_PK(pos) + getEmission_PK(pos, a,b); + } + float Lr (char a, float x, float y; int pos) { + return x + y + getTransition_Lr(pos) + getEmission_Lr(pos, a); + } + float lR ( float x, char b, float y; int pos) { + return x + y + getTransition_lR(pos) + getEmission_lR(pos, b); + } + float bg ( float x, float y; int pos) { + return x + y + getTransition_bg(pos); + } + choice [float] h([float] i) { + return list(maximum(i)); + } +} +algebra alg_inside extends alg_cyk { + choice [float] h([float] candidates) { + return list(bitsum(candidates)); + } +} + +algebra alg_align implements sig_cm(alphabet = char, answer = ali) { + ali NIL(void; int pos) { + ali res; + return res; +} + ali INS(char a, ali x; int pos) { + ali res; + append(res.model, '-'); append(res.seq, a); append(res.cons, getConsensus_INS(pos)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + return res; + } + ali MAT(char a, ali x; int pos) { + ali res; + append(res.model, '*'); append(res.seq, a); append(res.cons, getConsensus_MAT(pos)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + return res; + } + ali DEL(ali x; int pos) { + ali res; + append(res.model, '*'); append(res.seq, '-'); append(res.cons, getConsensus_DEL(pos)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + return res; + } + ali PK (char a, ali x, char b, ali y; int pos) { + ali res; + append(res.model, '<'); append(res.seq, a ); append(res.cons, getConsensus_PK(pos,0)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + append(res.model, '>'); append(res.seq, b ); append(res.cons, getConsensus_PK(pos,1)); + append(res.model, y.model); append(res.seq, y.seq); append(res.cons, y.cons); + return res; + } + ali Lr (char a, ali x, ali y; int pos) { + ali res; + append(res.model, '<'); append(res.seq, a ); append(res.cons, getConsensus_Lr(pos,0)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + append(res.model, '>'); append(res.seq, '-'); append(res.cons, getConsensus_Lr(pos,1)); + append(res.model, y.model); append(res.seq, y.seq); append(res.cons, y.cons); + return res; + } + ali lR ( ali x, char b, ali y; int pos) { + ali res; + append(res.model, '<'); append(res.seq, '-'); append(res.cons, getConsensus_lR(pos,0)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + append(res.model, '>'); append(res.seq, b ); append(res.cons, getConsensus_lR(pos,1)); + append(res.model, y.model); append(res.seq, y.seq); append(res.cons, y.cons); + return res; + } + ali bg ( ali x, ali y; int pos) { + ali res; + append(res.model, '<'); append(res.seq, '-'); append(res.cons, getConsensus_bg(pos,0)); + append(res.model, x.model); append(res.seq, x.seq); append(res.cons, x.cons); + append(res.model, '>'); append(res.seq, '-'); append(res.cons, getConsensus_bg(pos,1)); + append(res.model, y.model); append(res.seq, y.seq); append(res.cons, y.cons); + return res; + } + choice [ali] h([ali] i) { + return i; + } +} + +grammar gra_build uses sig_cm(axiom = start) { + start = a_1 # h; + a_1 = INS(CHAR, a_1; 1) | PK(CHAR, a_2, CHAR, a_109; 1) | Lr(CHAR, a_2, a_109; 1) | lR(a_2, CHAR, a_109; 1) | bg(a_2, a_109; 1) # h; + a_2 = INS(CHAR, a_2; 2) | PK(CHAR, a_3, CHAR, a_108; 2) | Lr(CHAR, a_3, a_108; 2) | lR(a_3, CHAR, a_108; 2) | bg(a_3, a_108; 2) # h; + a_3 = INS(CHAR, a_3; 3) | PK(CHAR, a_4, CHAR, a_107; 3) | Lr(CHAR, a_4, a_107; 3) | lR(a_4, CHAR, a_107; 3) | bg(a_4, a_107; 3) # h; + a_4 = INS(CHAR, a_4; 4) | PK(CHAR, a_5, CHAR, a_106; 4) | Lr(CHAR, a_5, a_106; 4) | lR(a_5, CHAR, a_106; 4) | bg(a_5, a_106; 4) # h; + a_5 = INS(CHAR, a_5; 6) | PK(CHAR, a_6, CHAR, a_105; 6) | Lr(CHAR, a_6, a_105; 6) | lR(a_6, CHAR, a_105; 6) | bg(a_6, a_105; 6) # h; + a_6 = INS(CHAR, a_6; 7) | PK(CHAR, a_7, CHAR, a_104; 7) | Lr(CHAR, a_7, a_104; 7) | lR(a_7, CHAR, a_104; 7) | bg(a_7, a_104; 7) # h; + a_7 = INS(CHAR, a_7; 8) | PK(CHAR, a_8, CHAR, a_103; 8) | Lr(CHAR, a_8, a_103; 8) | lR(a_8, CHAR, a_103; 8) | bg(a_8, a_103; 8) # h; + a_8 = INS(CHAR, a_8; 9) | MAT(CHAR, a_9; 9) | DEL(a_9; 9) # h; + a_9 = INS(CHAR, a_9; 11) | MAT(CHAR, a_10; 11) | DEL(a_10; 11) # h; + a_10 = INS(CHAR, a_10; 13) | PK(CHAR, a_11, CHAR, a_28; 13) | Lr(CHAR, a_11, a_28; 13) | lR(a_11, CHAR, a_28; 13) | bg(a_11, a_28; 13) # h; + a_11 = INS(CHAR, a_11; 14) | PK(CHAR, a_12, CHAR, a_27; 14) | Lr(CHAR, a_12, a_27; 14) | lR(a_12, CHAR, a_27; 14) | bg(a_12, a_27; 14) # h; + a_12 = INS(CHAR, a_12; 15) | PK(CHAR, a_13, CHAR, a_26; 15) | Lr(CHAR, a_13, a_26; 15) | lR(a_13, CHAR, a_26; 15) | bg(a_13, a_26; 15) # h; + a_13 = INS(CHAR, a_13; 16) | PK(CHAR, a_14, CHAR, a_25; 16) | Lr(CHAR, a_14, a_25; 16) | lR(a_14, CHAR, a_25; 16) | bg(a_14, a_25; 16) # h; + a_14 = INS(CHAR, a_14; 17) | MAT(CHAR, a_15; 17) | DEL(a_15; 17) # h; + a_15 = INS(CHAR, a_15; 18) | MAT(CHAR, a_16; 18) | DEL(a_16; 18) # h; + a_16 = INS(CHAR, a_16; 19) | MAT(CHAR, a_17; 19) | DEL(a_17; 19) # h; + a_17 = INS(CHAR, a_17; 23) | MAT(CHAR, a_18; 23) | DEL(a_18; 23) # h; + a_18 = INS(CHAR, a_18; 24) | MAT(CHAR, a_19; 24) | DEL(a_19; 24) # h; + a_19 = INS(CHAR, a_19; 25) | MAT(CHAR, a_20; 25) | DEL(a_20; 25) | MAT(CHAR, a_23; 25) | DEL(a_23; 25) # h; + a_20 = INS(CHAR, a_20; 26) | MAT(CHAR, a_21; 26) | DEL(a_21; 26) # h; + a_21 = INS(CHAR, a_21; 29) | MAT(CHAR, a_22; 29) | DEL(a_22; 29) # h; + a_22 = INS(CHAR, a_22; 30) | NIL(EMPTY; 30) # h; + a_23 = INS(CHAR, a_23; 29) | MAT(CHAR, a_24; 29) | DEL(a_24; 29) # h; + a_24 = INS(CHAR, a_24; 30) | NIL(EMPTY; 30) # h; + a_25 = INS(CHAR, a_25; 31) | NIL(EMPTY; 31) # h; + a_26 = INS(CHAR, a_26; 32) | NIL(EMPTY; 32) # h; + a_27 = INS(CHAR, a_27; 33) | NIL(EMPTY; 33) # h; + a_28 = INS(CHAR, a_28; 34) | MAT(CHAR, a_29; 34) | DEL(a_29; 34) # h; + a_29 = INS(CHAR, a_29; 36) | PK(CHAR, a_30, CHAR, a_46; 36) | Lr(CHAR, a_30, a_46; 36) | lR(a_30, CHAR, a_46; 36) | bg(a_30, a_46; 36) # h; + a_30 = INS(CHAR, a_30; 38) | PK(CHAR, a_31, CHAR, a_45; 38) | Lr(CHAR, a_31, a_45; 38) | lR(a_31, CHAR, a_45; 38) | bg(a_31, a_45; 38) # h; + a_31 = INS(CHAR, a_31; 39) | PK(CHAR, a_32, CHAR, a_44; 39) | Lr(CHAR, a_32, a_44; 39) | lR(a_32, CHAR, a_44; 39) | bg(a_32, a_44; 39) # h; + a_32 = INS(CHAR, a_32; 40) | PK(CHAR, a_33, CHAR, a_43; 40) | Lr(CHAR, a_33, a_43; 40) | lR(a_33, CHAR, a_43; 40) | bg(a_33, a_43; 40) # h; + a_33 = INS(CHAR, a_33; 41) | PK(CHAR, a_34, CHAR, a_42; 41) | Lr(CHAR, a_34, a_42; 41) | lR(a_34, CHAR, a_42; 41) | bg(a_34, a_42; 41) # h; + a_34 = INS(CHAR, a_34; 42) | MAT(CHAR, a_35; 42) | DEL(a_35; 42) # h; + a_35 = INS(CHAR, a_35; 44) | MAT(CHAR, a_36; 44) | DEL(a_36; 44) # h; + a_36 = INS(CHAR, a_36; 45) | MAT(CHAR, a_37; 45) | DEL(a_37; 45) # h; + a_37 = INS(CHAR, a_37; 46) | MAT(CHAR, a_38; 46) | DEL(a_38; 46) # h; + a_38 = INS(CHAR, a_38; 47) | MAT(CHAR, a_39; 47) | DEL(a_39; 47) # h; + a_39 = INS(CHAR, a_39; 48) | MAT(CHAR, a_40; 48) | DEL(a_40; 48) # h; + a_40 = INS(CHAR, a_40; 49) | MAT(CHAR, a_41; 49) | DEL(a_41; 49) # h; + a_41 = INS(CHAR, a_41; 50) | NIL(EMPTY; 50) # h; + a_42 = INS(CHAR, a_42; 51) | NIL(EMPTY; 51) # h; + a_43 = INS(CHAR, a_43; 52) | NIL(EMPTY; 52) # h; + a_44 = INS(CHAR, a_44; 53) | NIL(EMPTY; 53) # h; + a_45 = INS(CHAR, a_45; 55) | NIL(EMPTY; 55) # h; + a_46 = INS(CHAR, a_46; 56) | MAT(CHAR, a_47; 56) | DEL(a_47; 56) | MAT(CHAR, a_82; 56) | DEL(a_82; 56) # h; + a_47 = INS(CHAR, a_47; 59) | PK(CHAR, a_48, CHAR, a_63; 59) | Lr(CHAR, a_48, a_63; 59) | lR(a_48, CHAR, a_63; 59) | bg(a_48, a_63; 59) # h; + a_48 = INS(CHAR, a_48; 60) | PK(CHAR, a_49, CHAR, a_62; 60) | Lr(CHAR, a_49, a_62; 60) | lR(a_49, CHAR, a_62; 60) | bg(a_49, a_62; 60) # h; + a_49 = INS(CHAR, a_49; 61) | PK(CHAR, a_50, CHAR, a_61; 61) | Lr(CHAR, a_50, a_61; 61) | lR(a_50, CHAR, a_61; 61) | bg(a_50, a_61; 61) # h; + a_50 = INS(CHAR, a_50; 62) | PK(CHAR, a_51, CHAR, a_60; 62) | Lr(CHAR, a_51, a_60; 62) | lR(a_51, CHAR, a_60; 62) | bg(a_51, a_60; 62) # h; + a_51 = INS(CHAR, a_51; 63) | PK(CHAR, a_52, CHAR, a_59; 63) | Lr(CHAR, a_52, a_59; 63) | lR(a_52, CHAR, a_59; 63) | bg(a_52, a_59; 63) # h; + a_52 = INS(CHAR, a_52; 65) | PK(CHAR, a_53, CHAR, a_58; 65) | Lr(CHAR, a_53, a_58; 65) | lR(a_53, CHAR, a_58; 65) | bg(a_53, a_58; 65) # h; + a_53 = INS(CHAR, a_53; 66) | MAT(CHAR, a_54; 66) | DEL(a_54; 66) # h; + a_54 = INS(CHAR, a_54; 67) | MAT(CHAR, a_55; 67) | DEL(a_55; 67) # h; + a_55 = INS(CHAR, a_55; 68) | MAT(CHAR, a_56; 68) | DEL(a_56; 68) # h; + a_56 = INS(CHAR, a_56; 69) | MAT(CHAR, a_57; 69) | DEL(a_57; 69) # h; + a_57 = INS(CHAR, a_57; 71) | NIL(EMPTY; 71) # h; + a_58 = INS(CHAR, a_58; 74) | NIL(EMPTY; 74) # h; + a_59 = INS(CHAR, a_59; 75) | NIL(EMPTY; 75) # h; + a_60 = INS(CHAR, a_60; 76) | NIL(EMPTY; 76) # h; + a_61 = INS(CHAR, a_61; 77) | NIL(EMPTY; 77) # h; + a_62 = INS(CHAR, a_62; 78) | NIL(EMPTY; 78) # h; + a_63 = INS(CHAR, a_63; 80) | MAT(CHAR, a_64; 80) | DEL(a_64; 80) # h; + a_64 = INS(CHAR, a_64; 81) | PK(CHAR, a_65, CHAR, a_81; 81) | Lr(CHAR, a_65, a_81; 81) | lR(a_65, CHAR, a_81; 81) | bg(a_65, a_81; 81) # h; + a_65 = INS(CHAR, a_65; 82) | PK(CHAR, a_66, CHAR, a_80; 82) | Lr(CHAR, a_66, a_80; 82) | lR(a_66, CHAR, a_80; 82) | bg(a_66, a_80; 82) # h; + a_66 = INS(CHAR, a_66; 83) | PK(CHAR, a_67, CHAR, a_79; 83) | Lr(CHAR, a_67, a_79; 83) | lR(a_67, CHAR, a_79; 83) | bg(a_67, a_79; 83) # h; + a_67 = INS(CHAR, a_67; 85) | PK(CHAR, a_68, CHAR, a_78; 85) | Lr(CHAR, a_68, a_78; 85) | lR(a_68, CHAR, a_78; 85) | bg(a_68, a_78; 85) # h; + a_68 = INS(CHAR, a_68; 86) | PK(CHAR, a_69, CHAR, a_77; 86) | Lr(CHAR, a_69, a_77; 86) | lR(a_69, CHAR, a_77; 86) | bg(a_69, a_77; 86) # h; + a_69 = INS(CHAR, a_69; 87) | MAT(CHAR, a_70; 87) | DEL(a_70; 87) # h; + a_70 = INS(CHAR, a_70; 89) | MAT(CHAR, a_71; 89) | DEL(a_71; 89) # h; + a_71 = INS(CHAR, a_71; 90) | MAT(CHAR, a_72; 90) | DEL(a_72; 90) # h; + a_72 = INS(CHAR, a_72; 91) | MAT(CHAR, a_73; 91) | DEL(a_73; 91) # h; + a_73 = INS(CHAR, a_73; 93) | MAT(CHAR, a_74; 93) | DEL(a_74; 93) # h; + a_74 = INS(CHAR, a_74; 94) | MAT(CHAR, a_75; 94) | DEL(a_75; 94) # h; + a_75 = INS(CHAR, a_75; 97) | MAT(CHAR, a_76; 97) | DEL(a_76; 97) # h; + a_76 = INS(CHAR, a_76; 98) | NIL(EMPTY; 98) # h; + a_77 = INS(CHAR, a_77; 99) | NIL(EMPTY; 99) # h; + a_78 = INS(CHAR, a_78; 100) | NIL(EMPTY; 100) # h; + a_79 = INS(CHAR, a_79; 101) | NIL(EMPTY; 101) # h; + a_80 = INS(CHAR, a_80; 103) | NIL(EMPTY; 103) # h; + a_81 = INS(CHAR, a_81; 105) | NIL(EMPTY; 105) # h; + a_82 = INS(CHAR, a_82; 57) | MAT(CHAR, a_83; 57) | DEL(a_83; 57) # h; + a_83 = INS(CHAR, a_83; 70) | MAT(CHAR, a_84; 70) | DEL(a_84; 70) # h; + a_84 = INS(CHAR, a_84; 80) | MAT(CHAR, a_85; 80) | DEL(a_85; 80) # h; + a_85 = INS(CHAR, a_85; 81) | PK(CHAR, a_86, CHAR, a_102; 81) | Lr(CHAR, a_86, a_102; 81) | lR(a_86, CHAR, a_102; 81) | bg(a_86, a_102; 81) # h; + a_86 = INS(CHAR, a_86; 82) | PK(CHAR, a_87, CHAR, a_101; 82) | Lr(CHAR, a_87, a_101; 82) | lR(a_87, CHAR, a_101; 82) | bg(a_87, a_101; 82) # h; + a_87 = INS(CHAR, a_87; 83) | PK(CHAR, a_88, CHAR, a_100; 83) | Lr(CHAR, a_88, a_100; 83) | lR(a_88, CHAR, a_100; 83) | bg(a_88, a_100; 83) # h; + a_88 = INS(CHAR, a_88; 85) | PK(CHAR, a_89, CHAR, a_99; 85) | Lr(CHAR, a_89, a_99; 85) | lR(a_89, CHAR, a_99; 85) | bg(a_89, a_99; 85) # h; + a_89 = INS(CHAR, a_89; 86) | PK(CHAR, a_90, CHAR, a_98; 86) | Lr(CHAR, a_90, a_98; 86) | lR(a_90, CHAR, a_98; 86) | bg(a_90, a_98; 86) # h; + a_90 = INS(CHAR, a_90; 87) | MAT(CHAR, a_91; 87) | DEL(a_91; 87) # h; + a_91 = INS(CHAR, a_91; 89) | MAT(CHAR, a_92; 89) | DEL(a_92; 89) # h; + a_92 = INS(CHAR, a_92; 90) | MAT(CHAR, a_93; 90) | DEL(a_93; 90) # h; + a_93 = INS(CHAR, a_93; 91) | MAT(CHAR, a_94; 91) | DEL(a_94; 91) # h; + a_94 = INS(CHAR, a_94; 93) | MAT(CHAR, a_95; 93) | DEL(a_95; 93) # h; + a_95 = INS(CHAR, a_95; 94) | MAT(CHAR, a_96; 94) | DEL(a_96; 94) # h; + a_96 = INS(CHAR, a_96; 97) | MAT(CHAR, a_97; 97) | DEL(a_97; 97) # h; + a_97 = INS(CHAR, a_97; 98) | NIL(EMPTY; 98) # h; + a_98 = INS(CHAR, a_98; 99) | NIL(EMPTY; 99) # h; + a_99 = INS(CHAR, a_99; 100) | NIL(EMPTY; 100) # h; + a_100 = INS(CHAR, a_100; 101) | NIL(EMPTY; 101) # h; + a_101 = INS(CHAR, a_101; 103) | NIL(EMPTY; 103) # h; + a_102 = INS(CHAR, a_102; 105) | NIL(EMPTY; 105) # h; + a_103 = INS(CHAR, a_103; 106) | NIL(EMPTY; 106) # h; + a_104 = INS(CHAR, a_104; 107) | NIL(EMPTY; 107) # h; + a_105 = INS(CHAR, a_105; 108) | NIL(EMPTY; 108) # h; + a_106 = INS(CHAR, a_106; 109) | NIL(EMPTY; 109) # h; + a_107 = INS(CHAR, a_107; 110) | NIL(EMPTY; 110) # h; + a_108 = INS(CHAR, a_108; 111) | NIL(EMPTY; 111) # h; + a_109 = INS(CHAR, a_109; 113) | MAT(CHAR, a_110; 113) | DEL(a_110; 113) # h; + a_110 = INS(CHAR, a_110; 114) | NIL(EMPTY; 114) # h; +} + +instance count = gra_build(alg_count); +instance train = gra_build(alg_enum); +instance cyk = gra_build(alg_cyk); +instance cykali = gra_build(alg_cyk * alg_align); +instance inside = gra_build(alg_inside); + diff --git a/testdata/grammar_outside/adpf.gap b/testdata/grammar_outside/adpf.gap new file mode 120000 index 000000000..72d0590a9 --- /dev/null +++ b/testdata/grammar_outside/adpf.gap @@ -0,0 +1 @@ +../grammar/adpf.gap \ No newline at end of file diff --git a/testdata/grammar_outside/adpf.new b/testdata/grammar_outside/adpf.new new file mode 120000 index 000000000..20e9e812a --- /dev/null +++ b/testdata/grammar_outside/adpf.new @@ -0,0 +1 @@ +../grammar/adpf.new \ No newline at end of file diff --git a/testdata/grammar_outside/adpf_hl.gap b/testdata/grammar_outside/adpf_hl.gap new file mode 120000 index 000000000..90e228caf --- /dev/null +++ b/testdata/grammar_outside/adpf_hl.gap @@ -0,0 +1 @@ +../grammar/adpf_hl.gap \ No newline at end of file diff --git a/testdata/grammar_outside/adpf_index.gap b/testdata/grammar_outside/adpf_index.gap new file mode 120000 index 000000000..fc3c81715 --- /dev/null +++ b/testdata/grammar_outside/adpf_index.gap @@ -0,0 +1 @@ +../grammar/adpf_index.gap \ No newline at end of file diff --git a/testdata/grammar_outside/adpf_multi.gap b/testdata/grammar_outside/adpf_multi.gap new file mode 120000 index 000000000..1f4d881ea --- /dev/null +++ b/testdata/grammar_outside/adpf_multi.gap @@ -0,0 +1 @@ +../grammar/adpf_multi.gap \ No newline at end of file diff --git a/testdata/grammar_outside/adpf_nonamb.gap b/testdata/grammar_outside/adpf_nonamb.gap new file mode 120000 index 000000000..9aea05e15 --- /dev/null +++ b/testdata/grammar_outside/adpf_nonamb.gap @@ -0,0 +1 @@ +../grammar/adpf_nonamb.gap \ No newline at end of file diff --git a/testdata/grammar_outside/alignments.gap b/testdata/grammar_outside/alignments.gap new file mode 100644 index 000000000..070c5fc40 --- /dev/null +++ b/testdata/grammar_outside/alignments.gap @@ -0,0 +1,114 @@ +input +type Rope = extern + +signature sig_alignments(alphabet, answer) { + answer Ins(, , answer); + answer Del(, , answer); + answer Ers(, , answer); + answer Sto(); + + answer Region(, answer, ); + answer Region_Pr(, answer, ); + answer Region_Pr_Pr(, answer, ); + + answer Insx(, , answer); + answer Delx(, , answer); + + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; +algebra alg_count auto count; + +algebra alg_similarity implements sig_alignments(alphabet=char, answer=int) { + int Ins(, , int x) { + return x -3; + } + int Del(, , int x) { + return x -2; + } + int Ers(, , int x) { + if (a == b) { + return x +1; + } else { + return x -1; + } + } + int Sto() { + return 0; + } + + int Region(, int x, ) { + return x; + } + int Region_Pr(, int x, ) { + return x; + } + int Region_Pr_Pr(, int x, ) { + return x; + } + + // this is slightly different form http://rna.informatik.uni-freiburg.de/Teaching/index.jsp?toolName=Gotoh# + // as there Ins + Insx is computed for first blank, we here score Ins for first blank and Insx for all following ones + int Insx(, , int x) { + return x -1; + } + int Delx(, , int x) { + return x -1; + } + + choice [int] h([int] candidates) { + return list(maximum(candidates)); + } +} + + +algebra alg_countmanual implements sig_alignments(alphabet=char, answer=int) { + int Ins(, , int x) { + return x; + } + int Del(, , int x) { + return x; + } + int Ers(, , int x) { + return x; + } + int Sto() { + return 1; + } + + int Region(, int x, ) { + return x; + } + int Region_Pr(, int x, ) { + return x; + } + int Region_Pr_Pr(, int x, ) { + return x; + } + + int Insx(, , int x) { + return x; + } + int Delx(, , int x) { + return x; + } + + choice [int] h([int] candidates) { + return list(sum(candidates)); + } +} + + +// pair-wise global alignment +grammar gra_needlemanwunsch uses sig_alignments(axiom=A) { + A = Ins(, , A) + | Del(, , A) + | Ers(, , A) + | Sto() + # h; +} + + +instance count = gra_needlemanwunsch(alg_count); +instance sim_enum = gra_needlemanwunsch(alg_similarity * alg_enum); diff --git a/testdata/grammar_outside/constAxiom.gap b/testdata/grammar_outside/constAxiom.gap new file mode 100644 index 000000000..f5ddcdbf3 --- /dev/null +++ b/testdata/grammar_outside/constAxiom.gap @@ -0,0 +1,35 @@ +signature sig_test(alphabet, answer) { + answer silent(char, answer); + answer consume_left(char, alphabet, answer); + answer consume_right(char, answer, alphabet); + answer dummy(answer); + answer nil(char, void); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +grammar gra_test uses sig_test(axiom = Sm1) { + // tabulated {S9} + Sm1 = dummy(S0) + # h; + + S0 = silent(CONST_CHAR('A'), S9) + | silent(CONST_CHAR('B'), S1) + # h; + + S9 = nil(CONST_CHAR('Z'), EMPTY) + # h; + + S1 = consume_left(CONST_CHAR('C'), CHAR, S1) + | consume_right(CONST_CHAR('D'), S1, CHAR) + | silent(CONST_CHAR('E'), S9) + # h; +} + +instance count = gra_test(alg_count); +instance enum = gra_test(alg_enum); + + \ No newline at end of file diff --git a/testdata/grammar_outside/elm_filter.gap b/testdata/grammar_outside/elm_filter.gap new file mode 120000 index 000000000..468e184e9 --- /dev/null +++ b/testdata/grammar_outside/elm_filter.gap @@ -0,0 +1 @@ +../grammar/elm_filter.gap \ No newline at end of file diff --git a/testdata/grammar_outside/elmamun.gap b/testdata/grammar_outside/elmamun.gap new file mode 100644 index 000000000..e515dd27e --- /dev/null +++ b/testdata/grammar_outside/elmamun.gap @@ -0,0 +1,202 @@ +/* +# Calif El Mamun's Caravan + + +Back in the old days, around the year 800, [Calif El Mamun of Bagdad](https://en.wikipedia.org/wiki/Al-Ma%27mun) planned to take his two sons on their first [hadj to Mekka](https://en.wikipedia.org/wiki/Hajj) ... +El Mamun called the camel dealer to negotiate about the required resources. + +After a long day of bargaining, the bill was written in the sand. + +(1 Calif, 2 sons, 3 baggage camels for each one, costing 4 tubes of oil, plus one riding camel for each one, costing 5 tubes of oil) +Computation was rather slow in those days ... + +There came the evening prayers, and there came the wind ... + +A mystery! Allah's hand had erased the parentheses, but left untouched the rest of the formula. + +The dealer was eager to redraw the parentheses: + +He even claimed that now the formula showed beautiful symmetry, pleasing the eye of God. +El Mamun was not good at figures, but he knew everything about camel dealers. +He felt suspicious. + +El Mamun called for the mathematician. [Al Chwarizmi](https://en.wikipedia.org/wiki/Muhammad_ibn_Musa_al-Khwarizmi), famous already in those days, studied the formula carefully, before he spoke. + +"Some possible answers are + + * `(1 + 2) * (3 * (4 + 5)) = 81` + * `1 + ((2 * (3 * 4)) + 5) = 30` + * `(1 + 2) * ((3 * 4) + 5) = 51` + +which are all equal in the eyes of God." +Apparently, Al Chwarizmi was a wise as well as a cautious man. + +El Mamun's contemplated this answer over night, and in the next morning, he ruled as follows: + + * The dealer should be buried in the sand, next to his formula `(1 + 2) * 3 * (4 + 5)`. + * Someone had to take care of the dealer's camels, and the Calif volunteered to collect them in his stables. + * Al Chwarizmi was awarded a research grant (51 tubes of oil) to study the optimal placement of parentheses, both from a buyer's or from a seller's perspective (depending on which side of the counter the Calif might find himself). + * Until this problem was solved, there should hold the provisional rule: "`*` takes priority over `+`", wherever parentheses were lacking in some formula. + +Some results from this episode can still be observed today! + + + * El Mamun became very, very rich, and his name gave rise to the word "mammon" in many modern languages. + * Studying hard, Al Chwarizmi became the father of algorithmics. He did not solve the problem, because [Dynamic Programming](https://en.wikipedia.org/wiki/Dynamic_programming) was only developed by [Richard Bellman](https://en.wikipedia.org/wiki/Richard_E._Bellman) in the 1950s. + * As a consequence of the question being unsettled, today `*` still takes priority over `+`. + +*/ + +type Rope = extern + +signature sig_elmamun(alphabet, answer) { + answer number(int); + answer add(answer, alphabet, answer); + answer mult(answer, alphabet, answer); + answer minus(answer, alphabet, answer); + answer heinz(answer, Rope, answer); + answer nil(void); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; +algebra alg_count auto count; + +algebra alg_pretty implements sig_elmamun(alphabet=char, answer=Rope) { + Rope number(int value) { + Rope res; + append(res, value); + return res; + } + Rope add(Rope left, char opSymbol, Rope right) { + Rope res; + append(res, '('); + append(res, left); + append(res, opSymbol); + append(res, right); + append(res, ')'); + return res; + } + Rope heinz(Rope left, Rope opSymbol, Rope right) { + Rope res; + append(res, '('); + append(res, left); + append(res, opSymbol); + append(res, right); + append(res, ')'); + return res; + } + Rope mult(Rope left, char opSymbol, Rope right) { + Rope res; + append(res, '('); + append(res, left); + append(res, opSymbol); + append(res, right); + append(res, ')'); + return res; + } + Rope minus(Rope left, char opSymbol, Rope right) { + Rope res; + append(res, '('); + append(res, left); + append(res, opSymbol); + append(res, right); + append(res, ')'); + return res; + } + Rope nil(void) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return candidates; + } +} + +algebra alg_buyer implements sig_elmamun(alphabet=char, answer=int) { + int number(int value) { + return value; + } + int add(int left, char opSymbol, int right) { + return left + right; + } + int heinz(int left, Rope opSymbol, int right) { + return left + right; + } + int mult(int left, char opSymbol, int right) { + return left * right; + } + int minus(int left, char opSymbol, int right) { + return left - right; + } + int nil(void) { + return 0; + } + choice [int] h([int] candidates) { + return list(minimum(candidates)); + } +} +algebra alg_seller extends alg_buyer { + choice [int] h([int] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_time implements sig_elmamun(alphabet=char, answer=int) { + int number(int value) { + return 0; + } + int add(int left, char opSymbol, int right) { + if (left > right) { + return left + 2; + } else { + return right + 2; + } + } + int heinz(int left, Rope opSymbol, int right) { + if (left > right) { + return left + 2; + } else { + return right + 2; + } + } + int mult(int left, char opSymbol, int right) { + if (left > right) { + return left + 5; + } else { + return right + 5; + } + } + int minus(int left, char opSymbol, int right) { + if (left > right) { + return left + 3; + } else { + return right + 3; + } + } + int nil(void) { + return 0; + } + choice [int] h([int] candidates) { + return list(minimum(candidates)); + } +} + +grammar gra_elmamun uses sig_elmamun(axiom = formula) { + formula = number(INT) + | add(formula, CHAR, formula) + | mult(formula, CHAR('*'), formula) + | heinz(formula, ROPE("manfred"), formula) + # h; +} + +instance pp = gra_elmamun(alg_pretty); +instance enum = gra_elmamun(alg_enum); +instance count = gra_elmamun(alg_count); +instance sellerpp = gra_elmamun(alg_seller * alg_pretty); +instance buyerpp = gra_elmamun(alg_buyer * alg_pretty); +instance ppbuyer = gra_elmamun(alg_pretty * alg_buyer); +instance timepp = gra_elmamun(alg_time * alg_pretty); + +// example input: +// "1+2*3*4+5" diff --git a/testdata/grammar_outside/elmamun_derivatives.gap b/testdata/grammar_outside/elmamun_derivatives.gap new file mode 100644 index 000000000..38ebc7ce8 --- /dev/null +++ b/testdata/grammar_outside/elmamun_derivatives.gap @@ -0,0 +1,73 @@ +type Rope = extern + +signature sig_elmamun(alphabet, answer) { + answer number(int); + answer add(answer, alphabet, answer); + answer mult(answer, alphabet, answer); + answer minus(answer, alphabet, answer); + answer nil(void); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; +algebra alg_count auto count; + +algebra alg_score implements sig_elmamun(alphabet=char, answer=float) { + float number(int value) { + return 1.0; + } + float add(float left, char opSymbol, float right) { + return left * right * exp(2); + } + float heinz(float left, Rope opSymbol, float right) { + return left * right; + } + float mult(float left, char opSymbol, float right) { + return left * right * exp(3); + } + float minus(float left, char opSymbol, float right) { + return left * right; + } + float nil(void) { + return 1.0; + } + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_hessians implements sig_elmamun(alphabet=char, answer=float) { + float number(int value) { + return 0.0; + } + float add(float left, char opSymbol, float right) { + return left + right + 2.0; + } + float heinz(float left, Rope opSymbol, float right) { + return left + right; + } + float mult(float left, char opSymbol, float right) { + return left + right + 3.0; + } + float minus(float left, char opSymbol, float right) { + return left + right; + } + float nil(void) { + return 0.0; + } + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + + +grammar gra_elmamun uses sig_elmamun(axiom = formula) { + formula = number(INT) + | add(formula, CHAR('+'), formula) + | mult(formula, CHAR('*'), formula) + | nil(EMPTY) + # h; +} + +instance firstD = gra_elmamun(alg_score); +instance bothD = gra_elmamun(alg_score * alg_hessians); diff --git a/testdata/grammar_outside/g3pl.gap b/testdata/grammar_outside/g3pl.gap new file mode 120000 index 000000000..f8dda6785 --- /dev/null +++ b/testdata/grammar_outside/g3pl.gap @@ -0,0 +1 @@ +../grammar/g3pl.gap \ No newline at end of file diff --git a/testdata/grammar_outside/helene.gap b/testdata/grammar_outside/helene.gap new file mode 120000 index 000000000..69eca1c62 --- /dev/null +++ b/testdata/grammar_outside/helene.gap @@ -0,0 +1 @@ +../grammar/helene.gap \ No newline at end of file diff --git a/testdata/grammar_outside/hmm_cpg.gap b/testdata/grammar_outside/hmm_cpg.gap new file mode 100644 index 000000000..0a6f520b3 --- /dev/null +++ b/testdata/grammar_outside/hmm_cpg.gap @@ -0,0 +1,302 @@ +type Rope = extern + +signature sig_cpg(alphabet, answer) { + answer transition_start_rich(float, answer, answer); + answer transition_start_poor(float, answer, answer); + answer transition_rich_rich(float, answer, answer); + answer transition_rich_poor(float, answer, answer); + answer transition_poor_rich(float, answer, answer); + answer transition_poor_poor(float, answer, answer); + + answer emission_rich_A(float, alphabet); + answer emission_rich_C(float, alphabet); + answer emission_rich_G(float, alphabet); + answer emission_rich_T(float, alphabet); + answer emission_poor_A(float, alphabet); + answer emission_poor_C(float, alphabet); + answer emission_poor_G(float, alphabet); + answer emission_poor_T(float, alphabet); + answer nil(void); + + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; +algebra alg_count auto count; + +algebra alg_viterbi implements sig_cpg(alphabet=char, answer=float) { + float transition_start_rich(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_start_poor(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_rich_poor(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_rich_rich(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_poor_poor(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_poor_rich(float transition, float emission, float x) { + return transition * emission * x; + } + + float emission_rich_A(float emission, char a) { + return emission; + } + float emission_rich_C(float emission, char a) { + return emission; + } + float emission_rich_G(float emission, char a) { + return emission; + } + float emission_rich_T(float emission, char a) { + return emission; + } + float emission_poor_A(float emission, char a) { + return emission; + } + float emission_poor_C(float emission, char a) { + return emission; + } + float emission_poor_G(float emission, char a) { + return emission; + } + float emission_poor_T(float emission, char a) { + return emission; + } + float nil(void) { + return 1.0; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} +algebra alg_fwd extends alg_viterbi { + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_states implements sig_cpg(alphabet=char, answer=Rope) { + Rope transition_start_rich(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_start_poor(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'L'); + append(res, x); + return res; + } + Rope transition_rich_poor(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'L'); + append(res, x); + return res; + } + Rope transition_rich_rich(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_poor_poor(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'L'); + append(res, x); + return res; + } + Rope transition_poor_rich(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + + Rope emission_rich_A(float emission, char a) { + Rope res; + return res; + } + Rope emission_rich_C(float emission, char a) { + Rope res; + return res; + } + Rope emission_rich_G(float emission, char a) { + Rope res; + return res; + } + Rope emission_rich_T(float emission, char a) { + Rope res; + return res; + } + Rope emission_poor_A(float emission, char a) { + Rope res; + return res; + } + Rope emission_poor_C(float emission, char a) { + Rope res; + return res; + } + Rope emission_poor_G(float emission, char a) { + Rope res; + return res; + } + Rope emission_poor_T(float emission, char a) { + Rope res; + return res; + } + + Rope nil(void) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return candidates; + } +} + +algebra alg_mult implements sig_cpg(alphabet=char, answer=Rope) { + Rope transition_start_rich(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_start_poor(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_rich_poor(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_rich_rich(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_poor_poor(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_poor_rich(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + + Rope emission_rich_A(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_rich_C(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_rich_G(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_rich_T(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_poor_A(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_poor_C(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_poor_G(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_poor_T(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope nil(void) { + Rope res; + append(res, 1.0); + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + + +grammar gra_cpg uses sig_cpg(axiom=start) { + start = transition_start_rich(CONST_FLOAT(0.5), rich_emission, rich) + | transition_start_poor(CONST_FLOAT(0.5), poor_emission, poor) + # h; + + rich = transition_rich_rich(CONST_FLOAT(0.63), rich_emission, rich) + | transition_rich_poor(CONST_FLOAT(0.37), poor_emission, poor) + | nil(EMPTY) + # h; + + poor = transition_poor_poor(CONST_FLOAT(0.63), poor_emission, poor) + | transition_poor_rich(CONST_FLOAT(0.37), rich_emission, rich) + | nil(EMPTY) + # h; + + rich_emission = emission_rich_A(CONST_FLOAT(0.13), CHAR('A')) + | emission_rich_C(CONST_FLOAT(0.37), CHAR('C')) + | emission_rich_G(CONST_FLOAT(0.37), CHAR('G')) + | emission_rich_T(CONST_FLOAT(0.13), CHAR('T')) + # h; + + poor_emission = emission_poor_A(CONST_FLOAT(0.37), CHAR('A')) + | emission_poor_C(CONST_FLOAT(0.13), CHAR('C')) + | emission_poor_G(CONST_FLOAT(0.13), CHAR('G')) + | emission_poor_T(CONST_FLOAT(0.37), CHAR('T')) + # h; +} + +instance enum = gra_cpg(alg_enum); +instance viterbistatesmult = gra_cpg(alg_viterbi * alg_states * alg_mult); +instance fwd = gra_cpg(alg_fwd); +instance multviterbistates = gra_cpg(alg_mult * alg_viterbi * alg_states); diff --git a/testdata/grammar_outside/hmm_sonneregen.gap b/testdata/grammar_outside/hmm_sonneregen.gap new file mode 100644 index 000000000..8821c9f8d --- /dev/null +++ b/testdata/grammar_outside/hmm_sonneregen.gap @@ -0,0 +1,251 @@ +type Rope = extern + +signature sig_weather(alphabet, answer) { + answer transition_start_hoch(float, answer, answer); + answer transition_start_tief(float, answer, answer); + answer transition_hoch_tief(float, answer, answer); + answer transition_hoch_hoch(float, answer, answer); + answer transition_tief_tief(float, answer, answer); + answer transition_tief_hoch(float, answer, answer); + + answer emission_hoch_sonne(float, alphabet); + answer emission_hoch_regen(float, alphabet); + answer emission_tief_sonne(float, alphabet); + answer emission_tief_regen(float, alphabet); + answer nil(void); + + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; +algebra alg_count auto count; + +algebra alg_viterbi implements sig_weather(alphabet=char, answer=float) { + float transition_start_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_start_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_hoch_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_hoch_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_tief_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_tief_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + + float emission_hoch_sonne(float emission, char a) { + return emission; + } + float emission_hoch_regen(float emission, char a) { + return emission; + } + float emission_tief_sonne(float emission, char a) { + return emission; + } + float emission_tief_regen(float emission, char a) { + return emission; + } + + float nil(void) { + return 1.0; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} +algebra alg_fwd extends alg_viterbi { + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_states implements sig_weather(alphabet=char, answer=Rope) { + Rope transition_start_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_start_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'T'); + append(res, x); + return res; + } + Rope transition_hoch_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'T'); + append(res, x); + return res; + } + Rope transition_hoch_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_tief_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'T'); + append(res, x); + return res; + } + Rope transition_tief_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + + Rope emission_hoch_sonne(float emission, char a) { + Rope res; + return res; + } + Rope emission_hoch_regen(float emission, char a) { + Rope res; + return res; + } + Rope emission_tief_sonne(float emission, char a) { + Rope res; + return res; + } + Rope emission_tief_regen(float emission, char a) { + Rope res; + return res; + } + + Rope nil(void) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +algebra alg_mult implements sig_weather(alphabet=char, answer=Rope) { + Rope transition_start_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_start_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_hoch_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_hoch_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_tief_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_tief_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + + Rope emission_hoch_sonne(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_hoch_regen(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_tief_sonne(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_tief_regen(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + + Rope nil(void) { + Rope res; + append(res, 1.0); + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + + +grammar gra_weather uses sig_weather(axiom=state_start) { + state_start = transition_start_hoch(CONST_FLOAT(0.5), emit_hoch, state_hoch) + | transition_start_tief(CONST_FLOAT(0.5), emit_tief, state_tief) + | nil(EMPTY) + # h; + + state_hoch = transition_hoch_tief(CONST_FLOAT(0.3), emit_tief, state_tief) + | transition_hoch_hoch(CONST_FLOAT(0.7), emit_hoch, state_hoch) + | nil(EMPTY) + # h; + + state_tief = transition_tief_tief(CONST_FLOAT(0.6), emit_tief, state_tief) + | transition_tief_hoch(CONST_FLOAT(0.4), emit_hoch, state_hoch) + | nil(EMPTY) + # h; + + + emit_hoch = emission_hoch_sonne(CONST_FLOAT(0.8), CHAR('S')) + | emission_hoch_regen(CONST_FLOAT(0.2), CHAR('R')) + # h; + + emit_tief = emission_tief_sonne(CONST_FLOAT(0.1), CHAR('S')) + | emission_tief_regen(CONST_FLOAT(0.9), CHAR('R')) + # h; +} + +instance enum = gra_weather(alg_enum); +instance viterbistatesmult = gra_weather(alg_viterbi * alg_states * alg_mult); +instance fwd = gra_weather(alg_fwd); +instance multviterbistates = gra_weather(alg_mult * alg_viterbi * alg_states); +instance count = gra_weather(alg_count); diff --git a/testdata/grammar_outside/hmm_sonneregen_properEnd.gap b/testdata/grammar_outside/hmm_sonneregen_properEnd.gap new file mode 100644 index 000000000..bda500272 --- /dev/null +++ b/testdata/grammar_outside/hmm_sonneregen_properEnd.gap @@ -0,0 +1,526 @@ +import negexpsum + +type Rope = extern + +signature sig_weather(alphabet, answer) { + answer transition_start_hoch(float, answer, answer); + answer transition_start_tief(float, answer, answer); + answer transition_start_ende(float, answer); + answer transition_hoch_tief(float, answer, answer); + answer transition_hoch_hoch(float, answer, answer); + answer transition_hoch_ende(float, answer); + answer transition_tief_tief(float, answer, answer); + answer transition_tief_hoch(float, answer, answer); + answer transition_tief_ende(float, answer); + + answer emission_hoch_sonne(float, alphabet); + answer emission_hoch_regen(float, alphabet); + answer emission_tief_sonne(float, alphabet); + answer emission_tief_regen(float, alphabet); + answer nil(void); + + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; +algebra alg_count auto count; + +algebra alg_viterbi implements sig_weather(alphabet=char, answer=float) { + float transition_start_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_start_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_start_ende(float transition, float x) { + return transition * x; + } + float transition_hoch_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_hoch_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_hoch_ende(float transition, float x) { + return transition * x; + } + float transition_tief_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_tief_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_tief_ende(float transition, float x) { + return transition * x; + } + + float emission_hoch_sonne(float emission, char a) { + return emission; + } + float emission_hoch_regen(float emission, char a) { + return emission; + } + float emission_tief_sonne(float emission, char a) { + return emission; + } + float emission_tief_regen(float emission, char a) { + return emission; + } + float nil(void) { + return 1.0; + } + + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_experiment implements sig_weather(alphabet=char, answer=float) { + float transition_start_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_start_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_start_ende(float transition, float x) { + return transition * x; + } + float transition_hoch_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_hoch_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_hoch_ende(float transition, float x) { + return transition * x; + } + float transition_tief_tief(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_tief_hoch(float transition, float emission, float x) { + return transition * emission * x; + } + float transition_tief_ende(float transition, float x) { + return transition * x; + } + + float emission_hoch_sonne(float emission, char a) { + return 1.0; + } + float emission_hoch_regen(float emission, char a) { + return 1.0; + } + float emission_tief_sonne(float emission, char a) { + return 1.0; + } + float emission_tief_regen(float emission, char a) { + return 1.0; + } + float nil(void) { + return 1.0; + } + + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_fwd extends alg_viterbi { + float normalize_derivative(float q, float pfunc) { + return q / pfunc; + } + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_hessians implements sig_weather(alphabet=char, answer=float) { + float transition_start_hoch(float transition, float emission, float x) { + return 0.48 * emission * x; + } + float transition_start_tief(float transition, float emission, float x) { + return 0.51 * emission * x; + } + float transition_start_ende(float transition, float x) { + return 0.01 * x; + } + float transition_hoch_tief(float transition, float emission, float x) { + return 0.20 * emission * x; + } + float transition_hoch_hoch(float transition, float emission, float x) { + return 0.70 * emission * x; + } + float transition_hoch_ende(float transition, float x) { + return 0.10 * x; + } + float transition_tief_tief(float transition, float emission, float x) { + return 0.50 * emission * x; + } + float transition_tief_hoch(float transition, float emission, float x) { + return 0.40 * emission * x; + } + float transition_tief_ende(float transition, float x) { + return 0.10 * x; + } + + float emission_hoch_sonne(float emission, char a) { + return 0.6; + } + float emission_hoch_regen(float emission, char a) { + return 0.4; + } + float emission_tief_sonne(float emission, char a) { + return 0.5; + } + float emission_tief_regen(float emission, char a) { + return 0.5; + } + float nil(void) { + return 1.0; + } + + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + + +algebra alg_fwd_log implements sig_weather(alphabet=char, answer=float) { + float transition_start_hoch(float transition, float emission, float x) { + return log(transition) + emission + x; + } + float transition_start_tief(float transition, float emission, float x) { + return log(transition) + emission + x; + } + float transition_start_ende(float transition, float x) { + return log(transition) + x; + } + float transition_hoch_tief(float transition, float emission, float x) { + return log(transition) + emission + x; + } + float transition_hoch_hoch(float transition, float emission, float x) { + return log(transition) + emission + x; + } + float transition_hoch_ende(float transition, float x) { + return log(transition) + x; + } + float transition_tief_tief(float transition, float emission, float x) { + return log(transition) + emission + x; + } + float transition_tief_hoch(float transition, float emission, float x) { + return log(transition) + emission + x; + } + float transition_tief_ende(float transition, float x) { + return log(transition) + x; + } + + float emission_hoch_sonne(float emission, char a) { + return log(emission); + } + float emission_hoch_regen(float emission, char a) { + return log(emission); + } + float emission_tief_sonne(float emission, char a) { + return log(emission); + } + float emission_tief_regen(float emission, char a) { + return log(emission); + } + float nil(void) { + return log(1.0); + } + + float normalize_derivative(float q, float pfunc) { + return exp(q - pfunc); + } + + choice [float] h([float] candidates) { + return list(expsum(candidates)); + } +} + +algebra alg_fwd_neglog implements sig_weather(alphabet=char, answer=float) { + float transition_start_hoch(float transition, float emission, float x) { + return log(1.0/transition) + emission + x; + } + float transition_start_tief(float transition, float emission, float x) { + return log(1.0/transition) + emission + x; + } + float transition_start_ende(float transition, float x) { + return log(1.0/transition) + x; + } + float transition_hoch_tief(float transition, float emission, float x) { + return log(1.0/transition) + emission + x; + } + float transition_hoch_hoch(float transition, float emission, float x) { + return log(1.0/transition) + emission + x; + } + float transition_hoch_ende(float transition, float x) { + return log(1.0/transition) + x; + } + float transition_tief_tief(float transition, float emission, float x) { + return log(1.0/transition) + emission + x; + } + float transition_tief_hoch(float transition, float emission, float x) { + return log(1.0/transition) + emission + x; + } + float transition_tief_ende(float transition, float x) { + return log(1.0/transition) + x; + } + + float emission_hoch_sonne(float emission, char a) { + return log(1.0/emission); + } + float emission_hoch_regen(float emission, char a) { + return log(1.0/emission); + } + float emission_tief_sonne(float emission, char a) { + return log(1.0/emission); + } + float emission_tief_regen(float emission, char a) { + return log(1.0/emission); + } + float nil(void) { + return log(1.0/1.0); + } + + float normalize_derivative(float q, float pfunc) { + return exp(pfunc - q); + } + + synoptic choice [float] h([float] candidates) { + return list(negexpsum(candidates)); + } +} + + +algebra alg_states implements sig_weather(alphabet=char, answer=Rope) { + Rope transition_start_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, '^'); + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_start_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, '^'); + append(res, 'T'); + append(res, x); + return res; + } + Rope transition_start_ende(float transition, Rope x) { + Rope res; + append(res, '^'); + append(res, x); + return res; + } + Rope transition_hoch_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'T'); + append(res, x); + return res; + } + Rope transition_hoch_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_hoch_ende(float transition, Rope x) { + Rope res; + append(res, x); + return res; + } + Rope transition_tief_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'T'); + append(res, x); + return res; + } + Rope transition_tief_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, 'H'); + append(res, x); + return res; + } + Rope transition_tief_ende(float transition, Rope x) { + Rope res; + append(res, x); + return res; + } + + Rope emission_hoch_sonne(float emission, char a) { + Rope res; + return res; + } + Rope emission_hoch_regen(float emission, char a) { + Rope res; + return res; + } + Rope emission_tief_sonne(float emission, char a) { + Rope res; + return res; + } + Rope emission_tief_regen(float emission, char a) { + Rope res; + return res; + } + Rope nil(void) { + Rope res; + append(res, '$'); + return res; + } + + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +algebra alg_mult implements sig_weather(alphabet=char, answer=Rope) { + Rope transition_start_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_start_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_start_ende(float transition, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_hoch_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_hoch_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_hoch_ende(float transition, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_tief_tief(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_tief_hoch(float transition, Rope emission, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, emission); + append(res, " * ", 3); + append(res, x); + return res; + } + Rope transition_tief_ende(float transition, Rope x) { + Rope res; + append(res, transition); + append(res, " * ", 3); + append(res, x); + return res; + } + + Rope emission_hoch_sonne(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_hoch_regen(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_tief_sonne(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope emission_tief_regen(float emission, char a) { + Rope res; + append(res, emission); + return res; + } + Rope nil(void) { + Rope res; + append(res, 1.0); + return res; + } + + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + + +grammar gra_weather uses sig_weather(axiom=start) { + start = transition_start_hoch(CONST_FLOAT(0.49), hoch_emission, hoch) + | transition_start_tief(CONST_FLOAT(0.49), tief_emission, tief) + | transition_start_ende(CONST_FLOAT(0.02), ende) + # h; + + hoch = transition_hoch_tief(CONST_FLOAT(0.29), tief_emission, tief) + | transition_hoch_hoch(CONST_FLOAT(0.69), hoch_emission, hoch) + | transition_hoch_ende(CONST_FLOAT(0.02), ende) + # h; + + tief = transition_tief_tief(CONST_FLOAT(0.59), tief_emission, tief) + | transition_tief_hoch(CONST_FLOAT(0.39), hoch_emission, hoch) + | transition_tief_ende(CONST_FLOAT(0.02), ende) + # h; + + ende = nil(EMPTY) + # h; + + hoch_emission = emission_hoch_sonne(CONST_FLOAT(0.8), CHAR('S')) + | emission_hoch_regen(CONST_FLOAT(0.2), CHAR('R')) + # h; + + tief_emission = emission_tief_sonne(CONST_FLOAT(0.1), CHAR('S')) + | emission_tief_regen(CONST_FLOAT(0.9), CHAR('R')) + # h; +} + +instance enum = gra_weather(alg_enum); +instance viterbistatesmult = gra_weather(alg_viterbi * alg_states * alg_mult); +instance fwd = gra_weather(alg_fwd); +instance fwd_log = gra_weather(alg_fwd_log); +instance fwd_neglog = gra_weather(alg_fwd_neglog); +instance multviterbistates = gra_weather(alg_mult * alg_viterbi * alg_states); + +instance bothD = gra_weather(alg_fwd * alg_hessians); +instance bothD_log = gra_weather(alg_fwd_log * alg_hessians); +instance bothD_neglog = gra_weather(alg_fwd_neglog * alg_hessians); diff --git a/testdata/grammar_outside/loco3stem.gap b/testdata/grammar_outside/loco3stem.gap new file mode 120000 index 000000000..405777244 --- /dev/null +++ b/testdata/grammar_outside/loco3stem.gap @@ -0,0 +1 @@ +../grammar/loco3stem.gap \ No newline at end of file diff --git a/testdata/grammar_outside/mini1.gap b/testdata/grammar_outside/mini1.gap new file mode 100644 index 000000000..2a9911bd7 --- /dev/null +++ b/testdata/grammar_outside/mini1.gap @@ -0,0 +1,61 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer ssadd(Subsequence, answer); + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int ssadd(Subsequence r, int x) { + return x; + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string ssadd(Subsequence r, string e) { + return e; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + sadd(BASE, struct) | + ssadd(REGION, struct) + # h; + + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/mini_bl.gap b/testdata/grammar_outside/mini_bl.gap new file mode 100644 index 000000000..d6f9b4640 --- /dev/null +++ b/testdata/grammar_outside/mini_bl.gap @@ -0,0 +1,56 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string nil(Subsequence loc) { + string r; + return r; + } + + choice [string] h([string] i) { + return i; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION with maxsize(30), struct, REGION with maxsize(30), BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/mini_complexIL.gap b/testdata/grammar_outside/mini_complexIL.gap new file mode 100644 index 000000000..85de279c9 --- /dev/null +++ b/testdata/grammar_outside/mini_complexIL.gap @@ -0,0 +1,60 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer comp(Subsequence, Subsequence, Subsequence, Subsequence, answer, Subsequence, answer); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int comp(Subsequence a, Subsequence lr, Subsequence lr2, Subsequence lr3, int x, Subsequence b, int y) { + return x+y; + } +} + +//algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { +// string nil(Subsequence loc) { +// string r; +// return r; +// } +// +// choice [string] h([string] i) { +// return i; +// } +// +// string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { +// string res; +// append(res, '('); +// append(res, '.', size(lregion)); +// append(res, e); +// append(res, '.', size(rregion)); +// append(res, ')'); +// return res; +// } +//} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION, comp(REGION, BASE, BASE, REGION, struct, BASE, struct), REGION, BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/mini_largeIL.gap b/testdata/grammar_outside/mini_largeIL.gap new file mode 100644 index 000000000..fa0be0279 --- /dev/null +++ b/testdata/grammar_outside/mini_largeIL.gap @@ -0,0 +1,56 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, Subsequence, answer, Subsequence, Subsequence, Subsequence); // an internal loop with a closing base-pair +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence a, Subsequence lr, int x, Subsequence rr, Subsequence b, Subsequence rb) { + return x + il_energy(lr, rr); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string nil(Subsequence loc) { + string r; + return r; + } + + choice [string] h([string] i) { + return i; + } + + string il(Subsequence lb,Subsequence a, Subsequence lregion,string e,Subsequence rregion,Subsequence b,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION with maxsize(30), REGION, struct, REGION, REGION with maxsize(30), BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/mini_twoLevelIL.gap b/testdata/grammar_outside/mini_twoLevelIL.gap new file mode 100644 index 000000000..521f668d7 --- /dev/null +++ b/testdata/grammar_outside/mini_twoLevelIL.gap @@ -0,0 +1,39 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer comp(Subsequence, Subsequence, Subsequence, answer, Subsequence, answer, Subsequence); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence lr, Subsequence r, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int comp(Subsequence a, Subsequence lr, Subsequence lr2, int x, Subsequence b, int y, Subsequence lr3) { + return x+y; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION, BASE, comp(BASE, BASE, REGION, struct, BASE, struct, REGION), REGION, BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle.gap b/testdata/grammar_outside/nodangle.gap new file mode 100644 index 000000000..c1fa7c6a0 --- /dev/null +++ b/testdata/grammar_outside/nodangle.gap @@ -0,0 +1,236 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(dangle, struct) | + nil(LOC) # h; + + dangle = drem(LOC, strong, LOC) # h; + + strong = weak # h; + + weak = stack | + hairpin | + leftB | + rightB | + iloop | + multiloop # h; + + stack = sr(BASE, weak, BASE) with basepairing # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = bl(BASE, REGION with maxsize(30), strong, BASE) with basepairing # h; + rightB = br(BASE, strong, REGION with maxsize(30), BASE) with basepairing # h; + iloop = il(BASE, REGION with maxsize(30), strong, REGION with maxsize(30), BASE) with basepairing # h; + multiloop = ml(BASE, ml_comps, BASE) with basepairing # h; + + ml_comps = sadd(BASE, ml_comps) | + cadd(incl(dangle), ml_comps1) # h; + + ml_comps1 = sadd(BASE, ml_comps1) | + cadd(incl(dangle), ml_comps1) | + incl(dangle) | + addss(incl(dangle), REGION) # h; +} + +instance mfe = gra_nodangle(alg_mfe); +instance pfunc = gra_nodangle(alg_pfunc); +instance count = gra_nodangle(alg_count); +instance enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_caddinclissue.gap b/testdata/grammar_outside/nodangle_caddinclissue.gap new file mode 100644 index 000000000..2504e63c1 --- /dev/null +++ b/testdata/grammar_outside/nodangle_caddinclissue.gap @@ -0,0 +1,169 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE with unpaired, struct) | + cadd(incl(dangle), struct) | + nil(LOC) # h; + + dangle = drem(LOC, hairpin, LOC) # h; + + hairpin = hl(BASE, REGION with minsize(3) with unpaired, BASE) with basepair # h; +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_emptyanswerissue.gap b/testdata/grammar_outside/nodangle_emptyanswerissue.gap new file mode 100644 index 000000000..27064ec58 --- /dev/null +++ b/testdata/grammar_outside/nodangle_emptyanswerissue.gap @@ -0,0 +1,217 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(weak, struct) | + nil(LOC) # h; + + + weak = hl(BASE, REGION with minsize(3), BASE) with basepairing | + bl(BASE, REGION with maxsize(30), weak, BASE) with basepairing | + il(BASE, REGION with maxsize(30), weak, REGION with maxsize(30), BASE) with basepairing + # h; + +} + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_filterempty.gap b/testdata/grammar_outside/nodangle_filterempty.gap new file mode 100644 index 000000000..4b961e225 --- /dev/null +++ b/testdata/grammar_outside/nodangle_filterempty.gap @@ -0,0 +1,217 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(weak, struct) | + nil(LOC) # h; + + weak = hairpin | + leftB + # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = sr(BASE, bl(BASE, REGION with maxsize(30), weak, BASE) with basepairing, BASE with basepairing) # h; +} + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_issue.gap b/testdata/grammar_outside/nodangle_issue.gap new file mode 100644 index 000000000..0a6f1542e --- /dev/null +++ b/testdata/grammar_outside/nodangle_issue.gap @@ -0,0 +1,167 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + cadd(hairpin, struct) + # h; + + hairpin = hl(BASE, REGION with minsize(3) with maxsize(30), BASE) with basepairing # h; +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_issue2.gap b/testdata/grammar_outside/nodangle_issue2.gap new file mode 100644 index 000000000..b2b3ac86a --- /dev/null +++ b/testdata/grammar_outside/nodangle_issue2.gap @@ -0,0 +1,170 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + incl(hairpin) | + sadd(BASE, struct) | + cadd(struct, sadd(BASE, struct)) + # h; + //dangle = hairpin # h; + + hairpin = hl(BASE, REGION with minsize(3) with maxsize(30), BASE) with basepairing # h; +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_mlIssue.gap b/testdata/grammar_outside/nodangle_mlIssue.gap new file mode 100644 index 000000000..271d7e27e --- /dev/null +++ b/testdata/grammar_outside/nodangle_mlIssue.gap @@ -0,0 +1,169 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + cadd(multiloop, struct) + # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + multiloop = ml(BASE, hairpin, BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_noNTrhs_issue.gap b/testdata/grammar_outside/nodangle_noNTrhs_issue.gap new file mode 100644 index 000000000..b9676bf3c --- /dev/null +++ b/testdata/grammar_outside/nodangle_noNTrhs_issue.gap @@ -0,0 +1,167 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = start) { + start = incl(struct) # h; + struct = sadd(BASE with unpaired, struct) | + nil(LOC) # h; + + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_tooManyLoops.gap b/testdata/grammar_outside/nodangle_tooManyLoops.gap new file mode 100644 index 000000000..da00de210 --- /dev/null +++ b/testdata/grammar_outside/nodangle_tooManyLoops.gap @@ -0,0 +1,212 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(hairpin, struct) | + nil(LOC) # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); +instance pfunc = gra_nodangle(alg_pfunc); +instance count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_withoverlay.gap b/testdata/grammar_outside/nodangle_withoverlay.gap new file mode 100644 index 000000000..c38ad4539 --- /dev/null +++ b/testdata/grammar_outside/nodangle_withoverlay.gap @@ -0,0 +1,237 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(dangle , struct) | + nil(LOC) # h; + + dangle = drem(LOC, strong, LOC) # h; + + strong = weak # h; + + weak = stack | + hairpin | + leftB | + rightB | + iloop | + multiloop # h; + + stack = sr(BASE, weak, BASE) with basepairing # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = bl(BASE, REGION with maxsize(30), strong, BASE) with basepairing # h; + rightB = br(BASE, strong, REGION with maxsize(30), BASE) with basepairing # h; + iloop = il(BASE, REGION with maxsize(30), strong, REGION with maxsize(30), BASE) with basepairing with_overlay iloopSumMax(30) # h; + multiloop = ml(BASE, ml_comps, BASE) with basepairing # h; + + ml_comps = sadd(BASE, ml_comps) | + cadd(incl(dangle), ml_comps1) # h; + + ml_comps1 = sadd(BASE, ml_comps1) | + cadd(incl(dangle), ml_comps1) | + incl(dangle) | + addss(incl(dangle), REGION) # h; +} + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nonzero_constsize.gap b/testdata/grammar_outside/nonzero_constsize.gap new file mode 100644 index 000000000..e02eb62db --- /dev/null +++ b/testdata/grammar_outside/nonzero_constsize.gap @@ -0,0 +1,51 @@ +signature sig_cm(alphabet, answer) { + answer silent_transition(float, answer; int); + answer left_transition(float, alphabet, answer; int); + answer right_transition(float, answer, alphabet; int); + answer pair_transition(float, alphabet, answer, alphabet; int); + answer bifurcation_transition(float, float, answer, answer; int); + answer nil(float, void; int); + choice [answer] h([answer]); +} + + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +grammar gra_cm uses sig_cm(axiom = state_B_3) { + state_B_3 = bifurcation_transition(CONST_FLOAT(0.000000), CONST_FLOAT(0.000000), state_S_4, state_S_12; 3) + # h; + + state_S_4 = silent_transition(CONST_FLOAT(-9.761000), state_ML_6; 4) + | silent_transition(CONST_FLOAT(-9.808000), state_D_8; 4) + # h; + + state_ML_6 = left_transition(CONST_FLOAT(-1.000000), CHAR, state_E_11; 6) + # h; + + state_D_8 = silent_transition(CONST_FLOAT(-1.000000), state_E_11; 8) + # h; + + state_E_11 = nil(CONST_FLOAT(0.000000), EMPTY; 11) + # h; + + + state_S_12 = silent_transition(CONST_FLOAT(-10.445000), state_ML_15; 12) + | silent_transition(CONST_FLOAT(-11.549000), state_D_17; 12) + # h; + + state_ML_15 = left_transition(CONST_FLOAT(-1.000000), CHAR, state_E_20; 15) + # h; + + state_D_17 = silent_transition(CONST_FLOAT(-1.000000), state_E_20; 17) + # h; + + state_E_20 = nil(CONST_FLOAT(0.000000), EMPTY; 20) + # h; + +} + +instance count = gra_cm(alg_count); +instance enum = gra_cm(alg_enum); + \ No newline at end of file diff --git a/testdata/grammar_outside/pknotsRG.gap b/testdata/grammar_outside/pknotsRG.gap new file mode 120000 index 000000000..f0c8dfb7c --- /dev/null +++ b/testdata/grammar_outside/pknotsRG.gap @@ -0,0 +1 @@ +../grammar/pknotsRG.gap \ No newline at end of file diff --git a/testdata/grammar_outside/rnashapes2wip.gap b/testdata/grammar_outside/rnashapes2wip.gap new file mode 120000 index 000000000..70c8653ce --- /dev/null +++ b/testdata/grammar_outside/rnashapes2wip.gap @@ -0,0 +1 @@ +../grammar/rnashapes2wip.gap \ No newline at end of file diff --git a/testdata/grammar_outside/rnashapesmfe.gap b/testdata/grammar_outside/rnashapesmfe.gap new file mode 120000 index 000000000..e9c947e7e --- /dev/null +++ b/testdata/grammar_outside/rnashapesmfe.gap @@ -0,0 +1 @@ +../grammar/rnashapesmfe.gap \ No newline at end of file diff --git a/testdata/grammar_outside/rnashapespf.gap b/testdata/grammar_outside/rnashapespf.gap new file mode 120000 index 000000000..98b81292a --- /dev/null +++ b/testdata/grammar_outside/rnashapespf.gap @@ -0,0 +1 @@ +../grammar/rnashapespf.gap \ No newline at end of file diff --git a/testdata/grammar_outside/single_block.gap b/testdata/grammar_outside/single_block.gap new file mode 120000 index 000000000..3df269ae9 --- /dev/null +++ b/testdata/grammar_outside/single_block.gap @@ -0,0 +1 @@ +../grammar/single_block.gap \ No newline at end of file diff --git a/testdata/grammar_outside/stefan3.gap b/testdata/grammar_outside/stefan3.gap new file mode 120000 index 000000000..049192085 --- /dev/null +++ b/testdata/grammar_outside/stefan3.gap @@ -0,0 +1 @@ +../grammar/stefan3.gap \ No newline at end of file diff --git a/testdata/grammar_outside/stefan4.gap b/testdata/grammar_outside/stefan4.gap new file mode 120000 index 000000000..2944f1b55 --- /dev/null +++ b/testdata/grammar_outside/stefan4.gap @@ -0,0 +1 @@ +../grammar/stefan4.gap \ No newline at end of file diff --git a/testdata/grammar_outside/tdm2hp.gap b/testdata/grammar_outside/tdm2hp.gap new file mode 120000 index 000000000..90dd67c24 --- /dev/null +++ b/testdata/grammar_outside/tdm2hp.gap @@ -0,0 +1 @@ +../grammar/tdm2hp.gap \ No newline at end of file diff --git a/testdata/grammar_outside/tdm2hporig.gap b/testdata/grammar_outside/tdm2hporig.gap new file mode 120000 index 000000000..a61558bde --- /dev/null +++ b/testdata/grammar_outside/tdm2hporig.gap @@ -0,0 +1 @@ +../grammar/tdm2hporig.gap \ No newline at end of file diff --git a/testdata/grammar_outside/tmhmm.gap b/testdata/grammar_outside/tmhmm.gap new file mode 100644 index 000000000..655cfdb64 --- /dev/null +++ b/testdata/grammar_outside/tmhmm.gap @@ -0,0 +1,951 @@ +import "ext_hmm.hh" +type Rope = extern + +signature sig_tmhmm(alphabet, answer) { + answer silent_transition(float, answer); + answer transition(char, float, answer, answer); + answer nil(void); + answer emission(float, alphabet); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_viterbi implements sig_tmhmm(alphabet=char, answer=float) { + float silent_transition(float prob, float t) { + return prob * t; + } + float transition(char label, float prob, float e, float t) { + return prob * e * t; + } + float nil(void) { + return 1.0; + } + float emission(float prob, char emission) { + return prob; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_fwd extends alg_viterbi { + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_fwd_scaled extends alg_viterbi { + float emission(float prob, char emission) { + /* 43.38 is a scaling factor against numeric instability, + * as candidate probabilities tend to become very small. + * The value is 1 / median of all emission probabilities + * in the TMHMM2 model; but in principle can be any value > 1. + */ + return 22.56 * prob; + } + float normalize_derivative(float q, float pfunc) { + return q / pfunc; + } + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_viterbi_bit extends alg_viterbi { + float silent_transition(float prob, float t) { + return log(1.0/prob) + t; + } + float transition(char label, float prob, float e, float t) { + return log(1.0/prob) + e + t; + } + float nil(void) { + return 0.0; + } + float emission(float prob, char emission) { + return log(1.0/prob); + } + choice [float] h([float] candidates) { + return list(minimum(candidates)); + } +} + +algebra alg_fwd_bit extends alg_viterbi_bit { + float normalize_derivative(float q, float pfunc) { + return exp(pfunc - q); + } + choice [float] h([float] candidates) { + return list(negexpsum(candidates)); + } +} + +algebra alg_label implements sig_tmhmm(alphabet=char, answer=Rope) { + Rope silent_transition(float prob, Rope x) { + return x; + } + Rope transition(char label, float prob, Rope e, Rope t) { + Rope res; + append(res, label); + append(res, t); + return res; + } + Rope nil(void) { + Rope res; + return res; + } + Rope emission(float prob, char emission) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +grammar gra_tmhmm uses sig_tmhmm(axiom = state_begin) { + state_begin = + silent_transition(CONST_FLOAT(0.549251), state_in10) | + silent_transition(CONST_FLOAT(0.207469), state_outglob10) | + silent_transition(CONST_FLOAT(0.24328), state_out10) | + state_end + # h; + + state_in10 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.995851), emit_in10, state_in11) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00111283), emit_in10, state_in29) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00303586), emit_in10, state_ohelixi1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + emit_in10 = + emission(CONST_FLOAT(0.0713632), CHAR('A')) | + emission(CONST_FLOAT(0.0188491), CHAR('C')) | + emission(CONST_FLOAT(0.043014), CHAR('D')) | + emission(CONST_FLOAT(0.0471663), CHAR('E')) | + emission(CONST_FLOAT(0.0298789), CHAR('F')) | + emission(CONST_FLOAT(0.0564853), CHAR('G')) | + emission(CONST_FLOAT(0.0233906), CHAR('H')) | + emission(CONST_FLOAT(0.038904), CHAR('I')) | + emission(CONST_FLOAT(0.0894525), CHAR('K')) | + emission(CONST_FLOAT(0.0551519), CHAR('L')) | + emission(CONST_FLOAT(0.0427067), CHAR('M')) | + emission(CONST_FLOAT(0.0544149), CHAR('N')) | + emission(CONST_FLOAT(0.0370019), CHAR('P')) | + emission(CONST_FLOAT(0.0524006), CHAR('Q')) | + emission(CONST_FLOAT(0.114758), CHAR('R')) | + emission(CONST_FLOAT(0.0661936), CHAR('S')) | + emission(CONST_FLOAT(0.0689907), CHAR('T')) | + emission(CONST_FLOAT(0.0416332), CHAR('V')) | + emission(CONST_FLOAT(0.0146085), CHAR('W')) | + emission(CONST_FLOAT(0.0336358), CHAR('Y')) + # h; + + state_in11 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.976066), emit_in10, state_in12) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0239339), emit_in10, state_in28) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.08323e-09), emit_in10, state_in29) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in12 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.895077), emit_in10, state_in13) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.104922), emit_in10, state_in27) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.76891e-06), emit_in10, state_in28) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in13 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.979527), emit_in10, state_in14) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0204673), emit_in10, state_in26) | + transition(CONST_CHAR('i'), CONST_FLOAT(5.81809e-06), emit_in10, state_in27) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in14 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.993341), emit_in10, state_in15) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00660812), emit_in10, state_in25) | + transition(CONST_CHAR('i'), CONST_FLOAT(5.08664e-05), emit_in10, state_in26) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in15 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.738969), emit_in10, state_in16) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.159734), emit_in10, state_in24) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.101297), emit_in10, state_in25) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in16 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.999938), emit_in10, state_in17) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.4427e-06), emit_in10, state_in23) | + transition(CONST_CHAR('i'), CONST_FLOAT(6.0424e-05), emit_in10, state_in24) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in17 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.973203), emit_in10, state_in18) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0168132), emit_in10, state_in22) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00998417), emit_in10, state_in23) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in18 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.977498), emit_in10, state_in19) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0217216), emit_in10, state_in21) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.000780768), emit_in10, state_in22) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in19 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.16223), emit_in10, state_in20) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.10126), emit_in10, state_in21) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.73651), emit_in10, state_inglob1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in20 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in21) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in21 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in22) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in22 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in23) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in23 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in24) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in24 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in25) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in25 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in26) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in26 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in27) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in27 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in28) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in28 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in29) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in29 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_ohelixi1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_inglob1 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.0132918), emit_inglob1, state_in20) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.986708), emit_inglob1, state_inglob1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_inglob1, state_end) + # h; + emit_inglob1 = + emission(CONST_FLOAT(0.0773341), CHAR('A')) | + emission(CONST_FLOAT(0.0212026), CHAR('C')) | + emission(CONST_FLOAT(0.0556231), CHAR('D')) | + emission(CONST_FLOAT(0.0789783), CHAR('E')) | + emission(CONST_FLOAT(0.0291466), CHAR('F')) | + emission(CONST_FLOAT(0.0821038), CHAR('G')) | + emission(CONST_FLOAT(0.02529), CHAR('H')) | + emission(CONST_FLOAT(0.0392883), CHAR('I')) | + emission(CONST_FLOAT(0.0466567), CHAR('K')) | + emission(CONST_FLOAT(0.0718204), CHAR('L')) | + emission(CONST_FLOAT(0.0191835), CHAR('M')) | + emission(CONST_FLOAT(0.0490524), CHAR('N')) | + emission(CONST_FLOAT(0.0671432), CHAR('P')) | + emission(CONST_FLOAT(0.0472671), CHAR('Q')) | + emission(CONST_FLOAT(0.0492684), CHAR('R')) | + emission(CONST_FLOAT(0.0852997), CHAR('S')) | + emission(CONST_FLOAT(0.0610192), CHAR('T')) | + emission(CONST_FLOAT(0.0528717), CHAR('V')) | + emission(CONST_FLOAT(0.0166592), CHAR('W')) | + emission(CONST_FLOAT(0.0247916), CHAR('Y')) + # h; + + state_outglob10 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob11) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + emit_outglob10 = + emission(CONST_FLOAT(0.0693743), CHAR('A')) | + emission(CONST_FLOAT(0.0149605), CHAR('C')) | + emission(CONST_FLOAT(0.0406956), CHAR('D')) | + emission(CONST_FLOAT(0.0538397), CHAR('E')) | + emission(CONST_FLOAT(0.0531778), CHAR('F')) | + emission(CONST_FLOAT(0.0792746), CHAR('G')) | + emission(CONST_FLOAT(0.0221055), CHAR('H')) | + emission(CONST_FLOAT(0.0440866), CHAR('I')) | + emission(CONST_FLOAT(0.0565779), CHAR('K')) | + emission(CONST_FLOAT(0.0988165), CHAR('L')) | + emission(CONST_FLOAT(0.0432829), CHAR('M')) | + emission(CONST_FLOAT(0.0414346), CHAR('N')) | + emission(CONST_FLOAT(0.0615562), CHAR('P')) | + emission(CONST_FLOAT(0.0412212), CHAR('Q')) | + emission(CONST_FLOAT(0.0677628), CHAR('R')) | + emission(CONST_FLOAT(0.0732544), CHAR('S')) | + emission(CONST_FLOAT(0.0524824), CHAR('T')) | + emission(CONST_FLOAT(0.0445653), CHAR('V')) | + emission(CONST_FLOAT(0.0140309), CHAR('W')) | + emission(CONST_FLOAT(0.0275), CHAR('Y')) + # h; + + state_outglob11 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob12) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob12 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob13) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob13 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob14) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob14 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob15) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob15 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob16) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob16 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob17) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob17 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob18) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob18 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob19) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob19 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglobLong) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglobLong = + transition(CONST_CHAR('O'), CONST_FLOAT(0.999093), emit_inglob1, state_outglobLong) | + transition(CONST_CHAR('O'), CONST_FLOAT(0.000906913), emit_inglob1, state_outglob20) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_inglob1, state_end) + # h; + + state_outglob20 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob21) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob21 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob22) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob22 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob23) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob23 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob24) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob24 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob25) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob25 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob26) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob26 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob27) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob27 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob28) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob28 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob29) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob29 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_ihelixo1) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_out10 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out11) | + transition(CONST_CHAR('o'), CONST_FLOAT(3.54571e-14), emit_out10, state_out29) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + emit_out10 = + emission(CONST_FLOAT(0.0690346), CHAR('A')) | + emission(CONST_FLOAT(0.0129673), CHAR('C')) | + emission(CONST_FLOAT(0.0627756), CHAR('D')) | + emission(CONST_FLOAT(0.0541851), CHAR('E')) | + emission(CONST_FLOAT(0.0425402), CHAR('F')) | + emission(CONST_FLOAT(0.0835626), CHAR('G')) | + emission(CONST_FLOAT(0.0271581), CHAR('H')) | + emission(CONST_FLOAT(0.0292546), CHAR('I')) | + emission(CONST_FLOAT(0.0530401), CHAR('K')) | + emission(CONST_FLOAT(0.0822093), CHAR('L')) | + emission(CONST_FLOAT(0.0334625), CHAR('M')) | + emission(CONST_FLOAT(0.0506017), CHAR('N')) | + emission(CONST_FLOAT(0.0693889), CHAR('P')) | + emission(CONST_FLOAT(0.0389539), CHAR('Q')) | + emission(CONST_FLOAT(0.0432109), CHAR('R')) | + emission(CONST_FLOAT(0.0863749), CHAR('S')) | + emission(CONST_FLOAT(0.0587278), CHAR('T')) | + emission(CONST_FLOAT(0.0480586), CHAR('V')) | + emission(CONST_FLOAT(0.0198473), CHAR('W')) | + emission(CONST_FLOAT(0.0346461), CHAR('Y')) + # h; + + state_out11 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.910217), emit_out10, state_out12) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0495866), emit_out10, state_out28) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0401965), emit_out10, state_out29) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out12 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.984498), emit_out10, state_out13) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00440955), emit_out10, state_out27) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0110921), emit_out10, state_out28) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out13 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.997286), emit_out10, state_out14) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00258189), emit_out10, state_out26) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.000132519), emit_out10, state_out27) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out14 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.812906), emit_out10, state_out15) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0130127), emit_out10, state_out25) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.174082), emit_out10, state_out26) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out15 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.951951), emit_out10, state_out16) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0400992), emit_out10, state_out24) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00795001), emit_out10, state_out25) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out16 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.660205), emit_out10, state_out17) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.33979), emit_out10, state_out23) | + transition(CONST_CHAR('o'), CONST_FLOAT(4.76867e-06), emit_out10, state_out24) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out17 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.992733), emit_out10, state_out18) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0072618), emit_out10, state_out22) | + transition(CONST_CHAR('o'), CONST_FLOAT(5.34599e-06), emit_out10, state_out23) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out18 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.971165), emit_out10, state_out19) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0119931), emit_out10, state_out21) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0168416), emit_out10, state_out22) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out19 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.770716), emit_out10, state_outglobShort) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00133523), emit_out10, state_out20) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.227948), emit_out10, state_out21) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_outglobShort = + transition(CONST_CHAR('o'), CONST_FLOAT(0.960334), emit_inglob1, state_outglobShort) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0396664), emit_inglob1, state_out20) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_inglob1, state_end) + # h; + + state_out20 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out21) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out21 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out22) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out22 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out23) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out23 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out24) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out24 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out25) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out25 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out26) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out26 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out27) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out27 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out28) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out28 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out29) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out29 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_ihelixo1) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_ohelixi1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi2) + # h; + emit_ohelixi1 = + emission(CONST_FLOAT(0.0890049), CHAR('A')) | + emission(CONST_FLOAT(0.0170933), CHAR('C')) | + emission(CONST_FLOAT(0.00159548), CHAR('D')) | + emission(CONST_FLOAT(0.00489647), CHAR('E')) | + emission(CONST_FLOAT(0.108081), CHAR('F')) | + emission(CONST_FLOAT(0.0692068), CHAR('G')) | + emission(CONST_FLOAT(0.00923517), CHAR('H')) | + emission(CONST_FLOAT(0.113471), CHAR('I')) | + emission(CONST_FLOAT(0.00466208), CHAR('K')) | + emission(CONST_FLOAT(0.19417), CHAR('L')) | + emission(CONST_FLOAT(0.0239901), CHAR('M')) | + emission(CONST_FLOAT(0.0233656), CHAR('N')) | + emission(CONST_FLOAT(0.0145168), CHAR('P')) | + emission(CONST_FLOAT(0.00487025), CHAR('Q')) | + emission(CONST_FLOAT(0.0127643), CHAR('R')) | + emission(CONST_FLOAT(0.0455139), CHAR('S')) | + emission(CONST_FLOAT(0.0292949), CHAR('T')) | + emission(CONST_FLOAT(0.128208), CHAR('V')) | + emission(CONST_FLOAT(0.0399529), CHAR('W')) | + emission(CONST_FLOAT(0.0661077), CHAR('Y')) + # h; + + state_ohelixi2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi3) + # h; + + state_ohelixi3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi4) + # h; + + state_ohelixi4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi5) + # h; + + state_ohelixi5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi6) + # h; + + state_ohelixi6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixi7) + # h; + + state_ohelixi7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixm) + # h; + + state_ohelixm = + transition(CONST_CHAR('M'), CONST_FLOAT(0.000534023), emit_ohelixm, state_ohelix2) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000567583), emit_ohelixm, state_ohelix3) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00064457), emit_ohelixm, state_ohelix4) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00159544), emit_ohelixm, state_ohelix5) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000669433), emit_ohelixm, state_ohelix6) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00161008), emit_ohelixm, state_ohelix7) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000762887), emit_ohelixm, state_ohelix8) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000789084), emit_ohelixm, state_ohelix9) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000868204), emit_ohelixm, state_ohelix10) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00519996), emit_ohelixm, state_ohelix11) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00774891), emit_ohelixm, state_ohelix12) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0108947), emit_ohelixm, state_ohelix13) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.697722), emit_ohelixm, state_ohelix14) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0444777), emit_ohelixm, state_ohelix15) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0328707), emit_ohelixm, state_ohelix16) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.111827), emit_ohelixm, state_ohelix17) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0324248), emit_ohelixm, state_ohelix18) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0448694), emit_ohelixm, state_ohelix19) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00212234), emit_ohelixm, state_ohelix20) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00107586), emit_ohelixm, state_ohelix21) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00072618), emit_ohelixm, state_ohelixo1) + # h; + emit_ohelixm = + emission(CONST_FLOAT(0.110896), CHAR('A')) | + emission(CONST_FLOAT(0.0254931), CHAR('C')) | + emission(CONST_FLOAT(0.00235724), CHAR('D')) | + emission(CONST_FLOAT(0.00383965), CHAR('E')) | + emission(CONST_FLOAT(0.0942003), CHAR('F')) | + emission(CONST_FLOAT(0.0818095), CHAR('G')) | + emission(CONST_FLOAT(0.00408389), CHAR('H')) | + emission(CONST_FLOAT(0.144377), CHAR('I')) | + emission(CONST_FLOAT(0.00236432), CHAR('K')) | + emission(CONST_FLOAT(0.182902), CHAR('L')) | + emission(CONST_FLOAT(0.0385107), CHAR('M')) | + emission(CONST_FLOAT(0.00978815), CHAR('N')) | + emission(CONST_FLOAT(0.0201094), CHAR('P')) | + emission(CONST_FLOAT(0.00437833), CHAR('Q')) | + emission(CONST_FLOAT(0.00115335), CHAR('R')) | + emission(CONST_FLOAT(0.0421756), CHAR('S')) | + emission(CONST_FLOAT(0.0514071), CHAR('T')) | + emission(CONST_FLOAT(0.132167), CHAR('V')) | + emission(CONST_FLOAT(0.0158643), CHAR('W')) | + emission(CONST_FLOAT(0.0321232), CHAR('Y')) + # h; + + state_ohelix2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix3) + # h; + + state_ohelix3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix4) + # h; + + state_ohelix4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix5) + # h; + + state_ohelix5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix6) + # h; + + state_ohelix6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix7) + # h; + + state_ohelix7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix8) + # h; + + state_ohelix8 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix9) + # h; + + state_ohelix9 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix10) + # h; + + state_ohelix10 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix11) + # h; + + state_ohelix11 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix12) + # h; + + state_ohelix12 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix13) + # h; + + state_ohelix13 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix14) + # h; + + state_ohelix14 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix15) + # h; + + state_ohelix15 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix16) + # h; + + state_ohelix16 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix17) + # h; + + state_ohelix17 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix18) + # h; + + state_ohelix18 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix19) + # h; + + state_ohelix19 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix20) + # h; + + state_ohelix20 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix21) + # h; + + state_ohelix21 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixo1) + # h; + + state_ohelixo1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixo2) + # h; + + state_ohelixo2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixo3) + # h; + + state_ohelixo3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo4) + # h; + + state_ohelixo4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo5) + # h; + + state_ohelixo5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo6) + # h; + + state_ohelixo6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo7) + # h; + + state_ohelixo7 = + transition(CONST_CHAR('M'), CONST_FLOAT(0.0757404), emit_ohelixo7, state_outglob10) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.92426), emit_ohelixo7, state_out10) + # h; + emit_ohelixo7 = + emission(CONST_FLOAT(0.110353), CHAR('A')) | + emission(CONST_FLOAT(0.00498206), CHAR('C')) | + emission(CONST_FLOAT(0.00469973), CHAR('D')) | + emission(CONST_FLOAT(0.00649427), CHAR('E')) | + emission(CONST_FLOAT(0.0973043), CHAR('F')) | + emission(CONST_FLOAT(0.0737631), CHAR('G')) | + emission(CONST_FLOAT(0.0119931), CHAR('H')) | + emission(CONST_FLOAT(0.12167), CHAR('I')) | + emission(CONST_FLOAT(0.00180854), CHAR('K')) | + emission(CONST_FLOAT(0.157124), CHAR('L')) | + emission(CONST_FLOAT(0.044721), CHAR('M')) | + emission(CONST_FLOAT(0.0107496), CHAR('N')) | + emission(CONST_FLOAT(0.0283821), CHAR('P')) | + emission(CONST_FLOAT(0.0143416), CHAR('Q')) | + emission(CONST_FLOAT(0.00857182), CHAR('R')) | + emission(CONST_FLOAT(0.0402204), CHAR('S')) | + emission(CONST_FLOAT(0.0501039), CHAR('T')) | + emission(CONST_FLOAT(0.107462), CHAR('V')) | + emission(CONST_FLOAT(0.0501891), CHAR('W')) | + emission(CONST_FLOAT(0.0550665), CHAR('Y')) + # h; + + state_ihelixo1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo2) + # h; + + state_ihelixo2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo3) + # h; + + state_ihelixo3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo4) + # h; + + state_ihelixo4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo5) + # h; + + state_ihelixo5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo6) + # h; + + state_ihelixo6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixo7) + # h; + + state_ihelixo7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixm) + # h; + + state_ihelixm = + transition(CONST_CHAR('M'), CONST_FLOAT(0.000534023), emit_ohelixm, state_ihelix2) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000567583), emit_ohelixm, state_ihelix3) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00064457), emit_ohelixm, state_ihelix4) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00159544), emit_ohelixm, state_ihelix5) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000669433), emit_ohelixm, state_ihelix6) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00161008), emit_ohelixm, state_ihelix7) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000762887), emit_ohelixm, state_ihelix8) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000789084), emit_ohelixm, state_ihelix9) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000868204), emit_ohelixm, state_ihelix10) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00519996), emit_ohelixm, state_ihelix11) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00774891), emit_ohelixm, state_ihelix12) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0108947), emit_ohelixm, state_ihelix13) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.697722), emit_ohelixm, state_ihelix14) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0444777), emit_ohelixm, state_ihelix15) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0328707), emit_ohelixm, state_ihelix16) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.111827), emit_ohelixm, state_ihelix17) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0324248), emit_ohelixm, state_ihelix18) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0448694), emit_ohelixm, state_ihelix19) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00212234), emit_ohelixm, state_ihelix20) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00107586), emit_ohelixm, state_ihelix21) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00072618), emit_ohelixm, state_ihelixi1) + # h; + + state_ihelix2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix3) + # h; + + state_ihelix3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix4) + # h; + + state_ihelix4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix5) + # h; + + state_ihelix5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix6) + # h; + + state_ihelix6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix7) + # h; + + state_ihelix7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix8) + # h; + + state_ihelix8 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix9) + # h; + + state_ihelix9 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix10) + # h; + + state_ihelix10 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix11) + # h; + + state_ihelix11 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix12) + # h; + + state_ihelix12 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix13) + # h; + + state_ihelix13 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix14) + # h; + + state_ihelix14 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix15) + # h; + + state_ihelix15 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix16) + # h; + + state_ihelix16 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix17) + # h; + + state_ihelix17 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix18) + # h; + + state_ihelix18 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix19) + # h; + + state_ihelix19 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix20) + # h; + + state_ihelix20 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix21) + # h; + + state_ihelix21 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixi1) + # h; + + state_ihelixi1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixi2) + # h; + + state_ihelixi2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixi3) + # h; + + state_ihelixi3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi4) + # h; + + state_ihelixi4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi5) + # h; + + state_ihelixi5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi6) + # h; + + state_ihelixi6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi7) + # h; + + state_ihelixi7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_in10) + # h; + + state_end = nil(EMPTY) # h; +} + +instance dummy = gra_tmhmm(alg_enum); +instance fwd_scaled = gra_tmhmm(alg_fwd_scaled); \ No newline at end of file diff --git a/testdata/grammar_outside/tmhmm_debug.gap b/testdata/grammar_outside/tmhmm_debug.gap new file mode 100644 index 000000000..ace396b17 --- /dev/null +++ b/testdata/grammar_outside/tmhmm_debug.gap @@ -0,0 +1,160 @@ +type Rope = extern + +signature sig_tmhmm(alphabet, answer) { + answer silent_step(answer); + answer step(char, answer, answer); + answer nil(void); + answer trans(float, answer); + answer only(float, alphabet); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_viterbi implements sig_tmhmm(alphabet=char, answer=float) { + float silent_step(float x) { + return x; + } + float step(char label, float e, float t) { + return e*t; + } + float nil(void) { + return 1; + } + float trans(float prob, float x) { + return prob * x; + } + float only(float prob, char emission) { + return prob; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_viterbi_bit extends alg_viterbi { + float step(char label, float e, float t) { + return log(1.0/e) + t; + } + float nil(void) { + return 0.0; + } + float trans(float prob, float x) { + return log(1.0/prob) + x; + } + choice [float] h([float] candidates) { + return list(minimum(candidates)); + } +} + +algebra alg_label implements sig_tmhmm(alphabet=char, answer=Rope) { + Rope silent_step(Rope x) { + return x; + } + Rope step(char label, Rope e, Rope t) { + Rope res; + append(res, label); + append(res, t); + return res; + } + Rope nil(void) { + Rope res; + return res; + } + Rope trans(float prob, Rope x) { + return x; + } + Rope only(float prob, char emission) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +grammar gra_tmhmm uses sig_tmhmm(axiom = state_begin) { + state_begin = silent_step(transitions_begin) # h; + transitions_begin = + trans(CONST_FLOAT(0.549251), state_in10) | + trans(CONST_FLOAT(0.207469), state_outglob10) | + trans(CONST_FLOAT(0.24328), state_out10) + # h; + state_in10 = step(CONST_CHAR('i'), emissions_in10, { transitions_in10 | nil(EMPTY) }) # h; + emissions_in10 = + only(CONST_FLOAT(0.0713632), CHAR('A')) | + only(CONST_FLOAT(0.0336358), CHAR('Y')) + # h; + transitions_in10 = + trans(CONST_FLOAT(0.995851), state_in11) | + trans(CONST_FLOAT(0.00111283), state_in29) | + trans(CONST_FLOAT(0.00303586), state_ohelixi1) + # h; + state_in11 = step(CONST_CHAR('i'), emissions_in10, { transitions_in11 | nil(EMPTY) }) # h; + transitions_in11 = + trans(CONST_FLOAT(0.976066), nil(EMPTY)) | + trans(CONST_FLOAT(0.0239339), nil(EMPTY)) | + trans(CONST_FLOAT(1.08323e-09), state_in29) + # h; + state_in29 = step(CONST_CHAR('i'), emissions_in10, { transitions_in29 | nil(EMPTY) }) # h; + transitions_in29 = + trans(CONST_FLOAT(1.0), state_ohelixi1) + # h; + state_ohelixi1 = step(CONST_CHAR('M'), emissions_ohelixi1, transitions_ohelixi1) # h; + emissions_ohelixi1 = + only(CONST_FLOAT(0.0890049), CHAR('A')) | + only(CONST_FLOAT(0.0661077), CHAR('Y')) + # h; + transitions_ohelixi1 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) + # h; + state_outglob10 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob10 | nil(EMPTY) }) # h; + emissions_outglob10 = + only(CONST_FLOAT(0.0693743), CHAR('A')) | + only(CONST_FLOAT(0.0275), CHAR('Y')) + # h; + transitions_outglob10 = + trans(CONST_FLOAT(1.0), state_outglob11) | + trans(CONST_FLOAT(0.0), state_outglob29) | + trans(CONST_FLOAT(0.0), state_ihelixo1) + # h; + state_outglob11 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob11 | nil(EMPTY) }) # h; + transitions_outglob11 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) | + trans(CONST_FLOAT(0.0), nil(EMPTY)) | + trans(CONST_FLOAT(0.0), state_outglob29) + # h; + state_outglob29 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob29 | nil(EMPTY) }) # h; + transitions_outglob29 = + trans(CONST_FLOAT(1.0), state_ihelixo1) + # h; + state_ihelixo1 = step(CONST_CHAR('M'), emissions_out10, transitions_ihelixo1) # h; + transitions_ihelixo1 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) + # h; + state_out10 = step(CONST_CHAR('o'), emissions_out10, { transitions_out10 | nil(EMPTY) }) # h; + emissions_out10 = + only(CONST_FLOAT(0.0690346), CHAR('A')) | + only(CONST_FLOAT(0.0346461), CHAR('Y')) + # h; + transitions_out10 = + trans(CONST_FLOAT(1.0), state_out11) | + trans(CONST_FLOAT(3.54571e-14), state_out29) | + trans(CONST_FLOAT(0.0), state_ihelixo1) + # h; + state_out11 = step(CONST_CHAR('o'), emissions_out10, { transitions_out11 | nil(EMPTY) }) # h; + transitions_out11 = + trans(CONST_FLOAT(0.910217), nil(EMPTY)) | + trans(CONST_FLOAT(0.0495866), nil(EMPTY)) | + trans(CONST_FLOAT(0.0401965), state_out29) + # h; + state_out29 = step(CONST_CHAR('o'), emissions_out10, { transitions_out29 | nil(EMPTY) }) # h; + transitions_out29 = + trans(CONST_FLOAT(1.0), state_ihelixo1) + # h; +} + +instance dummy = gra_tmhmm(alg_enum); +instance count = gra_tmhmm(alg_count); diff --git a/testdata/grammar_outside/unblock_alot.gap b/testdata/grammar_outside/unblock_alot.gap new file mode 100644 index 000000000..74fdb37b8 --- /dev/null +++ b/testdata/grammar_outside/unblock_alot.gap @@ -0,0 +1,239 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, {{{struct}}}) | + cadd({dangle | sadd(BASE, {dangle | incl(hairpin) | incl(strong)})}, struct) | + nil(LOC) # h; + + dangle = drem(LOC, strong, LOC) # h; + + strong = weak # h; + + weak = stack | + hairpin | + leftB | + rightB | + iloop | + multiloop # h; + + stack = sr(BASE, weak, BASE) with basepairing # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = bl(BASE, REGION with maxsize(30), strong, BASE) with basepairing # h; + rightB = br(BASE, strong, REGION with maxsize(30), BASE) with basepairing # h; + iloop = il(BASE, REGION with maxsize(30), strong, REGION with maxsize(30), BASE) with basepairing with_overlay iloopSumMax(30) # h; + multiloop = ml(BASE, ml_comps, BASE) with basepairing # h; + + ml_comps = sadd(BASE, ml_comps) | + cadd(incl(dangle), ml_comps1) # h; + + ml_comps1 = sadd(BASE, ml_comps1) | + cadd(incl(dangle), ml_comps1) | + incl(dangle) | + addss(incl(dangle), REGION) # h; +} + + + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/unblock_multialt_parentNT.gap b/testdata/grammar_outside/unblock_multialt_parentNT.gap new file mode 100644 index 000000000..92f51d29f --- /dev/null +++ b/testdata/grammar_outside/unblock_multialt_parentNT.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = {sadd(BASE, struct) | sadd(BASE, hairpin) | weak} + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = {hairpin} # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/grammar_outside/unblock_multialt_parentSimple.gap b/testdata/grammar_outside/unblock_multialt_parentSimple.gap new file mode 100644 index 000000000..3d57191c0 --- /dev/null +++ b/testdata/grammar_outside/unblock_multialt_parentSimple.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, {struct | weak | incl(dangle)}) + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = hairpin # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/grammar_outside/unblock_onealt_parentNT.gap b/testdata/grammar_outside/unblock_onealt_parentNT.gap new file mode 100644 index 000000000..caff68a6b --- /dev/null +++ b/testdata/grammar_outside/unblock_onealt_parentNT.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = {sadd(BASE, struct)} + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = {hairpin} # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/grammar_outside/unblock_onealt_parentSimple.gap b/testdata/grammar_outside/unblock_onealt_parentSimple.gap new file mode 100644 index 000000000..9711b86da --- /dev/null +++ b/testdata/grammar_outside/unblock_onealt_parentSimple.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, {struct}) + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = {hairpin} # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/modtest/outside_checksemantics.cc b/testdata/modtest/outside_checksemantics.cc new file mode 100644 index 000000000..25d7cf194 --- /dev/null +++ b/testdata/modtest/outside_checksemantics.cc @@ -0,0 +1,69 @@ +#include "../../src/driver.hh" +#include "../../src/log.hh" + +#include +#include +#include +#include + +int main(int argc, char **argv) { + std::ostringstream o; + Log log; + log.set_debug(false); + log.set_ostream(std::cout); + + Driver driver; + + if (argc != 2) { + std::cerr << "Call " << *argv << " *.gap-file\n"; + return 1; + } + // === front + // set the file name of the gap-source-code + driver.setFilename(argv[1]); + + // parses the input file and builds the AST + driver.parse(); + + // simply gets the selected grammar, which is either the + // grammar that occurred first in the source code or is the + // one that was named in the parameters on the command line + Grammar *grammar = driver.ast.grammar(); + // Now check the semantic, which does more than the function + // name suggests. The semantic check is embedded in the algorithm + // that links the grammar graph together, and computes yield-sizes. + // If the method returns false, there are some semantic errors, + // which leads to the end of the compilation process. + bool r = grammar->check_semantic(); + return 1; +// +// // inject rules for outside grammar +// grammar->inject_outside_nts(); +// +// // set approx table design +// grammar->approx_table_conf(); +// +// // find what type of input is read +// // chars, sequence of ints etc. +// driver.ast.derive_temp_alphabet(); +// +// r = driver.ast.check_signature(); +// if (!r) { +// return 4; +// } +// +// // apply this to identify standard functions like Min, Max, Exp etc. +// driver.ast.derive_roles(); +// +// +// // ------------- back ------------ +// grammar->init_list_sizes(); +// +// grammar->init_indices(); +// grammar->init_decls(); +// // for cyk (ordering of NT for parsing, see page 101 of the thesis) +// grammar->dep_analysis(); +// +// unsigned int nodeID = 1; +// grammar->to_dot(&nodeID, std::cout, 3); +} diff --git a/testdata/modtest/run_outside.sh b/testdata/modtest/run_outside.sh new file mode 100644 index 000000000..ffcadeebe --- /dev/null +++ b/testdata/modtest/run_outside.sh @@ -0,0 +1,67 @@ +#!/bin/ksh + +# call for example: +# ksh run.sh ../../../adpc-tng-logs tab typecheck + +set -u + +if [ $# -lt 2 ]; then + echo $0 DATA-BASE TOOL-ONE \[MORE_TOOLS...\] + exit 1 +fi + +GRAMMAR=../grammar_outside +WORKDIR=`pwd` +TEMP=$WORKDIR/temp +REF=$1 +PREFIX=../.. + +mkdir -p $TEMP + +if [ ! -d $REF ]; then + echo Reference directory is no directory: $TEMP/$REF + exit 1 +fi + +succ_count=0 +err_count=0 +failed=0 + +. ../log.sh + +for j in ${*:2}; do + cd $GRAMMAR + mkdir -p $TEMP/$j + for i in `ls * | grep -v '\(^core$\|\.orig$\)'`; do + failed=0 + log_both $TEMP/$j/$i $PREFIX/$j $i + if [ $failed != 0 ]; then + err_count=$((err_count+1)) + fi + done +done + +module_errors=$err_count + +err_count=0 +cd $TEMP +for j in ${*:2}; do + echo +------------------------------------------------------------------------------+ + failed=0 + l=`echo $REF/$j[0-9]* | tr ' ' '\n' | sed 's/\([0-9]\+\)/:\1/' |\ + sort -n -r -k 2 -t : | tr -d : | head -1` + log diff -ur $l $j + + if [ $failed != 0 ]; then + echo --++--FAIL--++-- + err_count=$((err_count+1)) + else + echo OK + succ_count=$((succ_count+1)) + fi + echo +------------------------------------------------------------------------------+ +done + + +echo +==============================================================================+ +. ../../stats.sh From 8fbe3800f5c46dcab61ea3b0e0c5be099bf8d9c4 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 17:29:49 +0100 Subject: [PATCH 003/189] activate outside mode --- testdata/modtest/outside_checksemantics.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testdata/modtest/outside_checksemantics.cc b/testdata/modtest/outside_checksemantics.cc index 25d7cf194..a3e97bad1 100644 --- a/testdata/modtest/outside_checksemantics.cc +++ b/testdata/modtest/outside_checksemantics.cc @@ -29,6 +29,12 @@ int main(int argc, char **argv) { // grammar that occurred first in the source code or is the // one that was named in the parameters on the command line Grammar *grammar = driver.ast.grammar(); + + // activate outside grammar generation + std::vector outside_nts; + outside_nts.push_back("ALL"); + driver.ast.set_outside_nt_list(&outside_nts); + // Now check the semantic, which does more than the function // name suggests. The semantic check is embedded in the algorithm // that links the grammar graph together, and computes yield-sizes. From f0d55aec02110c0366cf65fcb062158c9884a696 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 17:36:27 +0100 Subject: [PATCH 004/189] add first semantic check: can empty words be parsed --- src/ast.cc | 9 +++++---- src/ast.hh | 16 ++++++++++++++++ src/gapc.cc | 9 +++++++++ src/grammar.cc | 7 ++++++- src/grammar.hh | 4 ++++ src/options.hh | 9 +++++++++ 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/ast.cc b/src/ast.cc index c53598ce4..44fb7506d 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -54,16 +54,17 @@ AST::AST() : product_(0), grammars_(0), selected_grammar(0), - back_track_paretosort(Product::NONE), - adp_specialization(ADP_Mode::STANDARD), - pareto_cutoff(-1), - float_acc(0), + back_track_paretosort(Product::NONE), + adp_specialization(ADP_Mode::STANDARD), + pareto_cutoff(-1), + float_acc(0), signature(NULL), first_instance(NULL), instance_(0), backtrack_product(0), backtrack_filter(0), original_product(0), char_type(0), + outside_nt_list(nullptr), checkpoint(nullptr) { Type::add_predefined(types); } diff --git a/src/ast.hh b/src/ast.hh index c070c6d32..683b17414 100644 --- a/src/ast.hh +++ b/src/ast.hh @@ -285,6 +285,12 @@ class AST { private: void set_tracks(); + // if not empty, automatically generate an outside version of + // the provided grammar and print out results of the provided + // list of outside non-terminals. Report ALL non-terminals, + // if list states 'ALL'. + std::vector *outside_nt_list; + public: Bool window_mode; void set_window_mode(bool w); @@ -298,6 +304,16 @@ class AST { } Printer::Checkpoint *checkpoint; + + bool outside_generation() { + if (!outside_nt_list) { + return false; + } + return outside_nt_list->size() > 0; + } + void set_outside_nt_list(std::vector *nts) { + outside_nt_list = nts; + } }; #endif // SRC_AST_HH_ diff --git a/src/gapc.cc b/src/gapc.cc index 9fe5f055f..46a091861 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -102,6 +102,11 @@ static void parse_options(int argc, char **argv, Options *rec) { "uses the selected instance and creates a GAP program which creates " "specialized GAP programs that recognize a subset of candidates of the " "original grammar.") + ("outside_grammar", po::value< std::vector >(), + "generate an outside version of the grammar and report outside results " + "for an inside non-terminal. Provide multiple times for lists of " + "non-terminals or type \"ALL\" to report results for all non-" + "terminals.") ("verbose", "show suppressed warnings and messages") ("log-level,l", po::value(), "the log level, valid values are 0 (VERBOSE), 1 (INFO), 2 (NORMAL), 3 " @@ -234,6 +239,9 @@ static void parse_options(int argc, char **argv, Options *rec) { if (vm.count("specialize_grammar")) { rec->specializeGrammar = true; } + if (vm.count("outside_grammar")) + rec->outside_nt_list = vm["outside_grammar"] + .as< std::vector >(); if (vm.count("verbose")) rec->verbose_mode = true; if (vm.count("log-level")) { @@ -354,6 +362,7 @@ class Main { // more information on this see the comment of the method // AST::select_grammar (instance_name). driver.ast.select_grammar(opts.instance); + driver.ast.set_outside_nt_list(&opts.outside_nt_list); driver.parse_product(opts.product); if (driver.is_failing()) { diff --git a/src/grammar.cc b/src/grammar.cc index 05ed26b72..11f7bf4cb 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -52,7 +52,6 @@ #include "symbol.hh" - void Grammar::add_nt(Symbol::NT *nt) { assert(nt->name); if (NTs.find(*nt->name) != NTs.end()) { @@ -490,6 +489,12 @@ bool Grammar::check_semantic() { print_links(); } } + + /* when outside grammar is requested, raise warning if inside grammar cannot + * parse the empty word, which is the recursion base for all outside + * candidates */ + b = this->check_outside_parse_empty_word(); + return r; } diff --git a/src/grammar.hh b/src/grammar.hh index 1ddb4aa12..96ff7482e 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -207,6 +207,10 @@ class Grammar { void multi_propagate_max_filter(); unsigned int to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + + /* semantic check: grammar must be able to parse the empty input in + * order to provide recursion base for outside candidates */ + bool check_outside_parse_empty_word(); }; diff --git a/src/options.hh b/src/options.hh index 6c9c9ad7a..2ddfdb12d 100644 --- a/src/options.hh +++ b/src/options.hh @@ -59,6 +59,8 @@ struct Options { specialization(0), step_option(0), plot_grammar(0), plotgrammar_stream_(NULL), checkpointing(false) { + // start with no requested outside NTs, i.e. no outside generation + outside_nt_list.clear(); } @@ -115,6 +117,13 @@ struct Options { // requested by the user. This will prompt the compiler to // ignore most of the other options (except the instance selector // and output file name). + + // if not empty, automatically generate an outside version of + // the provided grammar and print out results of the provided + // list of outside non-terminals. Report ALL non-terminals, + // if list states 'ALL'. + std::vector outside_nt_list; + bool specializeGrammar; // flag that is used to turn on verbose mode, i.g. all suppressed // warnings and messages will be shown From 0b0091ee26c188ae98e0c600bced0cff2c6dfcd3 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 17:38:13 +0100 Subject: [PATCH 005/189] activate tests --- .github/workflows/outside.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/outside.yml diff --git a/.github/workflows/outside.yml b/.github/workflows/outside.yml new file mode 100644 index 000000000..f3bda8fe9 --- /dev/null +++ b/.github/workflows/outside.yml @@ -0,0 +1,34 @@ +name: test outside injection + +on: + push: + branches: [ master ] + pull_request: + branches: [ master, outside ] + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + tags: + description: 'Test scenario tags' + +jobs: + gapc_ubuntu: + runs-on: ubuntu-latest + steps: + - name: Update apt + run: sudo apt-get update + - name: Install dependencies + run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip + + - name: Checkout truth + run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + + - uses: actions/checkout@v2 + - name: configure + run: ./configure --prefix $GITHUB_WORKSPACE + + - name: test-mod + run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu From 80be2bcc96b3f5e51871a68ca855ebce0ac44a76 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 18:04:07 +0100 Subject: [PATCH 006/189] adding new souce file --- src/outside/grammar_transformation.cc | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/outside/grammar_transformation.cc diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc new file mode 100644 index 000000000..02c312356 --- /dev/null +++ b/src/outside/grammar_transformation.cc @@ -0,0 +1,28 @@ +/* + * grammar_transformation.cc + * + * Created on: Mar 7, 2023 + * Author: sjanssen + */ + +#include "../grammar.hh" +#include "../ast.hh" + +bool Grammar::check_outside_parse_empty_word() { + if (this->ast.outside_generation()) { + for (std::vector::const_iterator i = this->axiom->multi_ys().begin(); i != this->axiom->multi_ys().end(); ++i) { + if ((*i).low() > 0) { + std::ostringstream msg; + msg << "The minimal yield size of your grammar '" << *this->name << "' is "; + (*i).low().put(msg); + msg << ", i.e. it cannot parse the empty input string ''." + << " For outside grammar generation, this means you are lacking a " + << "recursion basis which will result in empty results for " + << "ALL outside candidates! Try adding an alternative like nil(EMPTY) to your axiom."; + Log::instance()->warning(this->location, msg.str()); + return false; + } + } + } + return true; +} From 2dafa7848d497b6b6cb0d5211508fcd19a4d4c95 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 18:52:38 +0100 Subject: [PATCH 007/189] linting --- src/outside/grammar_transformation.cc | 47 ++++++++++++++++++++------- src/outside/grammar_transformation.hh | 22 +++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/outside/grammar_transformation.hh diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 02c312356..241d6635c 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -1,24 +1,47 @@ -/* - * grammar_transformation.cc - * - * Created on: Mar 7, 2023 - * Author: sjanssen - */ +/* {{{ + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ + +#include + +#include "grammar_transformation.hh" #include "../grammar.hh" #include "../ast.hh" bool Grammar::check_outside_parse_empty_word() { if (this->ast.outside_generation()) { - for (std::vector::const_iterator i = this->axiom->multi_ys().begin(); i != this->axiom->multi_ys().end(); ++i) { + for (std::vector::const_iterator i = + this->axiom->multi_ys().begin(); + i != this->axiom->multi_ys().end(); ++i) { if ((*i).low() > 0) { - std::ostringstream msg; - msg << "The minimal yield size of your grammar '" << *this->name << "' is "; + std::ostringstream msg; + msg << "The minimal yield size of your grammar '" << *this->name + << "' is "; (*i).low().put(msg); msg << ", i.e. it cannot parse the empty input string ''." - << " For outside grammar generation, this means you are lacking a " - << "recursion basis which will result in empty results for " - << "ALL outside candidates! Try adding an alternative like nil(EMPTY) to your axiom."; + << " For outside grammar generation, this means you are lacking a" + << " recursion basis which will result in empty results for " + << "ALL outside candidates! Try adding an alternative like " + << "nil(EMPTY) to your axiom."; Log::instance()->warning(this->location, msg.str()); return false; } diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh new file mode 100644 index 000000000..5650b4050 --- /dev/null +++ b/src/outside/grammar_transformation.hh @@ -0,0 +1,22 @@ +/* {{{ + + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ From 04f04b3ae591c65281e43c302ce0f24fea097628 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 20:19:41 +0100 Subject: [PATCH 008/189] added header guard --- src/outside/grammar_transformation.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh index 5650b4050..41bd17f09 100644 --- a/src/outside/grammar_transformation.hh +++ b/src/outside/grammar_transformation.hh @@ -20,3 +20,8 @@ along with this program. If not, see . }}} */ + +#ifndef SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ +#define SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ + +#endif // SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ From f0231dad8ca3e8b31e95a1332aba40d67f45e9ff Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 7 Mar 2023 22:33:46 +0100 Subject: [PATCH 009/189] adding a test for user input NTs --- src/ast.hh | 3 ++ src/grammar.cc | 4 ++ src/grammar.hh | 6 +++ src/outside/grammar_transformation.cc | 44 +++++++++++++++++++++ src/outside/grammar_transformation.hh | 4 ++ testdata/modtest/outside_checksemantics.cc | 45 +++++++--------------- 6 files changed, 74 insertions(+), 32 deletions(-) diff --git a/src/ast.hh b/src/ast.hh index 683b17414..f470b80c1 100644 --- a/src/ast.hh +++ b/src/ast.hh @@ -314,6 +314,9 @@ class AST { void set_outside_nt_list(std::vector *nts) { outside_nt_list = nts; } + const std::vector *get_outside_nt_list() { + return this->outside_nt_list; + } }; #endif // SRC_AST_HH_ diff --git a/src/grammar.cc b/src/grammar.cc index 11f7bf4cb..66c8333cb 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -494,6 +494,10 @@ bool Grammar::check_semantic() { * parse the empty word, which is the recursion base for all outside * candidates */ b = this->check_outside_parse_empty_word(); + r = r && b; + + // check that all NTs requested by the user are actually part of the grammar + this->check_outside_requested_nonexisting_nts(); return r; } diff --git a/src/grammar.hh b/src/grammar.hh index 96ff7482e..840d81d61 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -211,6 +211,12 @@ class Grammar { /* semantic check: grammar must be able to parse the empty input in * order to provide recursion base for outside candidates */ bool check_outside_parse_empty_word(); + + /* input check: tests if all NTs requested by the user to be reported + * actually do exist in the chosen inside grammar. + * Throws an error if NTs are not present. + */ + void check_outside_requested_nonexisting_nts(); }; diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 241d6635c..99e7fca10 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -22,6 +22,8 @@ }}} */ #include +#include +#include #include "grammar_transformation.hh" #include "../grammar.hh" @@ -49,3 +51,45 @@ bool Grammar::check_outside_parse_empty_word() { } return true; } + +void Grammar::check_outside_requested_nonexisting_nts() { + /* double check that all NTs do exist that the user requested to + * be reported in the outside grammar. + */ + + // a list that collects the names of non existent NTs + std::list *warn_missing_nts = new std::list(); + + // iterate through NTs which the user requested to be reported + for (std::vector::const_iterator i = + this->ast.get_outside_nt_list()->begin(); + i != this->ast.get_outside_nt_list()->end(); ++i) { + // ignore the special user input "ALL", since this is per definition not + // a non-terminal in the grammar + if ((*i).compare(OUTSIDE_ALL) == 0) { + continue; + } + + // next, check if NT with user given name is present in grammar + if (this->NTs.find(*i) == this->NTs.end()) { + // if not, add this NT name to the list + warn_missing_nts->push_back(*i); + } + } + + if (warn_missing_nts->size() > 0) { + std::string msg = std::string( + "You requested outside grammar generation and\nreporting results for " + "the following non-terminals, which do NOT exist in your grammar '" + + *this->name + "':\n"); + for (std::list::iterator i = warn_missing_nts->begin(); + i != warn_missing_nts->end(); ++i) { + msg += " '" + *i + "'"; + if (next(i) != warn_missing_nts->end()) { + msg += "\n"; + } + } + throw LogError(this->location, msg); + } +} + diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh index 41bd17f09..b5d0886b1 100644 --- a/src/outside/grammar_transformation.hh +++ b/src/outside/grammar_transformation.hh @@ -24,4 +24,8 @@ #ifndef SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ #define SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ +static const char *OUTSIDE_NT_PREFIX = "outside_"; +static const char *OUTSIDE_ALL = "ALL"; + + #endif // SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ diff --git a/testdata/modtest/outside_checksemantics.cc b/testdata/modtest/outside_checksemantics.cc index a3e97bad1..a7894a0cc 100644 --- a/testdata/modtest/outside_checksemantics.cc +++ b/testdata/modtest/outside_checksemantics.cc @@ -33,6 +33,9 @@ int main(int argc, char **argv) { // activate outside grammar generation std::vector outside_nts; outside_nts.push_back("ALL"); + if (grammar->name->compare("canonicals_nonamb") == 0) { + outside_nts.push_back("idonotexist"); + } driver.ast.set_outside_nt_list(&outside_nts); // Now check the semantic, which does more than the function @@ -40,36 +43,14 @@ int main(int argc, char **argv) { // that links the grammar graph together, and computes yield-sizes. // If the method returns false, there are some semantic errors, // which leads to the end of the compilation process. - bool r = grammar->check_semantic(); - return 1; -// -// // inject rules for outside grammar -// grammar->inject_outside_nts(); -// -// // set approx table design -// grammar->approx_table_conf(); -// -// // find what type of input is read -// // chars, sequence of ints etc. -// driver.ast.derive_temp_alphabet(); -// -// r = driver.ast.check_signature(); -// if (!r) { -// return 4; -// } -// -// // apply this to identify standard functions like Min, Max, Exp etc. -// driver.ast.derive_roles(); -// -// -// // ------------- back ------------ -// grammar->init_list_sizes(); -// -// grammar->init_indices(); -// grammar->init_decls(); -// // for cyk (ordering of NT for parsing, see page 101 of the thesis) -// grammar->dep_analysis(); -// -// unsigned int nodeID = 1; -// grammar->to_dot(&nodeID, std::cout, 3); + bool r; + try { + r = grammar->check_semantic(); + } catch (std::exception const &exc) { + std::cerr << exc.what(); + } + + if (!r) { + return 1; + } } From 470d36eb64c67097860544bc56a1042df7cef7a4 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 8 Mar 2023 08:51:29 +0100 Subject: [PATCH 010/189] skip test if no outside was requested at all --- src/outside/grammar_transformation.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 99e7fca10..ebaee537f 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -26,6 +26,7 @@ #include #include "grammar_transformation.hh" +#include "../signature.hh" #include "../grammar.hh" #include "../ast.hh" @@ -57,6 +58,12 @@ void Grammar::check_outside_requested_nonexisting_nts() { * be reported in the outside grammar. */ + if (!this->ast.get_outside_nt_list()) { + // the user did not request any outside NT to be reported + return; + } + assert(this->ast.get_outside_nt_list()); + // a list that collects the names of non existent NTs std::list *warn_missing_nts = new std::list(); @@ -93,3 +100,22 @@ void Grammar::check_outside_requested_nonexisting_nts() { } } +bool Grammar::check_multiple_answer_types(Signature_Base &s) { +// if (!this->ast.outside_generation()) { +// // no need to check, if no outside transformation was requested +// return true; +// } +// +// Signature *sig = dynamic_cast(&s); +// if (sig) { +// for (hashtable::const_iterator i = sig->decls.begin(); i != sig->decls.end(); ++i) { +// Fn_Decl *algfct = (*i).second; +// std::cerr << (*i).first << "\n"; +// for (std::list::const_iterator t = algfct->types.begin(); t != algfct->types.end(); ++t) { +// std::cerr << " " << (*t)->getType() << (algfct->return_type == *t) << "\n"; +// } +// } +// } + + return true; +} From 4d88388fa1a50af0af59e7320a26ba7b2732a9a9 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 8 Mar 2023 13:43:04 +0100 Subject: [PATCH 011/189] new semantic check for mixed types --- src/ast.cc | 4 + src/instance.hh | 9 ++ src/outside/grammar_transformation.cc | 117 ++++++++++++++++++--- testdata/modtest/outside_checksemantics.cc | 32 +++++- 4 files changed, 141 insertions(+), 21 deletions(-) diff --git a/src/ast.cc b/src/ast.cc index 44fb7506d..e06354f38 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -149,6 +149,10 @@ bool AST::check_instances(Instance *instance) { bool b = i->second->init(instance); r = r && b; } + + bool b = instance->check_multiple_answer_types(this->outside_generation()); + r = r && b; + return r; } diff --git a/src/instance.hh b/src/instance.hh index 49de6587a..229dacbf7 100644 --- a/src/instance.hh +++ b/src/instance.hh @@ -84,6 +84,15 @@ class Instance { bool replace_classified_product(); void check_alphabets(); + + /* when outside generation is requested, grammar is modified, but not the + * algebra(s), nor the algebra functions. If you use e.g. + * 'typeA afct(BASE, typeB);' in your signature and somewhere in your + * inside grammar, the outside grammar will contain + * 'typeB = afct(BASE; typeA)' which is not defined. + * Thus, we need to make sure that the user does not request outside with + * instances that use a signature with multiple answer types */ + bool check_multiple_answer_types(bool for_outside_generation); }; inline std::ostream &operator<<(std::ostream &s, const Instance &i) { diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index ebaee537f..5379c5a9c 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -24,11 +24,15 @@ #include #include #include +#include #include "grammar_transformation.hh" #include "../signature.hh" +#include "../instance.hh" #include "../grammar.hh" #include "../ast.hh" +#include "../fn_def.hh" +#include "../visitor.hh" bool Grammar::check_outside_parse_empty_word() { if (this->ast.outside_generation()) { @@ -100,22 +104,101 @@ void Grammar::check_outside_requested_nonexisting_nts() { } } -bool Grammar::check_multiple_answer_types(Signature_Base &s) { -// if (!this->ast.outside_generation()) { -// // no need to check, if no outside transformation was requested -// return true; -// } -// -// Signature *sig = dynamic_cast(&s); -// if (sig) { -// for (hashtable::const_iterator i = sig->decls.begin(); i != sig->decls.end(); ++i) { -// Fn_Decl *algfct = (*i).second; -// std::cerr << (*i).first << "\n"; -// for (std::list::const_iterator t = algfct->types.begin(); t != algfct->types.end(); ++t) { -// std::cerr << " " << (*t)->getType() << (algfct->return_type == *t) << "\n"; -// } -// } -// } +// traverses the grammar and collect all algebra function names used +// such that after traversal, we can ask if an algebra function, +// given its name, is actually part of the grammar +struct AlgfctUsedInGrammar : public Visitor { + private: + std::set used_algfct; + bool is_traversed = false; + + public: + void visit(Alt::Base &a) { + Alt::Simple *as = dynamic_cast(&a); + if (as) { + used_algfct.insert(*as->name); + } + is_traversed = true; + } - return true; + bool is_used(std::string *algfct_name) { + assert(is_traversed); + return used_algfct.find(*algfct_name) != used_algfct.end(); + } +}; + +bool Instance::check_multiple_answer_types(bool for_outside_generation) { + if (!for_outside_generation) { + // no need to check, if no outside transformation was requested + return true; + } + + AlgfctUsedInGrammar v = AlgfctUsedInGrammar(); + this->grammar_->traverse(v); + + // identify individual algebras used in the algebra product of the instance + unsigned int num_errors = 0; + for (Product::iterator i = Product::begin(this->product); i != Product::end(); + ++i) { + if ((*i)->is(Product::SINGLE)) { + Algebra *alg = dynamic_cast(*i)->algebra(); + for (hashtable::const_iterator i = alg->fns.begin(); + i != alg->fns.end(); ++i) { + Fn_Decl *algfct = (*i).second; + + // do not check choice functions + if (algfct->is_Choice_Fn()) { + continue; + } + + // ignore algebra function if not used in instance' grammar, i.e. + // it might be declared in signature and algebra(s) but not used + // in grammar definition + if (!v.is_used(algfct->name)) { + continue; + } + + // only check algebra functions whose return type is NOT a terminal + // (type) + if (!algfct->return_type->is_terminal()) { + for (std::list::const_iterator t = algfct->types.begin(); + t != algfct->types.end(); ++t) { + // only check rhs components that are not terminal (types) + // TODO(sjanssen) pkiss algfct does contain Subsequence, + // but these are not flagges as terminals?! + if ((!(*t)->is_terminal()) && (!(*t)->simple()->is(Type::SUBSEQ))) { + // check if return type is NOT equal to non-terminal types on the + // rhs + if (!algfct->return_type->simple()->is_eq(*(*t)->simple())) { + std::ostringstream msg; + msg << "return type '" + << *algfct->return_type + << "' is different to the type '" + << *(*t) + << "',\nwhich you are using on the r.h.s. of the function " + << "definition '" + << *(algfct->name) + << "' in algebra '" + << *(alg->name) + << "'.\nThis will lead to a compile error, since" + << " you requested outside grammar generation.\nThe outside" + << " grammar parts will contain production rules where " + << "l.h.s. and r.h.s. non-termials of '" + (*(algfct->name)) + << + "' are swapped,\nbut we lack definitions for these " + << "swapped versions in your algebras!"; + Log::instance()->error(alg->location, "type mismatch"); + Log::instance()->error((*t)->location, msg.str()); + num_errors++; + + // one warning per algebra function should be enough + break; + } + } + } + } + } + } + } + + return num_errors == 0; } diff --git a/testdata/modtest/outside_checksemantics.cc b/testdata/modtest/outside_checksemantics.cc index a7894a0cc..9cc06269e 100644 --- a/testdata/modtest/outside_checksemantics.cc +++ b/testdata/modtest/outside_checksemantics.cc @@ -1,11 +1,13 @@ -#include "../../src/driver.hh" -#include "../../src/log.hh" - #include #include #include #include +#include "../../src/driver.hh" +#include "../../src/log.hh" +#include "../../src/instance.hh" + + int main(int argc, char **argv) { std::ostringstream o; Log log; @@ -43,14 +45,36 @@ int main(int argc, char **argv) { // that links the grammar graph together, and computes yield-sizes. // If the method returns false, there are some semantic errors, // which leads to the end of the compilation process. - bool r; + bool r = true; try { r = grammar->check_semantic(); } catch (std::exception const &exc) { std::cerr << exc.what(); + return 0; } if (!r) { return 1; } + + grammar->approx_table_conf(); + + // find what type of input is read + // chars, sequence of ints etc. + driver.ast.derive_temp_alphabet(); + + r = driver.ast.check_signature(); + r = driver.ast.check_algebras(); + driver.ast.derive_roles(); + + std::string instname = ""; + if (grammar->name->compare("pknotsRG") == 0) { + instname = "mfeppenf"; + } + Instance *instance = driver.ast.instance(instname); + try { + r = driver.ast.check_instances(instance); + } catch (std::exception const &exc) { + std::cerr << exc.what(); + } } From b72ea45315750ab2e04ed40fbd175b3884a346ce Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 8 Mar 2023 14:53:31 +0100 Subject: [PATCH 012/189] fct to check for being terminal or not --- src/outside/grammar_transformation.cc | 59 ++++++++++++++++++++------- src/outside/grammar_transformation.hh | 17 ++++++++ 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 5379c5a9c..f2871cf05 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -21,18 +21,7 @@ }}} */ -#include -#include -#include -#include - #include "grammar_transformation.hh" -#include "../signature.hh" -#include "../instance.hh" -#include "../grammar.hh" -#include "../ast.hh" -#include "../fn_def.hh" -#include "../visitor.hh" bool Grammar::check_outside_parse_empty_word() { if (this->ast.outside_generation()) { @@ -127,6 +116,48 @@ struct AlgfctUsedInGrammar : public Visitor { } }; + +bool is_terminal_type(Type::Base *t) { + if ((t->is(Type::ALPHABET)) || (t->is(Type::VOID)) || + (t->is(Type::REALVOID)) || (t->is(Type::CHAR)) || + (t->is(Type::STRING)) || (t->is(Type::BOOL)) || (t->is(Type::SEQ)) || + (t->is(Type::SUBSEQ)) || (t->is(Type::INT)) || (t->is(Type::FLOAT)) || + (t->is(Type::RATIONAL))) { + return true; + } + if ((t->is(Type::BIGINT)) || (t->is(Type::SHAPE)) || (t->is(Type::INTEGER))) { + return false; + } + if ((t->is(Type::EXTERNAL)) || (t->is(Type::TUPLEDEF))) { + return false; + } + if (t->is(Type::USAGE)) { + return (t->is_terminal()) || (is_terminal_type(t->simple())); + } + if (t->is(Type::MULTI)) { + Type::Multi *tm = dynamic_cast(t); + for (std::list::const_iterator i = tm->types().begin(); + i != tm->types().end(); ++i) { + if (!is_terminal_type(*i)) { + return false; + } + } + return true; + } + if (t->is(Type::SINGLE)) { + return t->is_terminal(); + } + + /* TODO(sjanssen): I need to find out if following types are either terminals + * or not: Signature, Table, Base, List, Name, Tuple, Def, Choice, Size, + * Range, Table, Generic, Referencable + */ + assert(false && "I have been lazy and did not yet define if above mentioned" + " types are terminals or not"); + return false; +} + + bool Instance::check_multiple_answer_types(bool for_outside_generation) { if (!for_outside_generation) { // no need to check, if no outside transformation was requested @@ -160,13 +191,11 @@ bool Instance::check_multiple_answer_types(bool for_outside_generation) { // only check algebra functions whose return type is NOT a terminal // (type) - if (!algfct->return_type->is_terminal()) { + if (!is_terminal_type(algfct->return_type)) { for (std::list::const_iterator t = algfct->types.begin(); t != algfct->types.end(); ++t) { // only check rhs components that are not terminal (types) - // TODO(sjanssen) pkiss algfct does contain Subsequence, - // but these are not flagges as terminals?! - if ((!(*t)->is_terminal()) && (!(*t)->simple()->is(Type::SUBSEQ))) { + if (!is_terminal_type(*t)) { // check if return type is NOT equal to non-terminal types on the // rhs if (!algfct->return_type->simple()->is_eq(*(*t)->simple())) { diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh index b5d0886b1..e19ad4135 100644 --- a/src/outside/grammar_transformation.hh +++ b/src/outside/grammar_transformation.hh @@ -24,8 +24,25 @@ #ifndef SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ #define SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ +#include +#include +#include +#include + +#include "grammar_transformation.hh" +#include "../signature.hh" +#include "../instance.hh" +#include "../grammar.hh" +#include "../ast.hh" +#include "../fn_def.hh" +#include "../visitor.hh" +#include "../type/multi.hh" + static const char *OUTSIDE_NT_PREFIX = "outside_"; static const char *OUTSIDE_ALL = "ALL"; +// check if a type (used in Signature or Algebra) belongs to a terminal parser +// or a non-terminal parser +bool is_terminal_type(Type::Base*); #endif // SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ From af3ab1675be98ea4ab1d599b45985a69d4b21dd0 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 8 Mar 2023 15:13:03 +0100 Subject: [PATCH 013/189] logic bug --- src/outside/grammar_transformation.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index f2871cf05..5a22e74d0 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -132,7 +132,7 @@ bool is_terminal_type(Type::Base *t) { return false; } if (t->is(Type::USAGE)) { - return (t->is_terminal()) || (is_terminal_type(t->simple())); + return (t->is_terminal()) && (is_terminal_type(t->simple())); } if (t->is(Type::MULTI)) { Type::Multi *tm = dynamic_cast(t); From 47c3a4d857ae460f4ad4aae56ca16d6253f3d9c7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 10 Mar 2023 13:30:16 +0100 Subject: [PATCH 014/189] reactivate resolve_blocks test --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 76cae78e2..c7f64eefc 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ gapc: src/gapc.o $(MAIN_OBJ) src/version.o src/prefix.o stats \ test_rt_tab \ -multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics: src/version.o src/prefix.o +multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics outside_resolve_blocks: src/version.o src/prefix.o backtrack: src/version.o From 691ff7cfc57122709b8b2944a452f558ee0ecdc0 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 11 Mar 2023 19:37:46 +0100 Subject: [PATCH 015/189] add functionallity to resolve Alt::Blocks in given grammar --- src/alt.hh | 6 +- src/gapc.cc | 6 + src/grammar.hh | 5 + src/outside/grammar_transformation.cc | 187 ++++++++++++++++++++++++++ src/outside/grammar_transformation.hh | 11 ++ 5 files changed, 212 insertions(+), 3 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index 0d0408517..7b2e6c6f2 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -275,10 +275,10 @@ class Base { return m_ys; } - private: - std::vector > multi_filter; - public: + // analogous to filters, multi_filter should be public + // TODO(sjanssen): check if we really need to expose multi_filter + std::vector > multi_filter; void add_multitrack_filter( const std::list &l, Filter::Type t, const Loc &loc); virtual bool multi_detect_loop( diff --git a/src/gapc.cc b/src/gapc.cc index 46a091861..5c1ec7a09 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -52,6 +52,7 @@ #include "printer/cfg_pretty_print.hh" #include "printer/gap.hh" #include "specialize_grammar/create_specialized_grammar.hh" +#include "outside/grammar_transformation.hh" namespace po = boost::program_options; @@ -383,6 +384,11 @@ class Main { throw LogError("Seen semantic errors."); } + // transform inside grammar into an outside one, if user requests + if (driver.ast.outside_generation()) { + grammar->convert_to_outside(); + } + // configure the window and k-best mode driver.ast.set_window_mode(opts.window_mode); driver.ast.kbest = Bool(opts.kbest); diff --git a/src/grammar.hh b/src/grammar.hh index 840d81d61..d02b04a0e 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -217,6 +217,11 @@ class Grammar { * Throws an error if NTs are not present. */ void check_outside_requested_nonexisting_nts(); + + /* not yet complete: will inject additional production rules such that + * the given (inside-) grammar is turned into an outside grammar. + */ + void convert_to_outside(); }; diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 5a22e74d0..30f90a27e 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -231,3 +231,190 @@ bool Instance::check_multiple_answer_types(bool for_outside_generation) { return num_errors == 0; } + +/* iterates through one lhs NT and reports the first occurrence of an + * Alt::Block, i.e. + * - hold a pointer to the Alt::Block, + * - hold a pointer to the top level Alt::Base on the rhs of the NT that holds + * the Alt::Block + * - and either + * + a pointer to the Symbol::NT, if the Block is on the top level rhs + * + or a pointer to the Alt::Base which is the parent of the Alt::Block + * together with the a pointer to the "Handle" (= Fn_Arg::Alt) enclosing + * the Alt::Block */ +struct FindFirstBlock : public Visitor { + // pointer to the first found block + Alt::Block *block = nullptr; + + // pointer to the Fn_Arg::Alt that encloses the first found block - iff it's parent is an Alt::Base + Fn_Arg::Alt *block_fnarg = nullptr; + + // the top level alternative that contains (somewhere) the first found block + Alt::Base *topalt = nullptr; + + // the direct Alt::Base parent of the first found block - iff it is not a Symbol::NT + Alt::Base *parent_alt = nullptr; + + // the direct Symbol::NT parent of the first found block - iff it is not an Alt::Block + Symbol::NT *parent_nt = nullptr; + + FindFirstBlock() : block(nullptr), block_fnarg(nullptr), parent_alt(nullptr), parent_nt(nullptr) { + } + + void visit(Symbol::NT &nt) { + if (!block) { + parent_alt = nullptr; + block_fnarg = nullptr; + parent_nt = &nt; + } + } + void visit_itr(Symbol::NT &nt) { + if (!block) { + parent_alt = nullptr; + block_fnarg = nullptr; + parent_nt = &nt; + } + } + + void visit_begin(Alt::Simple &alt) { + if (!block) { + parent_alt = &alt; + parent_nt = nullptr; + if (alt.top_level) { + topalt = &alt; + } + } + } + void visit(Alt::Link &alt) { + // can only point to a rhs non-terminal + } + void visit_begin(Alt::Block &alt) { + if ((!block) && (alt.alts.size() > 0)) { + block = &alt; + if (alt.top_level) { + topalt = &alt; + } + } + } + void visit(Alt::Multi &alt) { + if (!block) { + parent_alt = &alt; + parent_nt = nullptr; + if (alt.top_level) { + topalt = &alt; + } + } + } + + void visit(Fn_Arg::Alt &arg) { + if (!block) { + block_fnarg = &arg; + } + } + + void visit(Grammar &g) { + throw LogError("Please only apply at individual NTs, not the full grammar!"); + } +}; + +void resolve_blocks(Symbol::NT *nt) { + if (nt) { + // check if there is any Alt::Block at the rhs of the NT + FindFirstBlock v_block = FindFirstBlock(); + nt->traverse(v_block); + + // iterate through all alternatives until no more Alt::Block can be found + while (v_block.block) { + std::list::iterator topalt = nt->alts.begin(); + for (; topalt != nt->alts.end(); ++topalt) { + if ((*topalt) == v_block.topalt) { + break; + } + } + + // Alt::Block can either occur within an algebra function like struct = cadd(foo, {joe, user}) + if (v_block.parent_alt && !v_block.parent_nt) { + if (v_block.parent_alt->is(Alt::SIMPLE)) { + // parent of the block is an Alt::Simple, i.e. has a list of children + for (std::list::iterator child = v_block.block->alts.begin(); child != v_block.block->alts.end(); ++child) { + // create a clone of the full alternative (up to the top level) that contains this block. This will invalidate all pointer information we have for the block ... + Alt::Base *clone = (*v_block.topalt).clone(); + + // ... thus acquire these info again, but for the clone, which is not yet part of any non-terminal + FindFirstBlock v_clone = FindFirstBlock(); + clone->traverse(v_clone); + + // now replace the block in the clone with the child of the original block + v_clone.block_fnarg->alt = *child; + + // carry over filters that are attached to the block, from the block to the child in the clone + v_clone.block_fnarg->alt->filters.insert(v_clone.block_fnarg->alt->filters.end(), + v_block.block->filters.begin(), + v_block.block->filters.end()); + v_clone.block_fnarg->alt->multi_filter.insert(v_clone.block_fnarg->alt->multi_filter.end(), + v_block.block->multi_filter.begin(), + v_block.block->multi_filter.end()); + + // insert new (partially, since it can still hold further Blocks) alternative into rhs of the NT + nt->alts.insert(topalt, clone); + } + // remove original top-alternative, which holds the found Alt::Block + nt->alts.remove(v_block.topalt); + } else if (v_block.parent_alt->is(Alt::LINK)) { + throw LogError("a Link is a leaf and thus cannot contain a block!"); + } else if (v_block.parent_alt->is(Alt::BLOCK)) { + throw LogError("parent block should have been removed already!"); + } else if (v_block.parent_alt->is(Alt::MULTI)) { + throw LogError("Alternative is not allowed in Multi-Track link."); + } else { + throw LogError("this is an unknown Alt subclass"); + } + + // or directly as a top level alternative of the non-termial, like struct = {joe, user} + } else if (!v_block.parent_alt && v_block.parent_nt) { + for (std::list::iterator child = v_block.block->alts.begin(); child != v_block.block->alts.end(); ++child) { + Alt::Base *clone = (*child)->clone(); + + // since parent is lhs non-terminal and block itself will be removed, + // children will become top level alternatives + clone->top_level = Bool(true); + + // don't forget to carry over filters ... + clone->filters.insert(clone->filters.end(), + v_block.block->filters.begin(), + v_block.block->filters.end()); + + // ... and filters for multitrack + clone->multi_filter.insert(clone->multi_filter.end(), + v_block.block->multi_filter.begin(), + v_block.block->multi_filter.end()); + + // insert new (partially, since it can still hold further Blocks) alternative into rhs of the NT + nt->alts.insert(topalt, clone); + } + + nt->alts.remove(*topalt); + } else { + throw LogError("each Alt::Block should have a parent!"); + } + + // check if there exist further Alt::Blocks, if not, we exit the while + // loop + v_block = FindFirstBlock(); + nt->traverse(v_block); + } + } +} + +void Grammar::convert_to_outside() { + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + if ((*i).second->is(Symbol::NONTERMINAL)) { + std::cerr << ((*i).first) << "\n"; + resolve_blocks(dynamic_cast((*i).second)); + } + } + + Log::instance()->verboseMessage( + "Grammar has been modified into an outside version."); +} diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh index e19ad4135..e3fa7d179 100644 --- a/src/outside/grammar_transformation.hh +++ b/src/outside/grammar_transformation.hh @@ -37,6 +37,7 @@ #include "../fn_def.hh" #include "../visitor.hh" #include "../type/multi.hh" +#include "../fn_arg.hh" static const char *OUTSIDE_NT_PREFIX = "outside_"; static const char *OUTSIDE_ALL = "ALL"; @@ -45,4 +46,14 @@ static const char *OUTSIDE_ALL = "ALL"; // or a non-terminal parser bool is_terminal_type(Type::Base*); +/* recursively resolve Alt::Blocks (which are short hand notations for + * alternative production rules) for a non-terminal. An example would be: + * struct = cadd(dangle, incl({struct | weak})) + * which shall be resolved into + * struct = cadd(dangle, incl(struct)) | cadd(dangle, incl(weak)) + * note that + * a) we do not know the "level" of the Alt::Block use + * b) we can have Alt::Block within Alt::Block */ +void resolve_blocks(Symbol::NT *nt); + #endif // SRC_OUTSIDE_GRAMMAR_TRANSFORMATION_HH_ From bc8d32d5cfaedf603002b3716bba9d7564ad8172 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 11 Mar 2023 19:41:41 +0100 Subject: [PATCH 016/189] linter --- src/outside/grammar_transformation.cc | 62 ++++++++++++++++++--------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 30f90a27e..30846eba2 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -246,19 +246,23 @@ struct FindFirstBlock : public Visitor { // pointer to the first found block Alt::Block *block = nullptr; - // pointer to the Fn_Arg::Alt that encloses the first found block - iff it's parent is an Alt::Base + // pointer to the Fn_Arg::Alt that encloses the first found block - iff it's + // parent is an Alt::Base Fn_Arg::Alt *block_fnarg = nullptr; // the top level alternative that contains (somewhere) the first found block Alt::Base *topalt = nullptr; - // the direct Alt::Base parent of the first found block - iff it is not a Symbol::NT + // the direct Alt::Base parent of the first found block - iff it is not a + // Symbol::NT Alt::Base *parent_alt = nullptr; - // the direct Symbol::NT parent of the first found block - iff it is not an Alt::Block + // the direct Symbol::NT parent of the first found block - iff it is not an + // Alt::Block Symbol::NT *parent_nt = nullptr; - FindFirstBlock() : block(nullptr), block_fnarg(nullptr), parent_alt(nullptr), parent_nt(nullptr) { + FindFirstBlock() : block(nullptr), block_fnarg(nullptr), parent_alt(nullptr), + parent_nt(nullptr) { } void visit(Symbol::NT &nt) { @@ -313,7 +317,8 @@ struct FindFirstBlock : public Visitor { } void visit(Grammar &g) { - throw LogError("Please only apply at individual NTs, not the full grammar!"); + throw LogError( + "Please only apply at individual NTs, not the full grammar!"); } }; @@ -332,30 +337,41 @@ void resolve_blocks(Symbol::NT *nt) { } } - // Alt::Block can either occur within an algebra function like struct = cadd(foo, {joe, user}) + // Alt::Block can either occur within an algebra function like + // struct = cadd(foo, {joe, user}) if (v_block.parent_alt && !v_block.parent_nt) { if (v_block.parent_alt->is(Alt::SIMPLE)) { // parent of the block is an Alt::Simple, i.e. has a list of children - for (std::list::iterator child = v_block.block->alts.begin(); child != v_block.block->alts.end(); ++child) { - // create a clone of the full alternative (up to the top level) that contains this block. This will invalidate all pointer information we have for the block ... + for (std::list::iterator child = + v_block.block->alts.begin(); + child != v_block.block->alts.end(); ++child) { + // create a clone of the full alternative (up to the top level) that + // contains this block. This will invalidate all pointer information + // we have for the block ... Alt::Base *clone = (*v_block.topalt).clone(); - // ... thus acquire these info again, but for the clone, which is not yet part of any non-terminal + // ... thus acquire these info again, but for the clone, which is + // not yet part of any non-terminal FindFirstBlock v_clone = FindFirstBlock(); clone->traverse(v_clone); - // now replace the block in the clone with the child of the original block + // now replace the block in the clone with the child of the original + // block v_clone.block_fnarg->alt = *child; - // carry over filters that are attached to the block, from the block to the child in the clone - v_clone.block_fnarg->alt->filters.insert(v_clone.block_fnarg->alt->filters.end(), - v_block.block->filters.begin(), - v_block.block->filters.end()); - v_clone.block_fnarg->alt->multi_filter.insert(v_clone.block_fnarg->alt->multi_filter.end(), - v_block.block->multi_filter.begin(), - v_block.block->multi_filter.end()); + // carry over filters that are attached to the block, from the block + // to the child in the clone + v_clone.block_fnarg->alt->filters.insert( + v_clone.block_fnarg->alt->filters.end(), + v_block.block->filters.begin(), + v_block.block->filters.end()); + v_clone.block_fnarg->alt->multi_filter.insert( + v_clone.block_fnarg->alt->multi_filter.end(), + v_block.block->multi_filter.begin(), + v_block.block->multi_filter.end()); - // insert new (partially, since it can still hold further Blocks) alternative into rhs of the NT + // insert new (partially, since it can still hold further Blocks) + // alternative into rhs of the NT nt->alts.insert(topalt, clone); } // remove original top-alternative, which holds the found Alt::Block @@ -370,9 +386,12 @@ void resolve_blocks(Symbol::NT *nt) { throw LogError("this is an unknown Alt subclass"); } - // or directly as a top level alternative of the non-termial, like struct = {joe, user} + // or directly as a top level alternative of the non-termial, + // like struct = {joe, user} } else if (!v_block.parent_alt && v_block.parent_nt) { - for (std::list::iterator child = v_block.block->alts.begin(); child != v_block.block->alts.end(); ++child) { + for (std::list::iterator child = + v_block.block->alts.begin(); + child != v_block.block->alts.end(); ++child) { Alt::Base *clone = (*child)->clone(); // since parent is lhs non-terminal and block itself will be removed, @@ -389,7 +408,8 @@ void resolve_blocks(Symbol::NT *nt) { v_block.block->multi_filter.begin(), v_block.block->multi_filter.end()); - // insert new (partially, since it can still hold further Blocks) alternative into rhs of the NT + // insert new (partially, since it can still hold further Blocks) + // alternative into rhs of the NT nt->alts.insert(topalt, clone); } From 24bfb4907a53acb768733d91c3109afeb4ae2700 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 11 Mar 2023 19:49:47 +0100 Subject: [PATCH 017/189] better name --- .github/workflows/outside.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/outside.yml b/.github/workflows/outside.yml index f3bda8fe9..8c36c4ff0 100644 --- a/.github/workflows/outside.yml +++ b/.github/workflows/outside.yml @@ -30,5 +30,5 @@ jobs: - name: configure run: ./configure --prefix $GITHUB_WORKSPACE - - name: test-mod + - name: test-mod_outside run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu From d82a8e883b93e92fe81cd545c2923ffd95b17a7f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 11 Mar 2023 19:50:03 +0100 Subject: [PATCH 018/189] add "resove blocks" test --- testdata/modtest/outside_resolve_blocks.cc | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 testdata/modtest/outside_resolve_blocks.cc diff --git a/testdata/modtest/outside_resolve_blocks.cc b/testdata/modtest/outside_resolve_blocks.cc new file mode 100644 index 000000000..650cfe976 --- /dev/null +++ b/testdata/modtest/outside_resolve_blocks.cc @@ -0,0 +1,91 @@ +// Copyright 2022 stefan.m.janssen@gmail.com + +#include +#include +#include +#include + +#include "../../src/driver.hh" +#include "../../src/log.hh" +#include "../../src/outside/grammar_transformation.hh" + +int main(int argc, char **argv) { + if (argc != 2) { + std::cerr << "Call " << *argv << " *.gap-file\n"; + return 1; + } + + std::ostringstream o; + Log log; + log.set_debug(false); + log.set_ostream(o); + + Driver driver; + + // === front + // set the file name of the gap-source-code + std::string filename(argv[1]); + driver.setFilename(filename); + + // parses the input file and builds the AST + driver.parse(); + if (driver.is_failing()) { + return 4; + } + + // simply gets the selected grammar, which is either the + // grammar that occurred first in the source code or is the + // one that was named in the parameters on the command line + Grammar *grammar = driver.ast.grammar(); + // Now check the semantic, which does more than the function + // name suggests. The semantic check is embedded in the algorithm + // that links the grammar graph together, and computes yield-sizes. + // If the method returns false, there are some semantic errors, + // which leads to the end of the compilation process. + bool r = grammar->check_semantic(); + if (!r) { + return 2; + } + + // replace Alt::Block from grammar rules with explicit + // alternatives + for (hashtable::iterator i = grammar->NTs.begin(); + i != grammar->NTs.end(); ++i) { + if ((*i).second->is(Symbol::NONTERMINAL)) { + resolve_blocks(dynamic_cast((*i).second)); + } + } + + // set approx table design + grammar->approx_table_conf(); + + // find what type of input is read + // chars, sequence of ints etc. + driver.ast.derive_temp_alphabet(); + + try { + r = driver.ast.check_signature(); + if (!r) { + return 3; + } + } catch (std::exception const &exc) { + return 9; + } + + // apply this to identify standard functions like Min, Max, Exp etc. + driver.ast.derive_roles(); + + + // ------------- back ------------ + grammar->init_list_sizes(); + + grammar->init_indices(); + grammar->init_decls(); + // for cyk (ordering of NT for parsing, see page 101 of the thesis) + grammar->dep_analysis(); + + unsigned int nodeID = 1; + grammar->to_dot(&nodeID, std::cout, 3); + + return 0; +} From c4d7c52ad5c83bab1b8bc372b60144b7caf4b1c6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 11 Mar 2023 20:53:17 +0100 Subject: [PATCH 019/189] added nil(EMPTY) back in --- testdata/grammar_outside/elmamun.gap | 1 + 1 file changed, 1 insertion(+) diff --git a/testdata/grammar_outside/elmamun.gap b/testdata/grammar_outside/elmamun.gap index e515dd27e..8bc7858b8 100644 --- a/testdata/grammar_outside/elmamun.gap +++ b/testdata/grammar_outside/elmamun.gap @@ -187,6 +187,7 @@ grammar gra_elmamun uses sig_elmamun(axiom = formula) { | add(formula, CHAR, formula) | mult(formula, CHAR('*'), formula) | heinz(formula, ROPE("manfred"), formula) + | nil(EMPTY) # h; } From e696d78543d47422062636f75ef41665acc14f8b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 11 Mar 2023 21:04:30 +0100 Subject: [PATCH 020/189] cleanup --- src/alt.hh | 1 - src/outside/grammar_transformation.cc | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/alt.hh b/src/alt.hh index 7b2e6c6f2..e3c310364 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -277,7 +277,6 @@ class Base { public: // analogous to filters, multi_filter should be public - // TODO(sjanssen): check if we really need to expose multi_filter std::vector > multi_filter; void add_multitrack_filter( const std::list &l, Filter::Type t, const Loc &loc); diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 30846eba2..3f90ba46c 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -330,6 +330,8 @@ void resolve_blocks(Symbol::NT *nt) { // iterate through all alternatives until no more Alt::Block can be found while (v_block.block) { + // determine the top level alternative in rhs of NT that holds the + // Alt::Block std::list::iterator topalt = nt->alts.begin(); for (; topalt != nt->alts.end(); ++topalt) { if ((*topalt) == v_block.topalt) { From f77dbff7ea3c951d3abefff9e743d0688586352e Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 12 Mar 2023 16:59:40 +0100 Subject: [PATCH 021/189] intermediate state --- src/alt.hh | 3 +- src/outside/grammar_transformation.cc | 91 ++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index e3c310364..4e53fc65b 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -266,7 +266,8 @@ class Base { public: void set_tracks(size_t t, size_t p); - protected: + // set to public, to allow transmission to outside pendants + public: Yield::Multi m_ys; public: diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 3f90ba46c..36c00f890 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -428,12 +428,97 @@ void resolve_blocks(Symbol::NT *nt) { } } +/* iterates through the rhs alternatives of an NT and creates a clone of an + * alternative where ONE (but not all) rhs NT is swapped with the lhs NT, e.g. + * struct = cadd(dangle, weak) | sadd(BASE, struct) will result in + * a) outside_dangle = cadd(outside_struct, weak) + * b) outside_weak = cadd(dangle, outside_struct) + * c) outside_struct = sadd(BASE, outside_struct) */ +struct Flip_lhs_rhs_nonterminals : public Visitor { + /* a list to store all newly generated clone alternatives. Each entry is a + * pair to save the new lhs non-terminal together with the modified rhs + * alternative */ + std::list > *alt_clones; + + // the inside lhs non terminal + Symbol::NT *lhs_nt; + + // the rhs top level alternative + Alt::Base *topalt = nullptr; + + Flip_lhs_rhs_nonterminals(Symbol::NT *nt) { + alt_clones = new std::list >(); + lhs_nt = nt->clone(nt->track_pos()); + lhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(lhs_nt->name)); + } + void visit(Alt::Base &alt) { + if (alt.top_level) { + topalt = &alt; + } + } + void visit_begin(Alt::Simple &alt) { + } + void visit(Alt::Link &alt) { + // skip links to terminal parser + if (alt.nt->is(Symbol::NONTERMINAL)) { + // copy of current rhs non-terminal name, which will be overwritten next + Symbol::NT *rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos()); + + alt.nt = lhs_nt; + alt.m_ys = lhs_nt->multi_ys(); + alt.name = lhs_nt->name; + + alt_clones->push_back(std::make_pair(std::string(OUTSIDE_NT_PREFIX + *(rhs_nt->name)), topalt->clone())); + + alt.nt = rhs_nt; + alt.m_ys = rhs_nt->multi_ys(); + alt.name = rhs_nt->name; + } + } + void visit_begin(Alt::Block &alt) { + } + void visit(Alt::Multi &alt) { + } +}; + void Grammar::convert_to_outside() { + unsigned int nodeID = 1; + for (hashtable::iterator i = NTs.begin(); - i != NTs.end(); ++i) { + i != NTs.end(); ++i) { if ((*i).second->is(Symbol::NONTERMINAL)) { - std::cerr << ((*i).first) << "\n"; - resolve_blocks(dynamic_cast((*i).second)); + Symbol::NT *nt_inside = dynamic_cast((*i).second); + +// std::cerr << *nt_inside->name << "\n"; + + // don't operate on the original inside non-terminal, but on a clone in which Alt::Block applications have been resolved + Symbol::NT *nt_inside_resolved = nt_inside->clone(nt_inside->track_pos()); + resolve_blocks(nt_inside_resolved); + + Flip_lhs_rhs_nonterminals v = Flip_lhs_rhs_nonterminals(nt_inside_resolved); + nt_inside_resolved->traverse(v); + + for (std::list >::iterator i = v.alt_clones->begin(); i != v.alt_clones->end(); ++i) { + (*i).second->to_dot(&nodeID, std::cerr, 1); +// std::string outside_nt_name = (*i).first; +// hashtable::iterator o = this->NTs.find(outside_nt_name); +// Symbol::NT *outside_nt; +// if (o == this->NTs.end()) { +// outside_nt = new Symbol::NT(&outside_nt_name, Loc()); +// this->NTs[outside_nt_name] = outside_nt; +// this->nt_list.push_back(outside_nt); +// } else { +// outside_nt = dynamic_cast((*o).second); +// } +// outside_nt->alts.push_back((*i).second); +// +//// this->NTs.insert(nt); +//// this->nt_list.push_back(nt_nt); +// +// Alt::Base *kalle = (*i).second; +// std::cerr << " produces: lhs=" << (*i).first << " -> " << (*i).second << "\n"; + } + } } From 31574fa042f98c2d7857d5549b13e6119bee9682 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 12 Mar 2023 19:01:11 +0100 Subject: [PATCH 022/189] intermediate: outside rules present, axiom missing, complete track missing --- src/outside/grammar_transformation.cc | 77 +++++++++++++++------------ src/symbol.cc | 8 ++- src/symbol.hh | 2 +- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 36c00f890..7dc9520f6 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -438,18 +438,21 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { /* a list to store all newly generated clone alternatives. Each entry is a * pair to save the new lhs non-terminal together with the modified rhs * alternative */ - std::list > *alt_clones; + std::list > *alt_clones; - // the inside lhs non terminal + // Symbol::NT *lhs_nt; // the rhs top level alternative Alt::Base *topalt = nullptr; Flip_lhs_rhs_nonterminals(Symbol::NT *nt) { - alt_clones = new std::list >(); - lhs_nt = nt->clone(nt->track_pos()); - lhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(lhs_nt->name)); + alt_clones = new std::list >(); + + lhs_nt = nt->clone(nt->track_pos(), true); + lhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(nt->name)); + lhs_nt->orig_name = lhs_nt->name; + lhs_nt->alts.clear(); } void visit(Alt::Base &alt) { if (alt.top_level) { @@ -461,18 +464,22 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { void visit(Alt::Link &alt) { // skip links to terminal parser if (alt.nt->is(Symbol::NONTERMINAL)) { - // copy of current rhs non-terminal name, which will be overwritten next - Symbol::NT *rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos()); + Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); + + Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); + outside_rhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(outside_rhs_nt->name)); + outside_rhs_nt->orig_name = outside_rhs_nt->name; + outside_rhs_nt->alts.clear(); alt.nt = lhs_nt; alt.m_ys = lhs_nt->multi_ys(); alt.name = lhs_nt->name; - alt_clones->push_back(std::make_pair(std::string(OUTSIDE_NT_PREFIX + *(rhs_nt->name)), topalt->clone())); + alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); - alt.nt = rhs_nt; - alt.m_ys = rhs_nt->multi_ys(); - alt.name = rhs_nt->name; + alt.nt = orig_rhs_nt; + alt.m_ys = orig_rhs_nt->multi_ys(); + alt.name = orig_rhs_nt->name; } } void visit_begin(Alt::Block &alt) { @@ -482,46 +489,46 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { }; void Grammar::convert_to_outside() { - unsigned int nodeID = 1; + hashtable outside_nts; for (hashtable::iterator i = NTs.begin(); i != NTs.end(); ++i) { if ((*i).second->is(Symbol::NONTERMINAL)) { Symbol::NT *nt_inside = dynamic_cast((*i).second); - -// std::cerr << *nt_inside->name << "\n"; + std::cerr << *nt_inside->name << ": "; // don't operate on the original inside non-terminal, but on a clone in which Alt::Block applications have been resolved - Symbol::NT *nt_inside_resolved = nt_inside->clone(nt_inside->track_pos()); + Symbol::NT *nt_inside_resolved = nt_inside->clone(nt_inside->track_pos(), true); resolve_blocks(nt_inside_resolved); Flip_lhs_rhs_nonterminals v = Flip_lhs_rhs_nonterminals(nt_inside_resolved); nt_inside_resolved->traverse(v); - for (std::list >::iterator i = v.alt_clones->begin(); i != v.alt_clones->end(); ++i) { - (*i).second->to_dot(&nodeID, std::cerr, 1); -// std::string outside_nt_name = (*i).first; -// hashtable::iterator o = this->NTs.find(outside_nt_name); -// Symbol::NT *outside_nt; -// if (o == this->NTs.end()) { -// outside_nt = new Symbol::NT(&outside_nt_name, Loc()); -// this->NTs[outside_nt_name] = outside_nt; -// this->nt_list.push_back(outside_nt); -// } else { -// outside_nt = dynamic_cast((*o).second); -// } -// outside_nt->alts.push_back((*i).second); -// -//// this->NTs.insert(nt); -//// this->nt_list.push_back(nt_nt); -// -// Alt::Base *kalle = (*i).second; -// std::cerr << " produces: lhs=" << (*i).first << " -> " << (*i).second << "\n"; - } + std::cerr << v.alt_clones->size() << "\n"; + // add new alternatives and new non-terminals to existing grammar + for (std::list >::iterator i = v.alt_clones->begin(); i != v.alt_clones->end(); ++i) { + std::string *nt_name = (*i).first->name; + hashtable::iterator it_nt = outside_nts.find(*nt_name); + if (it_nt == outside_nts.end()) { + outside_nts[*nt_name] = (*i).first; + } + it_nt = outside_nts.find(*nt_name); + dynamic_cast((*it_nt).second)->alts.push_back((*i).second); + } } } + // now add the new outside NTs to the grammar + for (hashtable::iterator i = outside_nts.begin(); + i != outside_nts.end(); ++i) { + this->NTs[(*i).first] = (*i).second; + this->nt_list.push_back(dynamic_cast((*i).second)); + } + Log::instance()->verboseMessage( "Grammar has been modified into an outside version."); + + unsigned int nodeID = 1; + this->to_dot(&nodeID, std::cerr, 1); } diff --git a/src/symbol.cc b/src/symbol.cc index ca9f52898..8ed3da4a9 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -1576,11 +1576,15 @@ void Symbol::NT::multi_init_calls() { } -Symbol::NT *Symbol::NT::clone(size_t track_pos) { +Symbol::NT *Symbol::NT::clone(size_t track_pos, bool keepname) { NT *nt = new NT(*this); std::ostringstream o; o << *orig_name << '_' << track_pos; - nt->name = new std::string(o.str()); + if (keepname) { + nt->name = this->name; + } else { + nt->name = new std::string(o.str()); + } nt->track_pos_ = track_pos; nt->alts.clear(); for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) diff --git a/src/symbol.hh b/src/symbol.hh index da0cd65cf..b8e94a045 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -354,7 +354,7 @@ class NT : public Base { NT(std::string *n, const Loc &l); - NT *clone(size_t track_pos); + NT *clone(size_t track_pos, bool keepname=false); void set_grammar_index(size_t i) { grammar_index_ = i; From 7f6918dadb694426de109cea0c27c52231a17f6a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 15:36:51 +0100 Subject: [PATCH 023/189] inject new axioms + transition to inside --- src/outside/grammar_transformation.cc | 145 ++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 10 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 7dc9520f6..b72b8d914 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -459,8 +459,6 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { topalt = &alt; } } - void visit_begin(Alt::Simple &alt) { - } void visit(Alt::Link &alt) { // skip links to terminal parser if (alt.nt->is(Symbol::NONTERMINAL)) { @@ -482,12 +480,113 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { alt.name = orig_rhs_nt->name; } } - void visit_begin(Alt::Block &alt) { + + void visit(Grammar &g) { + throw LogError( + "Please only apply at individual NTs, not the full grammar!"); } - void visit(Alt::Multi &alt) { + +}; + +struct Count_rhsNTs : public Visitor { + unsigned int rhs_nts; + + Count_rhsNTs() { + rhs_nts = 0; + } + + void visit(Alt::Link &alt) { + if (alt.nt->is(Symbol::NONTERMINAL)) { + rhs_nts++; + } } }; +void inject_outside_axiom(Grammar *grammar, hashtable outside_nts) { + /* inside production rules that have NO non-terminals on their right hand + * sides must be those that parse the final sub-words of the input. + * Therefore, they must be the smallest start-points for outside + * construction, i.e. the axiom should point to them. */ + std::set *axiom_candidates = new std::set(); + // check all alternatives, if they do NOT use any non-terminals on their rhs + // if so, the NT must become one of the outside axioms + for (hashtable::iterator i = grammar->NTs.begin(); + i != grammar->NTs.end(); ++i) { + if ((*i).second->is(Symbol::NONTERMINAL)) { + Symbol::NT *nt_inside = dynamic_cast((*i).second); + for (std::list::const_iterator a = nt_inside->alts.begin(); a != nt_inside->alts.end(); ++a) { + Count_rhsNTs v = Count_rhsNTs(); + (*a)->traverse(v); + if (v.rhs_nts == 0) { + std::string he = std::string(OUTSIDE_NT_PREFIX + *nt_inside->name); + hashtable::iterator it_outside_nt = outside_nts.find(he); + if (it_outside_nt != outside_nts.end()) { + axiom_candidates->insert(dynamic_cast((*it_outside_nt).second)); + } + } + } + } + } + + if (axiom_candidates->size() == 1) { + // if there is only one candidate NT, we simple make this NT the new axiom + grammar->axiom_name = (*axiom_candidates->begin())->name; + } else if (axiom_candidates->size() > 1) { + // it is more complicated if there are several NTs + // we then need to create a novel lhs NT ... + //std::string *axiom_name = new std::string(*OUTSIDE_NT_PREFIX + "_axioms"); + std::string *axiom_name = new std::string(OUTSIDE_NT_PREFIX + std::string("axioms")); + hashtable::iterator it_ntclash = grammar->NTs.find(*axiom_name); + if (it_ntclash != grammar->NTs.end()) { + throw LogError((*it_ntclash).second->location, "Please avoid using '" + *axiom_name + "' as l.h.s. non-terminal name, when requesting outside grammar generation!"); + } + Symbol::NT *nt_axiom = new Symbol::NT(axiom_name, Loc()); + nt_axiom->name = axiom_name; + nt_axiom->orig_name = axiom_name; + + // TODO can't I clone inside NT? + // carry over tracks from original inside axiom + nt_axiom->set_tracks(grammar->axiom->tracks(), grammar->axiom->track_pos()); + nt_axiom->setup_multi_ys(); + + for (std::set::iterator i = axiom_candidates->begin(); + i != axiom_candidates->end(); ++i) { + Alt::Link *link = new Alt::Link((*i)->name, Loc()); + link->nt = *i; + link->set_tracks((*i)->tracks(), (*i)->track_pos()); + link->init_multi_ys(); + nt_axiom->alts.push_back(link); + } + // add new lhs non-terminal to grammar + grammar->add_nt(nt_axiom); + + grammar->axiom_name = axiom_name; + + } + grammar->init_axiom(); +} + +void inject_outside_inside_transition(Grammar *grammar, Symbol::NT* target) { + Alt::Link *link = new Alt::Link(grammar->axiom_name, grammar->axiom_loc); + link->nt = dynamic_cast(grammar->axiom); + Filter *f = new Filter(new std::string("complete_track"), Loc()); + f->type = Filter::WITH; + std::list *comptracks = new std::list(); + for (unsigned int track = 0; track < grammar->axiom->tracks(); ++track) { + comptracks->push_back(f); + } + link->set_tracks(grammar->axiom->tracks(), grammar->axiom->track_pos()); + link->init_multi_ys(); +// link->is_outside_inside_transition = true; + if (link->nt->tracks() == 1) { + link->filters.push_back(f); + } else { + link->add_multitrack_filter(*comptracks, f->type, Loc()); + } + link->top_level = Bool(true); + target->alts.push_back(link); +} + void Grammar::convert_to_outside() { hashtable outside_nts; @@ -495,7 +594,6 @@ void Grammar::convert_to_outside() { i != NTs.end(); ++i) { if ((*i).second->is(Symbol::NONTERMINAL)) { Symbol::NT *nt_inside = dynamic_cast((*i).second); - std::cerr << *nt_inside->name << ": "; // don't operate on the original inside non-terminal, but on a clone in which Alt::Block applications have been resolved Symbol::NT *nt_inside_resolved = nt_inside->clone(nt_inside->track_pos(), true); @@ -504,7 +602,6 @@ void Grammar::convert_to_outside() { Flip_lhs_rhs_nonterminals v = Flip_lhs_rhs_nonterminals(nt_inside_resolved); nt_inside_resolved->traverse(v); - std::cerr << v.alt_clones->size() << "\n"; // add new alternatives and new non-terminals to existing grammar for (std::list >::iterator i = v.alt_clones->begin(); i != v.alt_clones->end(); ++i) { std::string *nt_name = (*i).first->name; @@ -522,13 +619,41 @@ void Grammar::convert_to_outside() { // now add the new outside NTs to the grammar for (hashtable::iterator i = outside_nts.begin(); i != outside_nts.end(); ++i) { - this->NTs[(*i).first] = (*i).second; - this->nt_list.push_back(dynamic_cast((*i).second)); + this->add_nt(dynamic_cast((*i).second)); } + // inject one alternative to the inside axiom which enables the transition + // from outside parts into the original inside part of the grammar + inject_outside_inside_transition(this, dynamic_cast((*outside_nts.find(std::string(OUTSIDE_NT_PREFIX + *this->axiom_name))).second)); + + // inject new outside axiom + inject_outside_axiom(this, outside_nts); + + /* NT-table dimension optimization (all start quadratic, but depending on + * yield size, some NT-tables can be reduced to linear or even constant + * "tables") must be re-considered, since original inside NTs will now + * be called from outside NTs and former constant tables (e.g. consuming + * the full input) might now be within a variable infix size and thus + * must become quadratic again. + * We therefore here reset the flag of all NTs to enable re-computation + * of optimal table dimensions ... within the outside context. + */ + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + if ((*i).second->is(Symbol::NONTERMINAL)) { + dynamic_cast((*i).second)->reset_table_dim(); + } + } + + /* re-run "check_semantics" to properly initialize novel non- + * terminals, links to non-terminals, update yield size analysis and + * update table dimensions for NTs + */ + this->check_semantic(); + Log::instance()->verboseMessage( "Grammar has been modified into an outside version."); - unsigned int nodeID = 1; - this->to_dot(&nodeID, std::cerr, 1); +// unsigned int nodeID = 1; +// this->to_dot(&nodeID, std::cerr, 1); } From 7a214b9b224dfbcad4bec936cb034374b6460bba Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 15:37:08 +0100 Subject: [PATCH 024/189] allow table_dim re-computation --- src/symbol.hh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/symbol.hh b/src/symbol.hh index b8e94a045..4daf76fdc 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -339,6 +339,12 @@ class NT : public Base { std::list alts; void set_alts(const std::list &a); + // This flags the table dimension computation as invalid. + // Used for outside grammar generation, as table dimensions + // have to be re-computed after outside NTs were injected + void reset_table_dim() { + this->tab_dim_ready = false; + } public: std::string *eval_fn; From 37c8a399ac05a795ad187f6b532f5c72cd575afd Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 15:41:41 +0100 Subject: [PATCH 025/189] add modtest: complete grammar transformation --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c7f64eefc..c8c36addd 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,6 @@ CXXFILES = $(wildcard src/*.cc) \ $(wildcard src/util/*.cc) \ $(wildcard src/printer/*.cc) \ $(wildcard src/specialize_grammar/*.cc) \ - $(wildcard src/outside/*.cc) \ $(UNITTEST_CXX) \ $(MODTESTS_CXX) \ $(wildcard testdata/test/*.cc) \ @@ -129,7 +128,7 @@ gapc: src/gapc.o $(MAIN_OBJ) src/version.o src/prefix.o stats \ test_rt_tab \ -multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics outside_resolve_blocks: src/version.o src/prefix.o +multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys multi_print_grammar outside_resolve_blocks outside_grammar outside_indices parser: src/version.o src/prefix.o backtrack: src/version.o From 6661689584edd5a01c228dab63cd563bc8ec26ad Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 15:45:40 +0100 Subject: [PATCH 026/189] use correct version --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c8c36addd..5a8f35b3c 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ CXXFILES = $(wildcard src/*.cc) \ $(wildcard src/util/*.cc) \ $(wildcard src/printer/*.cc) \ $(wildcard src/specialize_grammar/*.cc) \ + $(wildcard src/outside/*.cc) \ $(UNITTEST_CXX) \ $(MODTESTS_CXX) \ $(wildcard testdata/test/*.cc) \ @@ -128,7 +129,7 @@ gapc: src/gapc.o $(MAIN_OBJ) src/version.o src/prefix.o stats \ test_rt_tab \ -multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys multi_print_grammar outside_resolve_blocks outside_grammar outside_indices parser: src/version.o src/prefix.o +multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics outside_resolve_blocks outside_grammar: src/version.o src/prefix.o backtrack: src/version.o From aa36abd46371fed70375df06e9d380906e6db90c Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 15:46:28 +0100 Subject: [PATCH 027/189] add new test that checks for grammar topology --- testdata/modtest/outside_grammar.cc | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 testdata/modtest/outside_grammar.cc diff --git a/testdata/modtest/outside_grammar.cc b/testdata/modtest/outside_grammar.cc new file mode 100644 index 000000000..1377148e5 --- /dev/null +++ b/testdata/modtest/outside_grammar.cc @@ -0,0 +1,71 @@ +#include "../../src/driver.hh" +#include "../../src/log.hh" + +#include +#include +#include +#include + +int main(int argc, char **argv) { + std::ostringstream o; + Log log; + log.set_debug(false); + log.set_ostream(o); + + Driver driver; + + if (argc != 2) { + std::cerr << "Call " << *argv << " *.gap-file\n"; + return 1; + } + // === front + // set the file name of the gap-source-code + driver.setFilename(argv[1]); + + // parses the input file and builds the AST + driver.parse(); + + // simply gets the selected grammar, which is either the + // grammar that occurred first in the source code or is the + // one that was named in the parameters on the command line + Grammar *grammar = driver.ast.grammar(); + // Now check the semantic, which does more than the function + // name suggests. The semantic check is embedded in the algorithm + // that links the grammar graph together, and computes yield-sizes. + // If the method returns false, there are some semantic errors, + // which leads to the end of the compilation process. + bool r = grammar->check_semantic(); + if (!r) { + throw LogError("Seen semantic errors."); + } + +// // inject rules for outside grammar +// grammar->inject_outside_nts(); + +// // set approx table design +// grammar->approx_table_conf(); +// +// // find what type of input is read +// // chars, sequence of ints etc. +// driver.ast.derive_temp_alphabet(); +// +// r = driver.ast.check_signature(); +// if (!r) { +// return 4; +// } +// +// // apply this to identify standard functions like Min, Max, Exp etc. +// driver.ast.derive_roles(); +// +// +// // ------------- back ------------ +// grammar->init_list_sizes(); +// +// grammar->init_indices(); +// grammar->init_decls(); +// // for cyk (ordering of NT for parsing, see page 101 of the thesis) +// grammar->dep_analysis(); + + unsigned int nodeID = 1; + grammar->to_dot(&nodeID, std::cout, 1); +} From 5f8a6ce4af2ab1ffb732cb2b7804256ac40121e6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 16:15:43 +0100 Subject: [PATCH 028/189] Visitor: add a visit at the end of traversing a grammar --- src/grammar.cc | 1 + src/visitor.cc | 2 ++ src/visitor.hh | 3 +++ 3 files changed, 6 insertions(+) diff --git a/src/grammar.cc b/src/grammar.cc index 8da76ecee..3a1fa0546 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -845,6 +845,7 @@ void Grammar::traverse(Visitor &v) { i != NTs.end(); ++i) { i->second->traverse(v); } + v.visit_end(*this); } diff --git a/src/visitor.cc b/src/visitor.cc index 97a771091..ce5cd3ef9 100644 --- a/src/visitor.cc +++ b/src/visitor.cc @@ -47,3 +47,5 @@ void Visitor::visit_end(Alt::Multi &a) {} void Visitor::visit(Fn_Arg::Base &f) {} void Visitor::visit(Fn_Arg::Const &f) {} void Visitor::visit(Fn_Arg::Alt &f) {} + +void Visitor::visit_end(Grammar &g) {} diff --git a/src/visitor.hh b/src/visitor.hh index 08a75038e..828d2718d 100644 --- a/src/visitor.hh +++ b/src/visitor.hh @@ -28,6 +28,7 @@ #include "symbol_fwd.hh" #include "alt_fwd.hh" #include "fn_arg_fwd.hh" +#include "grammar.hh" class Visitor { public: @@ -56,6 +57,8 @@ class Visitor { virtual void visit(Fn_Arg::Const &f); virtual void visit(Fn_Arg::Alt &f); + + virtual void visit_end(Grammar &g); }; #endif // SRC_VISITOR_HH_ From 640bef3ad5fe76b457d95dfeb97c287d4c30c3de Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 13 Mar 2023 16:16:08 +0100 Subject: [PATCH 029/189] refactor --- src/outside/grammar_transformation.cc | 115 +++++++++++++++++++++----- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index b72b8d914..2cd923c66 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -440,41 +440,63 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { * alternative */ std::list > *alt_clones; - // + // a clone of the original inside lhs NT Symbol::NT *lhs_nt; // the rhs top level alternative Alt::Base *topalt = nullptr; Flip_lhs_rhs_nonterminals(Symbol::NT *nt) { + // initialize the for now empty list of flipped alternative production rules alt_clones = new std::list >(); + // clone the given inside lhs NT lhs_nt = nt->clone(nt->track_pos(), true); + // and prefix it's name with "outside_" lhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(nt->name)); lhs_nt->orig_name = lhs_nt->name; + // remove all alternatives lhs_nt->alts.clear(); } void visit(Alt::Base &alt) { if (alt.top_level) { + // record the current top level alternative. Starting point for cloning topalt = &alt; } } void visit(Alt::Link &alt) { // skip links to terminal parser if (alt.nt->is(Symbol::NONTERMINAL)) { + /* a bit hacky: we need to create exact copies of the inside alternative + * production rule, but if we clone all components will have different + * pointers as they are different objects. Thus, we + * a) safely store the original rhs NT (orig_rhs_nt) away + * b) create a second clone of the rhs NT, but prefix its name with + * "outside_" and remove all alternatives + * c) next, we overwrite the current rhs NT of the Alt::Link with the + * lhs NT (which was already prefixed with "outside_") + * d) NOW clone the modified production rule + * e) restore the state before cloning of the inside production rule + */ + + // a) Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); + // b) Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); outside_rhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(outside_rhs_nt->name)); outside_rhs_nt->orig_name = outside_rhs_nt->name; outside_rhs_nt->alts.clear(); + // c) alt.nt = lhs_nt; alt.m_ys = lhs_nt->multi_ys(); alt.name = lhs_nt->name; + // d) alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); + // e) alt.nt = orig_rhs_nt; alt.m_ys = orig_rhs_nt->multi_ys(); alt.name = orig_rhs_nt->name; @@ -485,14 +507,16 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { throw LogError( "Please only apply at individual NTs, not the full grammar!"); } - }; struct Count_rhsNTs : public Visitor { - unsigned int rhs_nts; + unsigned int rhs_nts = 0; + + std::set *axiom_candidates; + hashtable outside_nts; - Count_rhsNTs() { - rhs_nts = 0; + Count_rhsNTs(hashtable outside_nts) : outside_nts(outside_nts) { + axiom_candidates = new std::set(); } void visit(Alt::Link &alt) { @@ -500,6 +524,55 @@ struct Count_rhsNTs : public Visitor { rhs_nts++; } } + + void visit_itr(Symbol::NT &nt) { + if (rhs_nts == 0) { + hashtable::iterator it_outside_nt = outside_nts.find(std::string(OUTSIDE_NT_PREFIX + *nt.name)); + if (it_outside_nt != outside_nts.end()) { + axiom_candidates->insert(dynamic_cast((*it_outside_nt).second)); + } + } + rhs_nts = 0; // for next iteration + } + + void visit_end(Grammar &g) { + if (axiom_candidates->size() == 1) { + // if there is only one candidate NT, we simple make this NT the new axiom + g.axiom_name = (*axiom_candidates->begin())->name; + } else if (axiom_candidates->size() > 1) { + // it is more complicated if there are several NTs + // we then need to create a novel lhs NT ... + //std::string *axiom_name = new std::string(*OUTSIDE_NT_PREFIX + "_axioms"); + std::string *axiom_name = new std::string(OUTSIDE_NT_PREFIX + std::string("axioms")); + hashtable::iterator it_ntclash = g.NTs.find(*axiom_name); + if (it_ntclash != g.NTs.end()) { + throw LogError((*it_ntclash).second->location, "Please avoid using '" + *axiom_name + "' as l.h.s. non-terminal name, when requesting outside grammar generation!"); + } + Symbol::NT *nt_axiom = new Symbol::NT(axiom_name, Loc()); + nt_axiom->name = axiom_name; + nt_axiom->orig_name = axiom_name; + + // TODO can't I clone inside NT? + // carry over tracks from original inside axiom + nt_axiom->set_tracks(g.axiom->tracks(), g.axiom->track_pos()); + nt_axiom->setup_multi_ys(); + + for (std::set::iterator i = axiom_candidates->begin(); + i != axiom_candidates->end(); ++i) { + Alt::Link *link = new Alt::Link((*i)->name, Loc()); + link->nt = *i; + link->set_tracks((*i)->tracks(), (*i)->track_pos()); + link->init_multi_ys(); + nt_axiom->alts.push_back(link); + } + // add new lhs non-terminal to grammar + g.add_nt(nt_axiom); + + g.axiom_name = axiom_name; + + } + g.init_axiom(); + } }; void inject_outside_axiom(Grammar *grammar, hashtable outside_nts) { @@ -515,7 +588,7 @@ void inject_outside_axiom(Grammar *grammar, hashtableis(Symbol::NONTERMINAL)) { Symbol::NT *nt_inside = dynamic_cast((*i).second); for (std::list::const_iterator a = nt_inside->alts.begin(); a != nt_inside->alts.end(); ++a) { - Count_rhsNTs v = Count_rhsNTs(); + Count_rhsNTs v = Count_rhsNTs(outside_nts); (*a)->traverse(v); if (v.rhs_nts == 0) { std::string he = std::string(OUTSIDE_NT_PREFIX + *nt_inside->name); @@ -626,8 +699,10 @@ void Grammar::convert_to_outside() { // from outside parts into the original inside part of the grammar inject_outside_inside_transition(this, dynamic_cast((*outside_nts.find(std::string(OUTSIDE_NT_PREFIX + *this->axiom_name))).second)); - // inject new outside axiom - inject_outside_axiom(this, outside_nts); + Count_rhsNTs v = Count_rhsNTs(outside_nts); + this->traverse(v); +// // inject new outside axiom +// inject_outside_axiom(this, outside_nts); /* NT-table dimension optimization (all start quadratic, but depending on * yield size, some NT-tables can be reduced to linear or even constant @@ -638,18 +713,18 @@ void Grammar::convert_to_outside() { * We therefore here reset the flag of all NTs to enable re-computation * of optimal table dimensions ... within the outside context. */ - for (hashtable::iterator i = NTs.begin(); - i != NTs.end(); ++i) { - if ((*i).second->is(Symbol::NONTERMINAL)) { - dynamic_cast((*i).second)->reset_table_dim(); - } - } - - /* re-run "check_semantics" to properly initialize novel non- - * terminals, links to non-terminals, update yield size analysis and - * update table dimensions for NTs - */ - this->check_semantic(); +// for (hashtable::iterator i = NTs.begin(); +// i != NTs.end(); ++i) { +// if ((*i).second->is(Symbol::NONTERMINAL)) { +// dynamic_cast((*i).second)->reset_table_dim(); +// } +// } +// +// /* re-run "check_semantics" to properly initialize novel non- +// * terminals, links to non-terminals, update yield size analysis and +// * update table dimensions for NTs +// */ +// this->check_semantic(); Log::instance()->verboseMessage( "Grammar has been modified into an outside version."); From e138ac2da04a1856a142cb8716fbe858e1c0e803 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 14 Mar 2023 12:05:28 +0100 Subject: [PATCH 030/189] use new function name --- testdata/modtest/outside_grammar.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testdata/modtest/outside_grammar.cc b/testdata/modtest/outside_grammar.cc index 1377148e5..9131b259b 100644 --- a/testdata/modtest/outside_grammar.cc +++ b/testdata/modtest/outside_grammar.cc @@ -39,8 +39,8 @@ int main(int argc, char **argv) { throw LogError("Seen semantic errors."); } -// // inject rules for outside grammar -// grammar->inject_outside_nts(); + // inject rules for outside grammar + grammar->convert_to_outside(); // // set approx table design // grammar->approx_table_conf(); From cf1538014f3a3d231bd93ffe2553aaf3b6a6b8c4 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 14 Mar 2023 12:05:45 +0100 Subject: [PATCH 031/189] WIP --- src/outside/grammar_transformation.cc | 160 ++++++++++++++++++-------- 1 file changed, 111 insertions(+), 49 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 2cd923c66..fc8276bdd 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -428,6 +428,30 @@ void resolve_blocks(Symbol::NT *nt) { } } +/* Counts the number of rhs non-terminals and algebra functions, e.g. + * hairpin = hl(BASE, REGION, BASE) : increase by 1 due to hl + * plus = CHAR('+') : no increase since only terminal used on rhs + * weak = hairpin | bulgeL : increase by 2 due to 2 non-terminals + */ +struct Count_rhsNTs : public Visitor { + unsigned int rhs_nts = 0; + + Count_rhsNTs() { + rhs_nts = 0; + } + + void visit_begin(Alt::Simple &alt) { + if (!alt.is_terminal()) { + rhs_nts++; + } + } + void visit(Alt::Link &alt) { + if (alt.nt->is(Symbol::NONTERMINAL)) { + rhs_nts++; + } + } +}; + /* iterates through the rhs alternatives of an NT and creates a clone of an * alternative where ONE (but not all) rhs NT is swapped with the lhs NT, e.g. * struct = cadd(dangle, weak) | sadd(BASE, struct) will result in @@ -467,39 +491,52 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { void visit(Alt::Link &alt) { // skip links to terminal parser if (alt.nt->is(Symbol::NONTERMINAL)) { - /* a bit hacky: we need to create exact copies of the inside alternative - * production rule, but if we clone all components will have different - * pointers as they are different objects. Thus, we - * a) safely store the original rhs NT (orig_rhs_nt) away - * b) create a second clone of the rhs NT, but prefix its name with - * "outside_" and remove all alternatives - * c) next, we overwrite the current rhs NT of the Alt::Link with the - * lhs NT (which was already prefixed with "outside_") - * d) NOW clone the modified production rule - * e) restore the state before cloning of the inside production rule + /* grammar might contain "alias" non-terminals that only point to + * terminals like: + * plus = CHAR('+') + * if the link points to such an "alias" non-terminal, we need to treat it + * as if it is a terminal, i.e. skip it for producing outside alternatives + * We therefore here count the number of used non-terminal and algebra + * functions in the linked non-terminal */ - - // a) - Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); - - // b) - Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); - outside_rhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(outside_rhs_nt->name)); - outside_rhs_nt->orig_name = outside_rhs_nt->name; - outside_rhs_nt->alts.clear(); - - // c) - alt.nt = lhs_nt; - alt.m_ys = lhs_nt->multi_ys(); - alt.name = lhs_nt->name; - - // d) - alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); - - // e) - alt.nt = orig_rhs_nt; - alt.m_ys = orig_rhs_nt->multi_ys(); - alt.name = orig_rhs_nt->name; + Count_rhsNTs nrNTs = Count_rhsNTs(); + alt.nt->traverse(nrNTs); +// std::cerr << *alt.nt->name << ": " << nrNTs.rhs_nts << "\n"; + if (nrNTs.rhs_nts > 0) { + /* a bit hacky: we need to create exact copies of the inside alternative + * production rule, but if we clone all components will have different + * pointers as they are different objects. Thus, we + * a) safely store the original rhs NT (orig_rhs_nt) away + * b) create a second clone of the rhs NT, but prefix its name with + * "outside_" and remove all alternatives + * c) next, we overwrite the current rhs NT of the Alt::Link with the + * lhs NT (which was already prefixed with "outside_") + * d) NOW clone the modified production rule + * e) restore the state before cloning of the inside production rule + */ + + // a) + Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); + + // b) + Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); + outside_rhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(outside_rhs_nt->name)); + outside_rhs_nt->orig_name = outside_rhs_nt->name; + outside_rhs_nt->alts.clear(); + + // c) + alt.nt = lhs_nt; + alt.m_ys = lhs_nt->multi_ys(); + alt.name = lhs_nt->name; + + // d) + alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); + + // e) + alt.nt = orig_rhs_nt; + alt.m_ys = orig_rhs_nt->multi_ys(); + alt.name = orig_rhs_nt->name; + } } } @@ -509,13 +546,13 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { } }; -struct Count_rhsNTs : public Visitor { +struct Count_rhsNTsXX : public Visitor { unsigned int rhs_nts = 0; std::set *axiom_candidates; hashtable outside_nts; - Count_rhsNTs(hashtable outside_nts) : outside_nts(outside_nts) { + Count_rhsNTsXX(hashtable outside_nts) : outside_nts(outside_nts) { axiom_candidates = new std::set(); } @@ -588,7 +625,7 @@ void inject_outside_axiom(Grammar *grammar, hashtableis(Symbol::NONTERMINAL)) { Symbol::NT *nt_inside = dynamic_cast((*i).second); for (std::list::const_iterator a = nt_inside->alts.begin(); a != nt_inside->alts.end(); ++a) { - Count_rhsNTs v = Count_rhsNTs(outside_nts); + Count_rhsNTsXX v = Count_rhsNTsXX(outside_nts); (*a)->traverse(v); if (v.rhs_nts == 0) { std::string he = std::string(OUTSIDE_NT_PREFIX + *nt_inside->name); @@ -639,29 +676,53 @@ void inject_outside_axiom(Grammar *grammar, hashtableinit_axiom(); } -void inject_outside_inside_transition(Grammar *grammar, Symbol::NT* target) { - Alt::Link *link = new Alt::Link(grammar->axiom_name, grammar->axiom_loc); - link->nt = dynamic_cast(grammar->axiom); +/* There must be one production rule that realizes the transition from outside + * to inside parts of the grammar. The target non-terminal must be the original + * inside axiom and the source is the outside_ version of the original inside + * axiom (not the outside axiom). However, this outside_ version does not yet + * exist, iff the axiom was never called on the rhs of the inside grammar part + */ +void inject_outside_inside_transition(Grammar *grammar, hashtable &outside_nts, std::string name_inside_axiom) { + std::string name_lhs_outside = std::string(OUTSIDE_NT_PREFIX + name_inside_axiom); +// if (outside_nts.find(name_lhs_outside) == outside_nts.end()) { +// outside_nts[name_lhs_outside] = new Symbol::NT(new std::string(name_inside_axiom), Loc()); +// } + if (outside_nts.find(name_lhs_outside) == outside_nts.end()) { + Symbol::NT *nt_lhs_outside = grammar->axiom->clone(grammar->axiom->track_pos(), false); + nt_lhs_outside->name = new std::string(name_lhs_outside); + nt_lhs_outside->orig_name = nt_lhs_outside->name; + nt_lhs_outside->alts.clear(); + outside_nts[name_lhs_outside] = nt_lhs_outside;// new Symbol::NT(new std::string(name_lhs_outside), Loc()); + } + Symbol::NT *lhs_outside = dynamic_cast(outside_nts[name_lhs_outside]); + assert(lhs_outside); + Symbol::NT *rhs_inside = dynamic_cast(grammar->NTs[name_inside_axiom]); + assert(rhs_inside); + + Alt::Link *link = new Alt::Link(new std::string(name_inside_axiom), Loc()); + link->nt = rhs_inside; Filter *f = new Filter(new std::string("complete_track"), Loc()); f->type = Filter::WITH; std::list *comptracks = new std::list(); - for (unsigned int track = 0; track < grammar->axiom->tracks(); ++track) { + for (unsigned int track = 0; track < rhs_inside->tracks(); ++track) { comptracks->push_back(f); } - link->set_tracks(grammar->axiom->tracks(), grammar->axiom->track_pos()); + link->set_tracks(rhs_inside->tracks(), rhs_inside->track_pos()); link->init_multi_ys(); -// link->is_outside_inside_transition = true; +// //link->is_outside_inside_transition = true; if (link->nt->tracks() == 1) { link->filters.push_back(f); } else { link->add_multitrack_filter(*comptracks, f->type, Loc()); } link->top_level = Bool(true); - target->alts.push_back(link); + + lhs_outside->alts.push_back(link); } void Grammar::convert_to_outside() { hashtable outside_nts; + std::string name_inside_axiom = *this->axiom_name; for (hashtable::iterator i = NTs.begin(); i != NTs.end(); ++i) { @@ -689,20 +750,21 @@ void Grammar::convert_to_outside() { } } + /* inject one alternative to the inside axiom which enables the transition + * from outside parts into the original inside part of the grammar */ + inject_outside_inside_transition(this, outside_nts, name_inside_axiom); + // now add the new outside NTs to the grammar for (hashtable::iterator i = outside_nts.begin(); i != outside_nts.end(); ++i) { this->add_nt(dynamic_cast((*i).second)); } - // inject one alternative to the inside axiom which enables the transition - // from outside parts into the original inside part of the grammar - inject_outside_inside_transition(this, dynamic_cast((*outside_nts.find(std::string(OUTSIDE_NT_PREFIX + *this->axiom_name))).second)); - - Count_rhsNTs v = Count_rhsNTs(outside_nts); + // inject new outside axiom + Count_rhsNTsXX v = Count_rhsNTsXX(outside_nts); this->traverse(v); -// // inject new outside axiom -// inject_outside_axiom(this, outside_nts); + + /* NT-table dimension optimization (all start quadratic, but depending on * yield size, some NT-tables can be reduced to linear or even constant From 4fda86f1370e83536fbfeca7aaf148b8d65aa511 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 14 Mar 2023 13:13:54 +0100 Subject: [PATCH 032/189] linting --- src/alt.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alt.hh b/src/alt.hh index 4e53fc65b..8b8462169 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -266,7 +266,7 @@ class Base { public: void set_tracks(size_t t, size_t p); - // set to public, to allow transmission to outside pendants + // set to public, to allow transmission to outside pendants public: Yield::Multi m_ys; From 0491ae4eba615885e38d76ea98c2b0698ffd6ec7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 14 Mar 2023 13:14:11 +0100 Subject: [PATCH 033/189] added comments, seems to work --- src/outside/grammar_transformation.cc | 261 ++++++++++++++------------ 1 file changed, 136 insertions(+), 125 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index fc8276bdd..b68540db0 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -22,6 +22,7 @@ }}} */ #include "grammar_transformation.hh" +#include bool Grammar::check_outside_parse_empty_word() { if (this->ast.outside_generation()) { @@ -116,7 +117,6 @@ struct AlgfctUsedInGrammar : public Visitor { } }; - bool is_terminal_type(Type::Base *t) { if ((t->is(Type::ALPHABET)) || (t->is(Type::VOID)) || (t->is(Type::REALVOID)) || (t->is(Type::CHAR)) || @@ -157,7 +157,6 @@ bool is_terminal_type(Type::Base *t) { return false; } - bool Instance::check_multiple_answer_types(bool for_outside_generation) { if (!for_outside_generation) { // no need to check, if no outside transformation was requested @@ -428,26 +427,28 @@ void resolve_blocks(Symbol::NT *nt) { } } -/* Counts the number of rhs non-terminals and algebra functions, e.g. +/* Counts the number of components a rule will inject into parse-trees, e.g. * hairpin = hl(BASE, REGION, BASE) : increase by 1 due to hl * plus = CHAR('+') : no increase since only terminal used on rhs * weak = hairpin | bulgeL : increase by 2 due to 2 non-terminals + * At least one component is necessary to subject the production rule to + * outside generation and/or outside axiom determination */ -struct Count_rhsNTs : public Visitor { - unsigned int rhs_nts = 0; +struct Count_parseComponents : public Visitor { + unsigned int number_components = 0; - Count_rhsNTs() { - rhs_nts = 0; + Count_parseComponents() { + number_components = 0; } void visit_begin(Alt::Simple &alt) { if (!alt.is_terminal()) { - rhs_nts++; + number_components++; } } void visit(Alt::Link &alt) { if (alt.nt->is(Symbol::NONTERMINAL)) { - rhs_nts++; + number_components++; } } }; @@ -470,7 +471,7 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { // the rhs top level alternative Alt::Base *topalt = nullptr; - Flip_lhs_rhs_nonterminals(Symbol::NT *nt) { + explicit Flip_lhs_rhs_nonterminals(Symbol::NT *nt) { // initialize the for now empty list of flipped alternative production rules alt_clones = new std::list >(); @@ -499,10 +500,9 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { * We therefore here count the number of used non-terminal and algebra * functions in the linked non-terminal */ - Count_rhsNTs nrNTs = Count_rhsNTs(); + Count_parseComponents nrNTs = Count_parseComponents(); alt.nt->traverse(nrNTs); -// std::cerr << *alt.nt->name << ": " << nrNTs.rhs_nts << "\n"; - if (nrNTs.rhs_nts > 0) { + if (nrNTs.number_components > 0) { /* a bit hacky: we need to create exact copies of the inside alternative * production rule, but if we clone all components will have different * pointers as they are different objects. Thus, we @@ -516,11 +516,14 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { */ // a) - Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); + Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone( + dynamic_cast(alt.nt)->track_pos(), true); // b) - Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone(dynamic_cast(alt.nt)->track_pos(), true); - outside_rhs_nt->name = new std::string(OUTSIDE_NT_PREFIX + *(outside_rhs_nt->name)); + Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone( + dynamic_cast(alt.nt)->track_pos(), true); + outside_rhs_nt->name = new std::string( + OUTSIDE_NT_PREFIX + *(outside_rhs_nt->name)); outside_rhs_nt->orig_name = outside_rhs_nt->name; outside_rhs_nt->alts.clear(); @@ -546,14 +549,30 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { } }; -struct Count_rhsNTsXX : public Visitor { +/* end points of the inside grammar, i.e. production rules that terminate, are + * the starting points of the outside grammar. Thus, we here iterate through + * the inside part of the grammar, collect the lhs non-terminal names of these + * terminating productions and finally create one novel non-terminal which we + * designate to be the new outside axiom with as many alternatives as we + * have collected lhs non-terminals before. + * Edge case: if there is only one lhs non-terminal, we can directly use this + * as outside axiom, without creating a new non-terminal first. */ +struct Collect_and_Insert_outside_axioms : public Visitor { + // counts the number of non-terminating rhs productions unsigned int rhs_nts = 0; - std::set *axiom_candidates; + // collects the lhs non-terminals that point to terminating rhs, + // i.e. end point of inside = starting points of outside + std::set *terminating_lhs_nts; + + // a reference to the already created new outside non-terminals, into which + // the new axiom must be added hashtable outside_nts; - Count_rhsNTsXX(hashtable outside_nts) : outside_nts(outside_nts) { - axiom_candidates = new std::set(); + Collect_and_Insert_outside_axioms( + hashtable outside_nts) : + outside_nts(outside_nts) { + terminating_lhs_nts = new std::set(); } void visit(Alt::Link &alt) { @@ -564,141 +583,126 @@ struct Count_rhsNTsXX : public Visitor { void visit_itr(Symbol::NT &nt) { if (rhs_nts == 0) { - hashtable::iterator it_outside_nt = outside_nts.find(std::string(OUTSIDE_NT_PREFIX + *nt.name)); + // we identified the (inside)nt as one that only points to terminating + // productions. Thus, we search for its outside counterparts and add + // this counterpart to the set of terminating_lhs_nts + hashtable::iterator it_outside_nt = + outside_nts.find(std::string(OUTSIDE_NT_PREFIX + *nt.name)); if (it_outside_nt != outside_nts.end()) { - axiom_candidates->insert(dynamic_cast((*it_outside_nt).second)); + assert((*it_outside_nt).second->is(Symbol::NONTERMINAL)); + terminating_lhs_nts->insert( + dynamic_cast((*it_outside_nt).second)); } } rhs_nts = 0; // for next iteration } - void visit_end(Grammar &g) { - if (axiom_candidates->size() == 1) { + void visit_end(Grammar &grammar) { + Symbol::NT *nt_axiom; + if (terminating_lhs_nts->size() == 1) { // if there is only one candidate NT, we simple make this NT the new axiom - g.axiom_name = (*axiom_candidates->begin())->name; - } else if (axiom_candidates->size() > 1) { + hashtable::iterator a = grammar.NTs.find( + *((*terminating_lhs_nts->begin())->name)); + // assert that the single found axiom candidate is actually in the NTs of + // the grammar + assert(a != grammar.NTs.end()); + // also assert that the axiom candidate is of type Symbol::NT + // (not Symbol::Terminal) + assert((*a).second->is(Symbol::NONTERMINAL)); + nt_axiom = dynamic_cast((*a).second); + } else if (terminating_lhs_nts->size() > 1) { // it is more complicated if there are several NTs - // we then need to create a novel lhs NT ... - //std::string *axiom_name = new std::string(*OUTSIDE_NT_PREFIX + "_axioms"); - std::string *axiom_name = new std::string(OUTSIDE_NT_PREFIX + std::string("axioms")); - hashtable::iterator it_ntclash = g.NTs.find(*axiom_name); - if (it_ntclash != g.NTs.end()) { - throw LogError((*it_ntclash).second->location, "Please avoid using '" + *axiom_name + "' as l.h.s. non-terminal name, when requesting outside grammar generation!"); + // we then need to create a novel lhs NT with the name "outside_axioms" + std::string *axiom_name = new std::string( + OUTSIDE_NT_PREFIX + std::string("axioms")); + + // we should double check that the user did not already define a NT with + // this name + hashtable::iterator it_ntclash = + grammar.NTs.find(*axiom_name); + if (it_ntclash != grammar.NTs.end()) { + throw LogError((*it_ntclash).second->location, "Please avoid using '" + + *axiom_name + "' as l.h.s. non-terminal name, when requesting " + + "outside grammar generation!"); } - Symbol::NT *nt_axiom = new Symbol::NT(axiom_name, Loc()); - nt_axiom->name = axiom_name; - nt_axiom->orig_name = axiom_name; - // TODO can't I clone inside NT? - // carry over tracks from original inside axiom - nt_axiom->set_tracks(g.axiom->tracks(), g.axiom->track_pos()); - nt_axiom->setup_multi_ys(); - - for (std::set::iterator i = axiom_candidates->begin(); - i != axiom_candidates->end(); ++i) { + // let's use the current inside axiom as template ... + nt_axiom = grammar.axiom->clone(grammar.axiom->track_pos(), false); + // but change its name + nt_axiom->name = axiom_name; + nt_axiom->orig_name = nt_axiom->name; + // and clear all current alternatives + nt_axiom->alts.clear(); + // remove choice function, as we chose/sum from/over different axiom + // candidates + nt_axiom->eval_fn = nullptr; + + // add all axiom candidates as alternatives to the new axiom + for (std::set::iterator i = terminating_lhs_nts->begin(); + i != terminating_lhs_nts->end(); ++i) { Alt::Link *link = new Alt::Link((*i)->name, Loc()); link->nt = *i; link->set_tracks((*i)->tracks(), (*i)->track_pos()); link->init_multi_ys(); + link->top_level = Bool(true); nt_axiom->alts.push_back(link); } - // add new lhs non-terminal to grammar - g.add_nt(nt_axiom); - - g.axiom_name = axiom_name; + // add new lhs non-terminal to grammar + grammar.add_nt(nt_axiom); + } else { + throw LogError("You inside grammar does not seem to terminate, which " + "should have been reported earlier via semantic checks?!"); } - g.init_axiom(); - } -}; -void inject_outside_axiom(Grammar *grammar, hashtable outside_nts) { - /* inside production rules that have NO non-terminals on their right hand - * sides must be those that parse the final sub-words of the input. - * Therefore, they must be the smallest start-points for outside - * construction, i.e. the axiom should point to them. */ - std::set *axiom_candidates = new std::set(); - // check all alternatives, if they do NOT use any non-terminals on their rhs - // if so, the NT must become one of the outside axioms - for (hashtable::iterator i = grammar->NTs.begin(); - i != grammar->NTs.end(); ++i) { - if ((*i).second->is(Symbol::NONTERMINAL)) { - Symbol::NT *nt_inside = dynamic_cast((*i).second); - for (std::list::const_iterator a = nt_inside->alts.begin(); a != nt_inside->alts.end(); ++a) { - Count_rhsNTsXX v = Count_rhsNTsXX(outside_nts); - (*a)->traverse(v); - if (v.rhs_nts == 0) { - std::string he = std::string(OUTSIDE_NT_PREFIX + *nt_inside->name); - hashtable::iterator it_outside_nt = outside_nts.find(he); - if (it_outside_nt != outside_nts.end()) { - axiom_candidates->insert(dynamic_cast((*it_outside_nt).second)); - } - } - } - } - } + // set grammar's axiom non-terminal + grammar.axiom = nt_axiom; - if (axiom_candidates->size() == 1) { - // if there is only one candidate NT, we simple make this NT the new axiom - grammar->axiom_name = (*axiom_candidates->begin())->name; - } else if (axiom_candidates->size() > 1) { - // it is more complicated if there are several NTs - // we then need to create a novel lhs NT ... - //std::string *axiom_name = new std::string(*OUTSIDE_NT_PREFIX + "_axioms"); - std::string *axiom_name = new std::string(OUTSIDE_NT_PREFIX + std::string("axioms")); - hashtable::iterator it_ntclash = grammar->NTs.find(*axiom_name); - if (it_ntclash != grammar->NTs.end()) { - throw LogError((*it_ntclash).second->location, "Please avoid using '" + *axiom_name + "' as l.h.s. non-terminal name, when requesting outside grammar generation!"); - } - Symbol::NT *nt_axiom = new Symbol::NT(axiom_name, Loc()); - nt_axiom->name = axiom_name; - nt_axiom->orig_name = axiom_name; - - // TODO can't I clone inside NT? - // carry over tracks from original inside axiom - nt_axiom->set_tracks(grammar->axiom->tracks(), grammar->axiom->track_pos()); - nt_axiom->setup_multi_ys(); - - for (std::set::iterator i = axiom_candidates->begin(); - i != axiom_candidates->end(); ++i) { - Alt::Link *link = new Alt::Link((*i)->name, Loc()); - link->nt = *i; - link->set_tracks((*i)->tracks(), (*i)->track_pos()); - link->init_multi_ys(); - nt_axiom->alts.push_back(link); - } - // add new lhs non-terminal to grammar - grammar->add_nt(nt_axiom); + // set grammar's axiom name + grammar.axiom_name = nt_axiom->name; - grammar->axiom_name = axiom_name; + // redirect grammar's axiom's location + grammar.axiom_loc = nt_axiom->location; + // initialize links of the new axiom + grammar.init_axiom(); } - grammar->init_axiom(); -} +}; /* There must be one production rule that realizes the transition from outside * to inside parts of the grammar. The target non-terminal must be the original * inside axiom and the source is the outside_ version of the original inside - * axiom (not the outside axiom). However, this outside_ version does not yet - * exist, iff the axiom was never called on the rhs of the inside grammar part + * axiom (not the outside axiom). However, */ -void inject_outside_inside_transition(Grammar *grammar, hashtable &outside_nts, std::string name_inside_axiom) { - std::string name_lhs_outside = std::string(OUTSIDE_NT_PREFIX + name_inside_axiom); -// if (outside_nts.find(name_lhs_outside) == outside_nts.end()) { -// outside_nts[name_lhs_outside] = new Symbol::NT(new std::string(name_inside_axiom), Loc()); -// } +void inject_outside_inside_transition( + Grammar *grammar, + hashtable &outside_nts, + std::string name_inside_axiom) { + std::string name_lhs_outside = std::string( + OUTSIDE_NT_PREFIX + name_inside_axiom); + + /* if the axiom was never called on the rhs of the inside grammar part, the + * outside counterpart of the inside axiom does not yet exist. Thus we create + * it here */ if (outside_nts.find(name_lhs_outside) == outside_nts.end()) { - Symbol::NT *nt_lhs_outside = grammar->axiom->clone(grammar->axiom->track_pos(), false); + Symbol::NT *nt_lhs_outside = grammar->axiom->clone( + grammar->axiom->track_pos(), false); nt_lhs_outside->name = new std::string(name_lhs_outside); nt_lhs_outside->orig_name = nt_lhs_outside->name; nt_lhs_outside->alts.clear(); - outside_nts[name_lhs_outside] = nt_lhs_outside;// new Symbol::NT(new std::string(name_lhs_outside), Loc()); + outside_nts[name_lhs_outside] = nt_lhs_outside; } - Symbol::NT *lhs_outside = dynamic_cast(outside_nts[name_lhs_outside]); + + Symbol::NT *lhs_outside = dynamic_cast( + outside_nts[name_lhs_outside]); assert(lhs_outside); - Symbol::NT *rhs_inside = dynamic_cast(grammar->NTs[name_inside_axiom]); + Symbol::NT *rhs_inside = dynamic_cast( + grammar->NTs[name_inside_axiom]); assert(rhs_inside); + /* we need to add a special filter to the transition, to ensure that + * it is only invoked with the FULL input sequence(s). Don't forget multi- + * track programs. */ Alt::Link *link = new Alt::Link(new std::string(name_inside_axiom), Loc()); link->nt = rhs_inside; Filter *f = new Filter(new std::string("complete_track"), Loc()); @@ -717,6 +721,7 @@ void inject_outside_inside_transition(Grammar *grammar, hashtabletop_level = Bool(true); + // finally add this new transition to the list of alternaties lhs_outside->alts.push_back(link); } @@ -729,17 +734,22 @@ void Grammar::convert_to_outside() { if ((*i).second->is(Symbol::NONTERMINAL)) { Symbol::NT *nt_inside = dynamic_cast((*i).second); - // don't operate on the original inside non-terminal, but on a clone in which Alt::Block applications have been resolved - Symbol::NT *nt_inside_resolved = nt_inside->clone(nt_inside->track_pos(), true); + // don't operate on the original inside non-terminal, but on a clone in + // which Alt::Block applications have been resolved + Symbol::NT *nt_inside_resolved = nt_inside->clone( + nt_inside->track_pos(), true); resolve_blocks(nt_inside_resolved); - Flip_lhs_rhs_nonterminals v = Flip_lhs_rhs_nonterminals(nt_inside_resolved); + Flip_lhs_rhs_nonterminals v = Flip_lhs_rhs_nonterminals( + nt_inside_resolved); nt_inside_resolved->traverse(v); // add new alternatives and new non-terminals to existing grammar - for (std::list >::iterator i = v.alt_clones->begin(); i != v.alt_clones->end(); ++i) { + for (std::list >::iterator i = + v.alt_clones->begin(); i != v.alt_clones->end(); ++i) { std::string *nt_name = (*i).first->name; - hashtable::iterator it_nt = outside_nts.find(*nt_name); + hashtable::iterator it_nt = + outside_nts.find(*nt_name); if (it_nt == outside_nts.end()) { outside_nts[*nt_name] = (*i).first; } @@ -761,7 +771,8 @@ void Grammar::convert_to_outside() { } // inject new outside axiom - Count_rhsNTsXX v = Count_rhsNTsXX(outside_nts); + Collect_and_Insert_outside_axioms v = Collect_and_Insert_outside_axioms( + outside_nts); this->traverse(v); From aa3332eb69e302412a9f0a161d951454260e278b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 14 Mar 2023 13:17:19 +0100 Subject: [PATCH 034/189] linting --- src/symbol.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/symbol.hh b/src/symbol.hh index 4daf76fdc..7738f43e6 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -360,7 +360,7 @@ class NT : public Base { NT(std::string *n, const Loc &l); - NT *clone(size_t track_pos, bool keepname=false); + NT *clone(size_t track_pos, bool keepname = false); void set_grammar_index(size_t i) { grammar_index_ = i; From 4415701db12553d1a4327bed33b14283e4e97b06 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 12 Apr 2023 14:11:35 +0200 Subject: [PATCH 035/189] Update plot_grammar.cc --- src/plot_grammar.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plot_grammar.cc b/src/plot_grammar.cc index 96b704056..5d011caf3 100644 --- a/src/plot_grammar.cc +++ b/src/plot_grammar.cc @@ -733,7 +733,7 @@ unsigned int Symbol::NT::to_dot(unsigned int *nodeID, std::ostream &out, unsigned int Grammar::to_dot(unsigned int *nodeID, std::ostream &out, int plot_grammar) { - int start_node; + int start_node = *nodeID; unsigned int i = 1; out << "digraph " << *this->name << " {\n"; inc_indent(); From 7f60b364d94063c6f9dda899daf7419d55cc154a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 12 Apr 2023 15:01:00 +0200 Subject: [PATCH 036/189] initialize startNode --- src/plot_grammar.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plot_grammar.cc b/src/plot_grammar.cc index 96b704056..5d011caf3 100644 --- a/src/plot_grammar.cc +++ b/src/plot_grammar.cc @@ -733,7 +733,7 @@ unsigned int Symbol::NT::to_dot(unsigned int *nodeID, std::ostream &out, unsigned int Grammar::to_dot(unsigned int *nodeID, std::ostream &out, int plot_grammar) { - int start_node; + int start_node = *nodeID; unsigned int i = 1; out << "digraph " << *this->name << " {\n"; inc_indent(); From daa07e9bac415b5a9baa6a7fe93a0b5f5c770dbf Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 13 Apr 2023 11:03:35 +0200 Subject: [PATCH 037/189] adding a new private bool attribute to indicate grammar components to be outside, and mechanism to flag accordingly --- src/alt.hh | 10 ++++++++ src/fn_arg.hh | 11 ++++++++ src/grammar.hh | 10 ++++++++ src/outside/grammar_transformation.cc | 36 +++++++++++++++++++++++++-- src/symbol.hh | 10 ++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index 8b8462169..15e29714b 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -76,6 +76,9 @@ class Base { */ Type type; + /* Flag this alternative as being part of an outside grammar component */ + bool _is_partof_outside = false; + protected: ADP_Mode::Adp_Specialization adp_specialization; ADP_Mode::Adp_Join adp_join; @@ -318,6 +321,13 @@ class Base { std::ostream &out, std::vector *childIDs = NULL); virtual unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + + const bool is_partof_outside() { + return _is_partof_outside; + } + void set_partof_outside() { + _is_partof_outside = true; + } }; diff --git a/src/fn_arg.hh b/src/fn_arg.hh index a34cebf42..0607e9a81 100644 --- a/src/fn_arg.hh +++ b/src/fn_arg.hh @@ -55,6 +55,10 @@ class Base { private: Type type; + /* Flag this function argument as being part of an outside grammar + * component */ + bool _is_partof_outside = false; + protected: bool productive; ::Type::Base *datatype; @@ -144,6 +148,13 @@ class Base { public: virtual void init_multi_ys() = 0; virtual const Yield::Multi &multi_ys() const { return m_ys; } + + const bool is_partof_outside() { + return _is_partof_outside; + } + void set_partof_outside() { + _is_partof_outside = true; + } }; diff --git a/src/grammar.hh b/src/grammar.hh index d02b04a0e..3ae56c8ea 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -64,6 +64,9 @@ class Grammar { void renumber_nts(); void move_new_nts(); + /* Flag this Grammar as being converted into an outside version */ + bool _is_partof_outside = false; + public: // The name of the grammar as defined in the grammar name of // the gap-source-code file. @@ -222,6 +225,13 @@ class Grammar { * the given (inside-) grammar is turned into an outside grammar. */ void convert_to_outside(); + + const bool is_partof_outside() { + return _is_partof_outside; + } + void set_partof_outside() { + _is_partof_outside = true; + } }; diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index b68540db0..ba6ac766a 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -549,6 +549,21 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { } }; +struct Flag_Outside_Grammar_Components : public Visitor { + void visit(Symbol::Terminal &s) { + s.set_partof_outside(); + } + void visit(Symbol::NT &s) { + s.set_partof_outside(); + } + void visit(Alt::Base &a) { + a.set_partof_outside(); + } + void visit(Fn_Arg::Base &f) { + f.set_partof_outside(); + } +}; + /* end points of the inside grammar, i.e. production rules that terminate, are * the starting points of the outside grammar. Thus, we here iterate through * the inside part of the grammar, collect the lhs non-terminal names of these @@ -648,6 +663,11 @@ struct Collect_and_Insert_outside_axioms : public Visitor { nt_axiom->alts.push_back(link); } + // a visitor to flag all sub-components as being outside + Flag_Outside_Grammar_Components v_flag = + Flag_Outside_Grammar_Components(); + nt_axiom->traverse(v_flag); + // add new lhs non-terminal to grammar grammar.add_nt(nt_axiom); } else { @@ -721,11 +741,14 @@ void inject_outside_inside_transition( } link->top_level = Bool(true); - // finally add this new transition to the list of alternaties + // finally add this new transition to the list of alternatives lhs_outside->alts.push_back(link); } void Grammar::convert_to_outside() { + // a visitor to later flag all sub-components as being outside + Flag_Outside_Grammar_Components v_flag = Flag_Outside_Grammar_Components(); + hashtable outside_nts; std::string name_inside_axiom = *this->axiom_name; @@ -767,14 +790,23 @@ void Grammar::convert_to_outside() { // now add the new outside NTs to the grammar for (hashtable::iterator i = outside_nts.begin(); i != outside_nts.end(); ++i) { + /* flag the new NT as being outside, to tell apart automatically generated + * NTs for outside parts from user defined inside parts. Necessary for e.g. + * - reverse index construction + */ + (*i).second->traverse(v_flag); + + // finally add new outside non-terminal to the grammar this->add_nt(dynamic_cast((*i).second)); } - // inject new outside axiom + // inject new outside axiom (also flag as being outside) Collect_and_Insert_outside_axioms v = Collect_and_Insert_outside_axioms( outside_nts); this->traverse(v); + // flag the grammar itself as being an outside version + this->set_partof_outside(); /* NT-table dimension optimization (all start quadratic, but depending on diff --git a/src/symbol.hh b/src/symbol.hh index 7738f43e6..39051a9f7 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -74,6 +74,9 @@ class Base { private: Type type; + /* Flag this Symbol as being part of an outside grammar component */ + bool _is_partof_outside = false; + protected: ADP_Mode::Adp_Specialization adp_specialization; ADP_Mode::Adp_Join adp_join; @@ -252,6 +255,13 @@ class Base { virtual unsigned int to_dot(unsigned int *nodeID, std::ostream &out, bool is_rhs, Symbol::NT *axiom, int plot_grammar); + + const bool is_partof_outside() { + return _is_partof_outside; + } + void set_partof_outside() { + _is_partof_outside = true; + } }; From 3f3c9e77f027c87bb6216a961a26618d7b03a892 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 13 Apr 2023 13:55:08 +0200 Subject: [PATCH 038/189] only warn about user defined non-terminals, but not automatically injected via outside --- src/grammar.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/grammar.cc b/src/grammar.cc index 3a1fa0546..c02cfe5d3 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -664,7 +664,11 @@ void Grammar::put_table_conf(std::ostream &s) { hashtable::iterator a = tabulated.find( *i->second->name); if (a == tabulated.end()) { - assert(false); + // user might not have considered outside NTs to be tabulated in + // his/her manual annotated table-design + if (i->second->is_partof_outside() == false) { + assert(false); + } } } } From 5d4c99d3e199ebb0d2a91b23ebb667daf867725f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 13 Apr 2023 14:00:37 +0200 Subject: [PATCH 039/189] initially, only set link names then later initialize alt::link.nt via init_nt_links() when NTs have been added to grammar --- src/outside/grammar_transformation.cc | 65 ++++++++++++++++----------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index ba6ac766a..281470c66 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -528,7 +528,8 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { outside_rhs_nt->alts.clear(); // c) - alt.nt = lhs_nt; + // don't set NT here, since we don't know the correct lhs pointer + alt.nt = nullptr; alt.m_ys = lhs_nt->multi_ys(); alt.name = lhs_nt->name; @@ -591,7 +592,10 @@ struct Collect_and_Insert_outside_axioms : public Visitor { } void visit(Alt::Link &alt) { - if (alt.nt->is(Symbol::NONTERMINAL)) { + /* also check that alt.nt is not NULL as at this stage outside NTs are not + * yet initialized, i.e. name is set correctly but the pointer to the NT + * is null. */ + if (alt.nt && alt.nt->is(Symbol::NONTERMINAL)) { rhs_nts++; } } @@ -656,9 +660,11 @@ struct Collect_and_Insert_outside_axioms : public Visitor { for (std::set::iterator i = terminating_lhs_nts->begin(); i != terminating_lhs_nts->end(); ++i) { Alt::Link *link = new Alt::Link((*i)->name, Loc()); - link->nt = *i; - link->set_tracks((*i)->tracks(), (*i)->track_pos()); - link->init_multi_ys(); + link->name = (*i)->name; + /* TODO(smj): check if really not necessary */ +// link->nt = *i; +// link->set_tracks((*i)->tracks(), (*i)->track_pos()); +// link->init_multi_ys(); link->top_level = Bool(true); nt_axiom->alts.push_back(link); } @@ -724,17 +730,21 @@ void inject_outside_inside_transition( * it is only invoked with the FULL input sequence(s). Don't forget multi- * track programs. */ Alt::Link *link = new Alt::Link(new std::string(name_inside_axiom), Loc()); - link->nt = rhs_inside; + /* nullptr as we don't know the pointer to lhs NT. + * Will be resolved through init_nt_links(), just provide the correct name! */ + link->nt = nullptr; + link->name = rhs_inside->name; Filter *f = new Filter(new std::string("complete_track"), Loc()); f->type = Filter::WITH; std::list *comptracks = new std::list(); for (unsigned int track = 0; track < rhs_inside->tracks(); ++track) { comptracks->push_back(f); } - link->set_tracks(rhs_inside->tracks(), rhs_inside->track_pos()); - link->init_multi_ys(); + // TODO(smj): check of really done via check_semantics() +// link->set_tracks(rhs_inside->tracks(), rhs_inside->track_pos()); +// link->init_multi_ys(); // //link->is_outside_inside_transition = true; - if (link->nt->tracks() == 1) { + if (rhs_inside->tracks() == 1) { link->filters.push_back(f); } else { link->add_multitrack_filter(*comptracks, f->type, Loc()); @@ -796,7 +806,7 @@ void Grammar::convert_to_outside() { */ (*i).second->traverse(v_flag); - // finally add new outside non-terminal to the grammar + // add new outside non-terminal to the grammar this->add_nt(dynamic_cast((*i).second)); } @@ -808,7 +818,14 @@ void Grammar::convert_to_outside() { // flag the grammar itself as being an outside version this->set_partof_outside(); + // initialize rhs non-terminals, i.e. point to the correct NT from the used + // name. + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + (*i).second->init_links(*this); + } + //TODO(smj): is this the proper location? /* NT-table dimension optimization (all start quadratic, but depending on * yield size, some NT-tables can be reduced to linear or even constant * "tables") must be re-considered, since original inside NTs will now @@ -818,22 +835,20 @@ void Grammar::convert_to_outside() { * We therefore here reset the flag of all NTs to enable re-computation * of optimal table dimensions ... within the outside context. */ -// for (hashtable::iterator i = NTs.begin(); -// i != NTs.end(); ++i) { -// if ((*i).second->is(Symbol::NONTERMINAL)) { -// dynamic_cast((*i).second)->reset_table_dim(); -// } -// } -// -// /* re-run "check_semantics" to properly initialize novel non- -// * terminals, links to non-terminals, update yield size analysis and -// * update table dimensions for NTs -// */ -// this->check_semantic(); + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + if ((*i).second->is(Symbol::NONTERMINAL)) { + dynamic_cast((*i).second)->reset_table_dim(); + } + } + + //TODO(smj): double check if this is necessary or at least do a silent test + /* re-run "check_semantics" to properly initialize novel non- + * terminals, links to non-terminals, update yield size analysis and + * update table dimensions for NTs + */ + this->check_semantic(); Log::instance()->verboseMessage( "Grammar has been modified into an outside version."); - -// unsigned int nodeID = 1; -// this->to_dot(&nodeID, std::cerr, 1); } From c4b92cbf0c365d4e6fa2b7d909e7b186af65c1f5 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 13 Apr 2023 15:40:38 +0200 Subject: [PATCH 040/189] linting --- src/outside/grammar_transformation.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 281470c66..69ede62b1 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -825,7 +825,7 @@ void Grammar::convert_to_outside() { (*i).second->init_links(*this); } - //TODO(smj): is this the proper location? + // TODO(smj): is this the proper location? /* NT-table dimension optimization (all start quadratic, but depending on * yield size, some NT-tables can be reduced to linear or even constant * "tables") must be re-considered, since original inside NTs will now @@ -842,7 +842,7 @@ void Grammar::convert_to_outside() { } } - //TODO(smj): double check if this is necessary or at least do a silent test + // TODO(smj): double check if this is necessary or at least do a silent test /* re-run "check_semantics" to properly initialize novel non- * terminals, links to non-terminals, update yield size analysis and * update table dimensions for NTs From 57add9469533de41e454146557fb2330be5c813c Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 18 Apr 2023 08:32:07 +0200 Subject: [PATCH 041/189] set track --- src/outside/grammar_transformation.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 69ede62b1..7d6a54a19 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -661,10 +661,8 @@ struct Collect_and_Insert_outside_axioms : public Visitor { i != terminating_lhs_nts->end(); ++i) { Alt::Link *link = new Alt::Link((*i)->name, Loc()); link->name = (*i)->name; - /* TODO(smj): check if really not necessary */ -// link->nt = *i; -// link->set_tracks((*i)->tracks(), (*i)->track_pos()); -// link->init_multi_ys(); + link->set_tracks((*i)->tracks(), (*i)->track_pos()); + link->init_multi_ys(); link->top_level = Bool(true); nt_axiom->alts.push_back(link); } @@ -741,9 +739,9 @@ void inject_outside_inside_transition( comptracks->push_back(f); } // TODO(smj): check of really done via check_semantics() -// link->set_tracks(rhs_inside->tracks(), rhs_inside->track_pos()); -// link->init_multi_ys(); -// //link->is_outside_inside_transition = true; + link->set_tracks(rhs_inside->tracks(), rhs_inside->track_pos()); + // link->init_multi_ys(); + // link->is_outside_inside_transition = true; if (rhs_inside->tracks() == 1) { link->filters.push_back(f); } else { @@ -751,6 +749,9 @@ void inject_outside_inside_transition( } link->top_level = Bool(true); + // flag this single link as the transition from outside to inside + link->set_outside_inside_transition(); + // finally add this new transition to the list of alternatives lhs_outside->alts.push_back(link); } From a98aa990f558ab497d5a72f6ec650e9649ac6cd2 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 18 Apr 2023 08:37:00 +0200 Subject: [PATCH 042/189] add _is_outside_inside_transition function --- src/alt.hh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/alt.hh b/src/alt.hh index 15e29714b..4c46d96d3 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -525,6 +525,12 @@ class Link : public Base { private: Runtime::Poly calls; + /* flags the one and only situation where outside grammar + * transitions into inside rules, i.e. user defined axiom. + * we need to ensure that according NT call asks for the + * empy word. */ + bool _is_outside_inside_transition = false; + public: // The name of the non-terminal this instance wrappes. This // name will be resolved when the method Link::init_links(Grammar*) @@ -634,6 +640,13 @@ class Link : public Base { void optimize_choice(); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + + const bool is_outside_inside_transition() { + return _is_outside_inside_transition; + } + void set_outside_inside_transition() { + _is_outside_inside_transition = true; + } }; From 7429b99944b4bfe2cfca04e32710bdbdef31485f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 18 Apr 2023 11:40:19 +0200 Subject: [PATCH 043/189] indices for terminals / non-terminals --- src/gapc.cc | 6 + src/outside/middle_end.cc | 76 ++++++++ src/outside/middle_end.hh | 398 ++++++++++++++++++++++++++++++++++++++ src/symbol.cc | 13 +- 4 files changed, 491 insertions(+), 2 deletions(-) create mode 100644 src/outside/middle_end.cc create mode 100644 src/outside/middle_end.hh diff --git a/src/gapc.cc b/src/gapc.cc index 4e425e90a..5327947d7 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -644,6 +644,12 @@ class Main { } grammar->init_indices(); + unsigned int nodeID = 1; + grammar->to_dot(&nodeID, opts.plotgrammar_stream(), opts.plot_grammar); + + opts.plotgrammar_stream_->flush(); + exit(99); + grammar->init_decls(); // for cyk (ordering of NT for parsing, see page 101 of the thesis) grammar->dep_analysis(); diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc new file mode 100644 index 000000000..882f51cb1 --- /dev/null +++ b/src/outside/middle_end.cc @@ -0,0 +1,76 @@ +/* {{{ + + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ + +#include "middle_end.hh" + +Expr::Base *next_index_var(unsigned &k, size_t track, + Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, + const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs) { + if (ys.low() != ys.high()) { + if (rhs.low() == rhs.high()) { + return right; + } else { + std::ostringstream o; + o << "t_" << track << "_k_" << k; + k++; + Expr::Vacc *ivar = new Expr::Vacc(new std::string(o.str())); + + assert(lhs.low() == lhs.high()); + std::pair index(0, 0); + + Yield::Size lhs_ys(lhs); + lhs_ys += ys; + + if (rhs.high() == Yield::UP) { + index.first = last_var->plus(lhs_ys.low()); + } else { + // e.g. second maxsize filter in grammar/forloops5 + Expr::Cond *ce = new Expr::Cond( + new Expr::Greater_Eq(right->minus( + last_var->plus(lhs_ys.low())), rhs.high()), + right->minus(rhs.high()), last_var->plus(lhs_ys.low())); + index.first = ce; + } + + index.second = right->minus(rhs.low()); + + Expr::Base *cond = new Expr::Less_Eq(ivar, index.second); + // e.g. first maxsize filter in grammar/forloops5 + if (lhs_ys.high() < Yield::UP) { + cond = new Expr::And( + cond, new Expr::Less_Eq (ivar, last_var->plus(lhs_ys.high()))); + } + + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), ivar, index.first); + // flag this variable as being an iterator e.g. in for-loops, + // such that it won't have a trailing indent for code generation + loopvariable->set_itr(true); + Statement::For *f = new Statement::For (loopvariable, cond); + //loops.push_back(f); + return ivar; + } + } else { + return next_var; + } +} diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh new file mode 100644 index 000000000..8b50ab82d --- /dev/null +++ b/src/outside/middle_end.hh @@ -0,0 +1,398 @@ +/* {{{ + + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ + +#ifndef SRC_OUTSIDE_MIDDLE_END_HH_ +#define SRC_OUTSIDE_MIDDLE_END_HH_ + +#include "../visitor.hh" +#include "../alt.hh" +#include "../fn_arg.hh" +#include "../symbol.hh" +#include "../expr.hh" +#include "../statement.hh" + +// copy and paste from alt.cc +Expr::Base *next_index_var(unsigned &k, size_t track, + Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, + const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs); + +struct Init_Indices_Outside : public Visitor { + private: + int num_outside_nts = 0; + std::vector _left; + enum Type { ALT, FN_ARG, SYMBOL }; + std::vector _left_types; + std::vector _right; + std::vector _right_types; + + void stack_component(void *ptr_component, Type t) { + if (num_outside_nts < 1) { + _left.push_back(ptr_component); + _left_types.push_back(t); + } else { + _right.push_back(ptr_component); + _right_types.push_back(t); + } + } + + void assert_one_outside_nt() { + // by design, there must be exactly one rhs outside NT in each alternative + // only exception is the transition from outside to inside grammar parts + assert(num_outside_nts == 1); + } + + public: + + void init_indices(Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track) { + assert_one_outside_nt(); + + Yield::Size ys_all = sum_ys_left(nullptr, nullptr, track); + Expr::Base *last_var = next_index_var(k, track, NULL, left, right, ys_all, Yield::Size(), ys_all); + Expr::Base *next_var = last_var; + + Yield::Size lhs; + // LEFT of outside NT + std::vector::iterator i_type = _left_types.begin(); + for (std::vector::iterator i = _left.begin(); i != _left.end(); ++i, ++i_type) { + Yield::Size ys = sum_ys_left(*i, *i, track); + Yield::Size rhs = sum_ys_left(*std::next(i), nullptr, track); + Yield::Size rhs_ys(rhs); + rhs_ys += ys; + + std::cerr << "L: " << lhs << " - " << ys << " - " << rhs; + + if (*i_type == ALT) { + Alt::Base *a = static_cast(*i); + //std::cerr << (*a).left_indices.size() << " <- Alt\n"; + if (a->is(Alt::LINK)) { + std::cerr << " : " << *(dynamic_cast(a)->name); + next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); + std::cerr << " next_var = " << *next_var; + + // copy and paste from Alt::Simple::init_indices + std::pair res(0, 0); + if (lhs.low() == lhs.high()) { + res.first = last_var->plus(lhs.low()); + if (ys.low() == ys.high()) { + res.second = last_var->plus(lhs.low())->plus(ys.low()); + lhs += ys; + } else { + if (rhs.low() == rhs.high()) { + res.second = next_var->minus(rhs.low()); + lhs += ys; + } else { + res.second = next_var; + lhs.set(0, 0); + last_var = next_var; + } + } + } else { + assert(rhs_ys.low() == rhs_ys.high()); + res.first = next_var->minus(rhs_ys.low()); + res.second = next_var->minus(rhs.low()); + lhs += ys; + } + + a->init_indices(res.first, res.second, k, track); + // end copy and paste + + std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; + } else if (a->is(Alt::SIMPLE)) { + std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); + } + } else if (*i_type == FN_ARG) { + Fn_Arg::Base *f = static_cast(*i); + std::cerr << " : Fn_Arg"; + //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; + //continue; + } else if (*i_type == SYMBOL) { + Symbol::Base *s = static_cast(*i); + std::cerr << " : Symbol"; + //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; +// accum_ys_center_to_left += (*s).multi_ys()(track); + } + + std::cerr << "\n"; + } + + + // RIGHT of outside NT + lhs = sum_ys_right(nullptr, nullptr, track); +// next_var = right; + last_var = right; + lhs.set(0, 0); + i_type = _right_types.begin(); + for (std::vector::iterator i = _right.begin(); i != _right.end(); ++i, ++i_type) { + Yield::Size ys = sum_ys_right(*i, *i, track); +// Yield::Size rhs = Yield::Size(Yield::UP); //sum_ys_right(*std::next(i), nullptr, track); + Yield::Size rhs = sum_ys_right(*std::next(i), nullptr, track); + Yield::Size rhs_ys(rhs); + rhs_ys += ys; + + std::cerr << "R: " << lhs << " - " << ys << " - " << rhs; + + if (*i_type == ALT) { + Alt::Base *a = static_cast(*i); + //std::cerr << (*a).left_indices.size() << " <- Alt\n"; + if (a->is(Alt::LINK)) { + std::cerr << " : " << *(dynamic_cast(a)->name); + next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); + std::cerr << " next_var = " << *next_var; + + // copy and paste from Alt::Simple::init_indices + std::pair res(0, 0); + if (lhs.low() == lhs.high()) { + res.first = last_var->plus(lhs.low()); + if (ys.low() == ys.high()) { + res.second = last_var->plus(lhs.low())->plus(ys.low()); + lhs += ys; + } else { + if (rhs.low() == rhs.high()) { + // edge case: we encounter right end but need another moving boundary for outside context + next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, Yield::Size(Yield::UP)); + + res.second = next_var->minus(rhs.low()); + lhs += ys; + } else { + res.second = next_var; + lhs.set(0, 0); + last_var = next_var; + } + } + } else { + assert(rhs_ys.low() == rhs_ys.high()); + res.first = next_var->minus(rhs_ys.low()); + res.second = next_var->minus(rhs.low()); + lhs += ys; + } + + a->init_indices(res.first, res.second, k, track); + // end copy and paste + + std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; + } else if (a->is(Alt::SIMPLE)) { + std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); + } + } else if (*i_type == FN_ARG) { + Fn_Arg::Base *f = static_cast(*i); + std::cerr << " : Fn_Arg"; + //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; + //continue; + } else if (*i_type == SYMBOL) { + Symbol::Base *s = static_cast(*i); + std::cerr << " : Symbol"; + //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; +// accum_ys_center_to_left += (*s).multi_ys()(track); + } + + std::cerr << "\n"; + } + +// std::vector::reverse_iterator ir_type = _left_types.rbegin(); +// //Expr::Base *last_var = next_index_var(k, track, NULL, left, right, ys_all, Yield::Size(), ys_all); +// for (std::vector::reverse_iterator ir = _right.rbegin(); ir != _right.rend(); ++ir, ++ir_type) { +// Yield::Size ys = sum_ys_right(*ir, *ir, track, false); +// Yield::Size rhs = sum_ys_right(*std::next(ir), nullptr, track, false); +// Yield::Size rhs_ys(rhs); +// rhs_ys += ys; +// +// std::cerr << lhs << " - " << ys << " - " << rhs; +// +// if (*i_type == ALT) { +// Alt::Base *a = static_cast(*ir); +// //std::cerr << (*a).left_indices.size() << " <- Alt\n"; +// if (a->is(Alt::LINK)) { +// std::cerr << " : " << *(dynamic_cast(a)->name); +// next_var = next_index_var(k, track, next_var, last_var, last_var, ys, lhs, rhs); +// std::cerr << " next_var = " << *next_var; +// +// // copy and paste from Alt::Simple::init_indices +// std::pair res(0, 0); +// if (lhs.low() == lhs.high()) { +// res.first = last_var->plus(lhs.low()); +// if (ys.low() == ys.high()) { +// res.second = last_var->plus(lhs.low())->plus(ys.low()); +// lhs += ys; +// } else { +// if (rhs.low() == rhs.high()) { +// res.second = next_var->minus(rhs.low()); +// lhs += ys; +// } else { +// res.second = next_var; +// lhs.set(0, 0); +// last_var = next_var; +// } +// } +// } else { +// assert(rhs_ys.low() == rhs_ys.high()); +// res.first = next_var->minus(rhs_ys.low()); +// res.second = next_var->minus(rhs.low()); +// lhs += ys; +// } +// +// a->init_indices(res.first, res.second, k, track); +// // end copy and paste +// +// std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; +// } else if (a->is(Alt::SIMPLE)) { +// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); +// } +// } else if (*i_type == FN_ARG) { +// Fn_Arg::Base *f = static_cast(*ir); +// std::cerr << " : Fn_Arg"; +// //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; +// //continue; +// } else if (*i_type == SYMBOL) { +// Symbol::Base *s = static_cast(*ir); +// std::cerr << " : Symbol"; +// //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; +//// accum_ys_center_to_left += (*s).multi_ys()(track); +// } +// +// std::cerr << "\n"; +// } + } + + Yield::Size sum_ys_left(void* start, void* end, size_t track) { + Yield::Size ys; + + bool seen_start = false; + if (start == nullptr) { + seen_start = true; + } + std::vector::iterator i_type = _left_types.begin(); + for (std::vector::iterator i = _left.begin(); i != _left.end(); ++i, ++i_type) { + if (*i == start) { + seen_start = true; + } + if (seen_start) { + if (*i_type == ALT) { + Alt::Base *a = static_cast(*i); + if (a->is(Alt::LINK)) { + ys += (*a).multi_ys()(track); + } + } else if (*i_type == SYMBOL) { + Symbol::Base *s = static_cast(*i); + ys += (*s).multi_ys()(track); + } + } + if (*i == end) { + break; + } + } + + return ys; + } + Yield::Size sum_ys_right(void* start, void* end, size_t track) { + Yield::Size ys; + + bool seen_start = false; + if (start == nullptr) { + seen_start = true; + } + std::vector::iterator i_type = _right_types.begin(); + for (std::vector::iterator i = _right.begin(); i != _right.end(); ++i, ++i_type) { + if (*i == start) { + seen_start = true; + } + if (seen_start) { + if (*i_type == ALT) { + Alt::Base *a = static_cast(*i); + if (a->is(Alt::LINK)) { + ys += (*a).multi_ys()(track); + } + } else if (*i_type == SYMBOL) { + Symbol::Base *s = static_cast(*i); + ys += (*s).multi_ys()(track); + } + } + if (*i == end) { + break; + } + } + + return ys; + } +// Yield::Size sum_ys_right(void* start, void* end, size_t track, bool exclude_end) { +// Yield::Size ys; +// +// bool seen_start = false; +// if (start == nullptr) { +// seen_start = true; +// } +// std::vector::reverse_iterator i_type = _right_types.rbegin(); +// std::vector::reverse_iterator i_end = _right.rend(); +// if (exclude_end && (_right.size() > 1)) { +// i_end = std::prev(std::prev(_right.rend())); +// } +// for (std::vector::reverse_iterator i = _right.rbegin(); i != i_end; ++i, ++i_type) { +// if (*i == start) { +// seen_start = true; +// } +// if (seen_start) { +// if (*i_type == ALT) { +// Alt::Base *a = static_cast(*i); +// if (a->is(Alt::LINK)) { +// ys += (*a).multi_ys()(track); +// } +// } else if (*i_type == SYMBOL) { +// Symbol::Base *s = static_cast(*i); +// ys += (*s).multi_ys()(track); +// } +// } +// if (*i == end) { +// break; +// } +// } +// +// return ys; +// } + + Init_Indices_Outside() : num_outside_nts(0) { + } + + void visit(Symbol::Terminal &s) { + stack_component(&s, SYMBOL); + } + void visit(Symbol::NT &s) { + stack_component(&s, SYMBOL); + } + void visit(Alt::Link &a) { + if (a.nt->is_partof_outside() || a.is_outside_inside_transition()) { + num_outside_nts++; + std::cerr << "gefunden: " << *a.nt->name << "\n"; + /* drop the link itself as it has been previously added via the + * visit(Alt::Base) call */ + _left.pop_back(); + _left_types.pop_back(); + } + } + void visit(Alt::Base &a) { + stack_component(&a, ALT); + } + void visit(Fn_Arg::Base &f) { + stack_component(&f, FN_ARG); + } +}; + +#endif /* SRC_OUTSIDE_MIDDLE_END_HH_ */ diff --git a/src/symbol.cc b/src/symbol.cc index 8ed3da4a9..c1b903e0e 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -46,6 +46,7 @@ #include "type/backtrace.hh" #include "alt.hh" +#include "outside/middle_end.hh" Symbol::Base::Base(std::string *n, Type t, const Loc &l) @@ -750,8 +751,16 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, left_indices[track] = left; right_indices[track] = right; - for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) - (*i)->init_indices(left, right, k, track); + for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) { + if ((*i)->is_partof_outside()) { + Init_Indices_Outside v = Init_Indices_Outside(); + (*i)->traverse(v); + //v.assert_one_outside_nt(); + v.init_indices(left, right, k, track); + } else { + (*i)->init_indices(left, right, k, track); + } + } } Statement::Base *Symbol::NT::build_return_empty(const Code::Mode &mode) { From 342821ab76d06c59ad8ddd3823c3541527432a30 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 18 Apr 2023 13:55:52 +0200 Subject: [PATCH 044/189] initialize yield sizes for outside->inside transition --- src/outside/grammar_transformation.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 7d6a54a19..e6a7d3217 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -662,7 +662,6 @@ struct Collect_and_Insert_outside_axioms : public Visitor { Alt::Link *link = new Alt::Link((*i)->name, Loc()); link->name = (*i)->name; link->set_tracks((*i)->tracks(), (*i)->track_pos()); - link->init_multi_ys(); link->top_level = Bool(true); nt_axiom->alts.push_back(link); } @@ -738,10 +737,8 @@ void inject_outside_inside_transition( for (unsigned int track = 0; track < rhs_inside->tracks(); ++track) { comptracks->push_back(f); } - // TODO(smj): check of really done via check_semantics() link->set_tracks(rhs_inside->tracks(), rhs_inside->track_pos()); - // link->init_multi_ys(); - // link->is_outside_inside_transition = true; + link->set_outside_inside_transition(); if (rhs_inside->tracks() == 1) { link->filters.push_back(f); } else { @@ -826,6 +823,16 @@ void Grammar::convert_to_outside() { (*i).second->init_links(*this); } + // initialize yield sizes for the outside-inside transition, which is one of + // the alternatives of the new outside axiom + for (std::list::iterator a = axiom->alts.begin(); + a != axiom->alts.end(); ++a) { + if ((*a)->is(Alt::LINK) && + (dynamic_cast(*a)->is_outside_inside_transition())) { + (*a)->init_multi_ys(); + } + } + // TODO(smj): is this the proper location? /* NT-table dimension optimization (all start quadratic, but depending on * yield size, some NT-tables can be reduced to linear or even constant From f37ed54e209ca9ef39583a16e36951b6fabb1574 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 19 Apr 2023 10:24:56 +0200 Subject: [PATCH 045/189] carry over nt parameters from inside lhs NT to outside rhs NT call --- src/outside/grammar_transformation.cc | 30 +++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index e6a7d3217..21d128917 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -533,6 +533,30 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { alt.m_ys = lhs_nt->multi_ys(); alt.name = lhs_nt->name; + /* the inside lhs NT might have nt Parameters. If so we need to ensure + * that the rhs call of the now outside NT is done with the same nt + * parameters. The body is copy & paste from Expr/new.cc + */ + if (lhs_nt->ntargs().size() > 0) { + std::list *_args = new std::list(); + for (std::list::const_iterator i = + lhs_nt->ntargs().begin(); + i != lhs_nt->ntargs().end(); ++i) { + Para_Decl::Simple *p = dynamic_cast(*i); + if (p) { + _args->push_back(new Expr::Vacc(p->name())); + } else { + Para_Decl::Multi *p = dynamic_cast(*i); + for (std::list::const_iterator j = + p->list().begin(); + j != p->list().end(); ++j) { + _args->push_back(new Expr::Vacc((*j)->name())); + } + } + } + alt.set_ntparas(Loc(), _args); + } + // d) alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); @@ -823,8 +847,10 @@ void Grammar::convert_to_outside() { (*i).second->init_links(*this); } - // initialize yield sizes for the outside-inside transition, which is one of - // the alternatives of the new outside axiom + /* initialize yield sizes for the outside-inside transition, which is one of + * the alternatives of the new outside axiom. + * Can only be done AFTER links have been initialized, i.e. nt members are + * no longer nullptr. */ for (std::list::iterator a = axiom->alts.begin(); a != axiom->alts.end(); ++a) { if ((*a)->is(Alt::LINK) && From 06460b5d5b962d1cc7ae71e3b6a719da60932954 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 19 Apr 2023 12:00:13 +0200 Subject: [PATCH 046/189] clean up *.o *.d and binaries for outside tests --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 5a8f35b3c..883028383 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ CXXFILES = $(wildcard src/*.cc) \ $(wildcard src/outside/*.cc) \ $(UNITTEST_CXX) \ $(MODTESTS_CXX) \ + $(MODOUTSIDETESTS_CXX) \ $(wildcard testdata/test/*.cc) \ rtlib/string.cc \ @@ -98,6 +99,7 @@ TEMP = $(GEN_CXXFILES) $(OFILES) $(DEPS)\ src/position.hh \ gapc \ $(MODTESTS) \ + $(MODOUTSIDETESTS) \ stats testdata/modtest/stats.o \ src/version.txt src/version.cc src/version.d src/version.o \ testdata/config-tests/config.finished \ From 0464e54d00d8e18d8ddf9a588d1adcdc91f7f40e Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 19 Apr 2023 15:14:18 +0200 Subject: [PATCH 047/189] a dirty version that gives indices for all elements of mini_twoLevelIL --- src/alt.hh | 2 +- src/outside/middle_end.hh | 134 ++++++++++++++++++++++++-------------- src/symbol.cc | 7 ++ 3 files changed, 92 insertions(+), 51 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index 4c46d96d3..65b2a0985 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -136,7 +136,7 @@ class Base { virtual Base *clone() = 0; - protected: + public: std::vector left_indices; std::vector right_indices; diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 8b50ab82d..5f13c7ddb 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -36,6 +36,62 @@ Expr::Base *next_index_var(unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs); +struct Init_Indices_Outside_Args : public Visitor { + size_t track; + unsigned int k; + Alt::Base *topalt; + + Init_Indices_Outside_Args(unsigned int &k, size_t track) { + this->track = track; + this->k = k; + } + + void visit_end(Alt::Simple &a) { + /* initialize left and right indices, simply by taking the + * left index of the left-most argument and + * right index of the right-most argument */ + (&a)->Base::init_indices( + (*a.args.begin())->left_indices.at(track), + (*a.args.rbegin())->right_indices.at(track), + k, + track); + } + + void visit(Fn_Arg::Alt &f) { + f.left_indices = f.alt->left_indices; + f.right_indices = f.alt->right_indices; + } +}; + +struct Init_Indices_OutsideNT : public Visitor { + size_t track; + unsigned int k; + Alt::Base *topalt; + + Init_Indices_OutsideNT(Alt::Base *topalt, unsigned int &k, size_t track) { + this->track = track; + this->k = k; + this->topalt = topalt; + } + +// void visit(Fn_Arg::Alt &f) { +// +// } + + void visit(Alt::Link &s) { + if (s.nt->is(Symbol::NONTERMINAL) && s.nt->is_partof_outside()) { + std::cerr << *s.nt->name << "\n"; + if (topalt->left_indices.at(track) && topalt->right_indices.at(track)) { + (&s)->Base::init_indices( + topalt->left_indices.at(track), + topalt->right_indices.at(track), + k, + track); + } + } + } +}; + struct Init_Indices_Outside : public Visitor { private: int num_outside_nts = 0; @@ -45,6 +101,8 @@ struct Init_Indices_Outside : public Visitor { std::vector _right; std::vector _right_types; + Alt::Link *_outsideNT = nullptr; + void stack_component(void *ptr_component, Type t) { if (num_outside_nts < 1) { _left.push_back(ptr_component); @@ -79,15 +137,15 @@ struct Init_Indices_Outside : public Visitor { Yield::Size rhs_ys(rhs); rhs_ys += ys; - std::cerr << "L: " << lhs << " - " << ys << " - " << rhs; +// std::cerr << "L: " << lhs << " - " << ys << " - " << rhs; if (*i_type == ALT) { Alt::Base *a = static_cast(*i); //std::cerr << (*a).left_indices.size() << " <- Alt\n"; if (a->is(Alt::LINK)) { - std::cerr << " : " << *(dynamic_cast(a)->name); +// std::cerr << " : " << *(dynamic_cast(a)->name); next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); - std::cerr << " next_var = " << *next_var; +// std::cerr << " next_var = " << *next_var; // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -116,23 +174,23 @@ struct Init_Indices_Outside : public Visitor { a->init_indices(res.first, res.second, k, track); // end copy and paste - std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; +// std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; } else if (a->is(Alt::SIMPLE)) { - std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); +// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); } } else if (*i_type == FN_ARG) { Fn_Arg::Base *f = static_cast(*i); - std::cerr << " : Fn_Arg"; +// std::cerr << " : Fn_Arg"; //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; //continue; } else if (*i_type == SYMBOL) { Symbol::Base *s = static_cast(*i); - std::cerr << " : Symbol"; +// std::cerr << " : Symbol"; //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; // accum_ys_center_to_left += (*s).multi_ys()(track); } - std::cerr << "\n"; +// std::cerr << "\n"; } @@ -149,15 +207,15 @@ struct Init_Indices_Outside : public Visitor { Yield::Size rhs_ys(rhs); rhs_ys += ys; - std::cerr << "R: " << lhs << " - " << ys << " - " << rhs; +// std::cerr << "R: " << lhs << " - " << ys << " - " << rhs; if (*i_type == ALT) { Alt::Base *a = static_cast(*i); //std::cerr << (*a).left_indices.size() << " <- Alt\n"; if (a->is(Alt::LINK)) { - std::cerr << " : " << *(dynamic_cast(a)->name); +// std::cerr << " : " << *(dynamic_cast(a)->name); next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); - std::cerr << " next_var = " << *next_var; +// std::cerr << " next_var = " << *next_var; // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -189,23 +247,23 @@ struct Init_Indices_Outside : public Visitor { a->init_indices(res.first, res.second, k, track); // end copy and paste - std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; +// std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; } else if (a->is(Alt::SIMPLE)) { - std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); +// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); } } else if (*i_type == FN_ARG) { Fn_Arg::Base *f = static_cast(*i); - std::cerr << " : Fn_Arg"; +// std::cerr << " : Fn_Arg"; //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; //continue; } else if (*i_type == SYMBOL) { Symbol::Base *s = static_cast(*i); - std::cerr << " : Symbol"; +// std::cerr << " : Symbol"; //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; // accum_ys_center_to_left += (*s).multi_ys()(track); } - std::cerr << "\n"; +// std::cerr << "\n"; } // std::vector::reverse_iterator ir_type = _left_types.rbegin(); @@ -271,6 +329,15 @@ struct Init_Indices_Outside : public Visitor { // // std::cerr << "\n"; // } + + if ((_left.size() == 0) && (_right.size() == 0) && _outsideNT) { + if (_outsideNT->is_outside_inside_transition()) { + _outsideNT->Base::init_indices(left->plus(right), right->minus(left), k, track); + } else { + // must be a direct link to an non-terminal + _outsideNT->Base::init_indices(left, right, k, track); + } + } } Yield::Size sum_ys_left(void* start, void* end, size_t track) { @@ -333,40 +400,6 @@ struct Init_Indices_Outside : public Visitor { return ys; } -// Yield::Size sum_ys_right(void* start, void* end, size_t track, bool exclude_end) { -// Yield::Size ys; -// -// bool seen_start = false; -// if (start == nullptr) { -// seen_start = true; -// } -// std::vector::reverse_iterator i_type = _right_types.rbegin(); -// std::vector::reverse_iterator i_end = _right.rend(); -// if (exclude_end && (_right.size() > 1)) { -// i_end = std::prev(std::prev(_right.rend())); -// } -// for (std::vector::reverse_iterator i = _right.rbegin(); i != i_end; ++i, ++i_type) { -// if (*i == start) { -// seen_start = true; -// } -// if (seen_start) { -// if (*i_type == ALT) { -// Alt::Base *a = static_cast(*i); -// if (a->is(Alt::LINK)) { -// ys += (*a).multi_ys()(track); -// } -// } else if (*i_type == SYMBOL) { -// Symbol::Base *s = static_cast(*i); -// ys += (*s).multi_ys()(track); -// } -// } -// if (*i == end) { -// break; -// } -// } -// -// return ys; -// } Init_Indices_Outside() : num_outside_nts(0) { } @@ -385,6 +418,7 @@ struct Init_Indices_Outside : public Visitor { * visit(Alt::Base) call */ _left.pop_back(); _left_types.pop_back(); + _outsideNT = &a; } } void visit(Alt::Base &a) { diff --git a/src/symbol.cc b/src/symbol.cc index c1b903e0e..ed22f776b 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -757,6 +757,13 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, (*i)->traverse(v); //v.assert_one_outside_nt(); v.init_indices(left, right, k, track); + + Init_Indices_Outside_Args v2 = Init_Indices_Outside_Args(k, track); + (*i)->traverse(v2); + + Init_Indices_OutsideNT v3 = Init_Indices_OutsideNT(*i, k, track); + (*i)->traverse(v3); + } else { (*i)->init_indices(left, right, k, track); } From 9f2465766a29c88239ee3bb13cb20c85cd4c7494 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 19 Apr 2023 17:01:50 +0200 Subject: [PATCH 048/189] don't sum via nullptr + fallback to left/right of NT when linking to outside NT --- src/outside/middle_end.hh | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 5f13c7ddb..9e8a8bef9 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -40,10 +40,14 @@ struct Init_Indices_Outside_Args : public Visitor { size_t track; unsigned int k; Alt::Base *topalt; + Expr::Vacc *left; + Expr::Vacc *right; - Init_Indices_Outside_Args(unsigned int &k, size_t track) { + Init_Indices_Outside_Args(Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { this->track = track; this->k = k; + this->left = left; + this->right = right; } void visit_end(Alt::Simple &a) { @@ -58,8 +62,15 @@ struct Init_Indices_Outside_Args : public Visitor { } void visit(Fn_Arg::Alt &f) { - f.left_indices = f.alt->left_indices; - f.right_indices = f.alt->right_indices; +// if (f.alt_ref()->is(Alt::LINK) && (dynamic_cast(f.alt_ref()))->nt->is_partof_outside()) { +// // fallback if linking to the ouside NT +// f.init_indices(left, right, k, track); +// } else { + if ((f.alt->left_indices.at(track) != nullptr) && (f.alt->right_indices.at(track) != nullptr)) { + f.init_indices(f.alt->left_indices.at(track), f.alt->right_indices.at(track), k, track); + } else { + f.init_indices(left, right, k, track); + } } }; @@ -80,7 +91,7 @@ struct Init_Indices_OutsideNT : public Visitor { void visit(Alt::Link &s) { if (s.nt->is(Symbol::NONTERMINAL) && s.nt->is_partof_outside()) { - std::cerr << *s.nt->name << "\n"; + //std::cerr << *s.nt->name << "\n"; if (topalt->left_indices.at(track) && topalt->right_indices.at(track)) { (&s)->Base::init_indices( topalt->left_indices.at(track), @@ -124,8 +135,8 @@ struct Init_Indices_Outside : public Visitor { void init_indices(Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track) { assert_one_outside_nt(); - Yield::Size ys_all = sum_ys_left(nullptr, nullptr, track); - Expr::Base *last_var = next_index_var(k, track, NULL, left, right, ys_all, Yield::Size(), ys_all); + Yield::Size ys_all = sum_ys_left(*_left.begin(), nullptr, track); + Expr::Base *last_var = next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all); Expr::Base *next_var = last_var; Yield::Size lhs; @@ -195,7 +206,8 @@ struct Init_Indices_Outside : public Visitor { // RIGHT of outside NT - lhs = sum_ys_right(nullptr, nullptr, track); + if (_right.size() > 0) { + lhs = sum_ys_right(*_right.begin(), nullptr, track); // next_var = right; last_var = right; lhs.set(0, 0); @@ -265,6 +277,7 @@ struct Init_Indices_Outside : public Visitor { // std::cerr << "\n"; } + } // std::vector::reverse_iterator ir_type = _left_types.rbegin(); // //Expr::Base *last_var = next_index_var(k, track, NULL, left, right, ys_all, Yield::Size(), ys_all); @@ -344,8 +357,8 @@ struct Init_Indices_Outside : public Visitor { Yield::Size ys; bool seen_start = false; - if (start == nullptr) { - seen_start = true; + if (start == *_left.end()) { + return ys; } std::vector::iterator i_type = _left_types.begin(); for (std::vector::iterator i = _left.begin(); i != _left.end(); ++i, ++i_type) { @@ -374,8 +387,8 @@ struct Init_Indices_Outside : public Visitor { Yield::Size ys; bool seen_start = false; - if (start == nullptr) { - seen_start = true; + if (start == *_right.end()) { + return ys; } std::vector::iterator i_type = _right_types.begin(); for (std::vector::iterator i = _right.begin(); i != _right.end(); ++i, ++i_type) { @@ -413,7 +426,7 @@ struct Init_Indices_Outside : public Visitor { void visit(Alt::Link &a) { if (a.nt->is_partof_outside() || a.is_outside_inside_transition()) { num_outside_nts++; - std::cerr << "gefunden: " << *a.nt->name << "\n"; + //std::cerr << "gefunden: " << *a.nt->name << "\n"; /* drop the link itself as it has been previously added via the * visit(Alt::Base) call */ _left.pop_back(); From b61f18e76b2c2f44ce516c037221be45961a65a5 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 19 Apr 2023 17:02:25 +0200 Subject: [PATCH 049/189] pass fallback left/right --- src/symbol.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/symbol.cc b/src/symbol.cc index ed22f776b..ea8ae77a4 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -756,9 +756,10 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, Init_Indices_Outside v = Init_Indices_Outside(); (*i)->traverse(v); //v.assert_one_outside_nt(); + //std::cerr << "NT: " << *this->name << "\n"; v.init_indices(left, right, k, track); - Init_Indices_Outside_Args v2 = Init_Indices_Outside_Args(k, track); + Init_Indices_Outside_Args v2 = Init_Indices_Outside_Args(left, right, k, track); (*i)->traverse(v2); Init_Indices_OutsideNT v3 = Init_Indices_OutsideNT(*i, k, track); From b1b069dcbb6de1d43937b29d66eb8f321902bc99 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 20 Apr 2023 13:07:11 +0200 Subject: [PATCH 050/189] deal with ntargs --- src/alt.hh | 12 ++++++++++ src/expr/new.cc | 21 +++++++++++++----- src/expr/new.hh | 2 ++ src/outside/grammar_transformation.cc | 32 +++++++++++++-------------- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index 65b2a0985..eccad04fa 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -506,6 +506,12 @@ class Simple : public Base { public: void set_ntparas(std::list *l); + const std::list get_ntparas() { + return ntparas; + } + void remove_ntparas() { + ntparas.clear(); + } void ntparas_to_dot(std::ostream &out); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); @@ -634,6 +640,12 @@ class Link : public Base { public: void set_ntparas(const Loc &loc, std::list *l); + const std::list get_ntparas() { + return ntparas; + } + void remove_ntparas() { + ntparas.clear(); + } void ntparas_to_dot(std::ostream &out); bool check_ntparas(); diff --git a/src/expr/new.cc b/src/expr/new.cc index 6b41659a5..ad98bc2bc 100644 --- a/src/expr/new.cc +++ b/src/expr/new.cc @@ -39,17 +39,26 @@ void Expr::This::put(std::ostream &s) const { #include "../para_decl.hh" -void Expr::New::add_args(const std::list &args) { +std::list *sync_ntparams(const std::list &args) { + std::list *expr_args = new std::list(); for (std::list::const_iterator i = args.begin(); - i != args.end(); ++i) { + i != args.end(); ++i) { Para_Decl::Simple *p = dynamic_cast(*i); if (p) { - args_.push_back(new Expr::Vacc(p->name())); + expr_args->push_back(new Expr::Vacc(p->name())); } else { Para_Decl::Multi *p = dynamic_cast(*i); - for (std::list::const_iterator j = p->list().begin(); - j != p->list().end(); ++j) - args_.push_back(new Expr::Vacc((*j)->name())); + for (std::list::const_iterator j = + p->list().begin(); + j != p->list().end(); ++j) { + expr_args->push_back(new Expr::Vacc((*j)->name())); + } } } + return expr_args; +} + +void Expr::New::add_args(const std::list &args) { + std::list *params = sync_ntparams(args); + args_.insert(args_.end(), params->begin(), params->end()); } diff --git a/src/expr/new.hh b/src/expr/new.hh index 5e5fffd7f..205fe0bc9 100644 --- a/src/expr/new.hh +++ b/src/expr/new.hh @@ -33,6 +33,8 @@ namespace Type { class Base; } +std::list *sync_ntparams(const std::list &args); + namespace Expr { class New : public Base { private: diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 21d128917..8cd8f7c47 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -22,6 +22,7 @@ }}} */ #include "grammar_transformation.hh" +#include "../expr/new.hh" #include bool Grammar::check_outside_parse_empty_word() { @@ -507,17 +508,20 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { * production rule, but if we clone all components will have different * pointers as they are different objects. Thus, we * a) safely store the original rhs NT (orig_rhs_nt) away + * + non-terminal parameters * b) create a second clone of the rhs NT, but prefix its name with * "outside_" and remove all alternatives * c) next, we overwrite the current rhs NT of the Alt::Link with the * lhs NT (which was already prefixed with "outside_") * d) NOW clone the modified production rule * e) restore the state before cloning of the inside production rule + * + non-terminal parameters */ // a) Symbol::NT *orig_rhs_nt = dynamic_cast(alt.nt)->clone( dynamic_cast(alt.nt)->track_pos(), true); + std::list orig_alt_ntparas = alt.get_ntparas(); // b) Symbol::NT *outside_rhs_nt = dynamic_cast(alt.nt)->clone( @@ -537,26 +541,12 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { * that the rhs call of the now outside NT is done with the same nt * parameters. The body is copy & paste from Expr/new.cc */ + alt.remove_ntparas(); if (lhs_nt->ntargs().size() > 0) { - std::list *_args = new std::list(); - for (std::list::const_iterator i = - lhs_nt->ntargs().begin(); - i != lhs_nt->ntargs().end(); ++i) { - Para_Decl::Simple *p = dynamic_cast(*i); - if (p) { - _args->push_back(new Expr::Vacc(p->name())); - } else { - Para_Decl::Multi *p = dynamic_cast(*i); - for (std::list::const_iterator j = - p->list().begin(); - j != p->list().end(); ++j) { - _args->push_back(new Expr::Vacc((*j)->name())); - } - } - } - alt.set_ntparas(Loc(), _args); + alt.set_ntparas(Loc(), sync_ntparams(lhs_nt->ntargs())); } + // d) alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); @@ -564,6 +554,11 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { alt.nt = orig_rhs_nt; alt.m_ys = orig_rhs_nt->multi_ys(); alt.name = orig_rhs_nt->name; + if (orig_alt_ntparas.size() > 0) { + alt.set_ntparas(alt.location, &orig_alt_ntparas); + } else { + alt.remove_ntparas(); + } } } } @@ -687,6 +682,9 @@ struct Collect_and_Insert_outside_axioms : public Visitor { link->name = (*i)->name; link->set_tracks((*i)->tracks(), (*i)->track_pos()); link->top_level = Bool(true); + if ((*i)->ntargs().size() > 0) { + link->set_ntparas(Loc(), sync_ntparams((*i)->ntargs())); + } nt_axiom->alts.push_back(link); } From 5d7b146ff12e865d0ea3b63c4f6c1367d4f3c717 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 20 Apr 2023 16:20:48 +0200 Subject: [PATCH 051/189] we need an additional visitor for Fn_Arg, namely AFTER this node has been visited --- src/fn_arg.cc | 1 + src/visitor.cc | 1 + src/visitor.hh | 1 + 3 files changed, 3 insertions(+) diff --git a/src/fn_arg.cc b/src/fn_arg.cc index d46cfc542..0581bf7b5 100644 --- a/src/fn_arg.cc +++ b/src/fn_arg.cc @@ -283,6 +283,7 @@ void Fn_Arg::Alt::traverse(Visitor &v) { v.visit(*dynamic_cast(this)); v.visit(*this); alt->traverse(v); + v.visit_end(*this); } void Fn_Arg::Const::traverse(Visitor &v) { diff --git a/src/visitor.cc b/src/visitor.cc index ce5cd3ef9..d5f7bb9bc 100644 --- a/src/visitor.cc +++ b/src/visitor.cc @@ -47,5 +47,6 @@ void Visitor::visit_end(Alt::Multi &a) {} void Visitor::visit(Fn_Arg::Base &f) {} void Visitor::visit(Fn_Arg::Const &f) {} void Visitor::visit(Fn_Arg::Alt &f) {} +void Visitor::visit_end(Fn_Arg::Alt &f) {} void Visitor::visit_end(Grammar &g) {} diff --git a/src/visitor.hh b/src/visitor.hh index 828d2718d..50b49bfca 100644 --- a/src/visitor.hh +++ b/src/visitor.hh @@ -57,6 +57,7 @@ class Visitor { virtual void visit(Fn_Arg::Const &f); virtual void visit(Fn_Arg::Alt &f); + virtual void visit_end(Fn_Arg::Alt &f); virtual void visit_end(Grammar &g); }; From adfbf2252daa2e3e2b8e87bf203e54caf7e6b03a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 20 Apr 2023 16:22:06 +0200 Subject: [PATCH 052/189] adding a doc string --- src/visitor.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/visitor.hh b/src/visitor.hh index 50b49bfca..83f8f7270 100644 --- a/src/visitor.hh +++ b/src/visitor.hh @@ -57,6 +57,8 @@ class Visitor { virtual void visit(Fn_Arg::Const &f); virtual void visit(Fn_Arg::Alt &f); + + // first visit the subtree of Fn_Arg->Alt and only then visit this virtual void visit_end(Fn_Arg::Alt &f); virtual void visit_end(Grammar &g); From b4c97229e168e45f6b1a73dc881eb1a47e6717ae Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 20 Apr 2023 16:23:40 +0200 Subject: [PATCH 053/189] no moving boundary left + visit Fn_Arg AFTER subtree has been visited --- src/outside/middle_end.hh | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 9e8a8bef9..97a2f919b 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -61,7 +61,7 @@ struct Init_Indices_Outside_Args : public Visitor { track); } - void visit(Fn_Arg::Alt &f) { + void visit_end(Fn_Arg::Alt &f) { // if (f.alt_ref()->is(Alt::LINK) && (dynamic_cast(f.alt_ref()))->nt->is_partof_outside()) { // // fallback if linking to the ouside NT // f.init_indices(left, right, k, track); @@ -155,31 +155,39 @@ struct Init_Indices_Outside : public Visitor { //std::cerr << (*a).left_indices.size() << " <- Alt\n"; if (a->is(Alt::LINK)) { // std::cerr << " : " << *(dynamic_cast(a)->name); + next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); // std::cerr << " next_var = " << *next_var; // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); - if (lhs.low() == lhs.high()) { - res.first = last_var->plus(lhs.low()); - if (ys.low() == ys.high()) { - res.second = last_var->plus(lhs.low())->plus(ys.low()); - lhs += ys; - } else { - if (rhs.low() == rhs.high()) { - res.second = next_var->minus(rhs.low()); + if (ys_all.low() == ys_all.high()) { + // no moving boundary between here and the outside_nt + res.first = last_var->minus(rhs_ys.low()); + res.second = last_var->minus(rhs.low()); + lhs += ys; + } else { + if (lhs.low() == lhs.high()) { + res.first = last_var->plus(lhs.low()); + if (ys.low() == ys.high()) { + res.second = last_var->plus(lhs.low())->plus(ys.low()); lhs += ys; } else { - res.second = next_var; - lhs.set(0, 0); - last_var = next_var; + if (rhs.low() == rhs.high()) { + res.second = next_var->minus(rhs.low()); + lhs += ys; + } else { + res.second = next_var; + lhs.set(0, 0); + last_var = next_var; + } } + } else { + assert(rhs_ys.low() == rhs_ys.high()); + res.first = next_var->minus(rhs_ys.low()); + res.second = next_var->minus(rhs.low()); + lhs += ys; } - } else { - assert(rhs_ys.low() == rhs_ys.high()); - res.first = next_var->minus(rhs_ys.low()); - res.second = next_var->minus(rhs.low()); - lhs += ys; } a->init_indices(res.first, res.second, k, track); From 4bb5e1a57dfce4590c04b84978f1075e01b1a8c7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 20 Apr 2023 16:53:57 +0200 Subject: [PATCH 054/189] don't clone but create fresh axiom NT to avoid wrong table dimensions --- src/outside/grammar_transformation.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 8cd8f7c47..1da6a0bf9 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -664,8 +664,8 @@ struct Collect_and_Insert_outside_axioms : public Visitor { + "outside grammar generation!"); } - // let's use the current inside axiom as template ... - nt_axiom = grammar.axiom->clone(grammar.axiom->track_pos(), false); + // create a fresh new non terminal which will become the outside axiom + nt_axiom = new Symbol::NT(axiom_name, Loc()); // but change its name nt_axiom->name = axiom_name; nt_axiom->orig_name = nt_axiom->name; From 899c02de2328918dcb0fbe28994316b8d38b534a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 21 Apr 2023 10:21:52 +0200 Subject: [PATCH 055/189] also index parameterized terminals + constant terminals --- src/outside/middle_end.hh | 73 +++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 97a2f919b..ea15867c2 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -150,12 +150,12 @@ struct Init_Indices_Outside : public Visitor { // std::cerr << "L: " << lhs << " - " << ys << " - " << rhs; - if (*i_type == ALT) { + if ((*i_type == ALT) || (*i_type == FN_ARG)) { Alt::Base *a = static_cast(*i); + Fn_Arg::Base *f = static_cast(*i); //std::cerr << (*a).left_indices.size() << " <- Alt\n"; - if (a->is(Alt::LINK)) { + if (a->is(Alt::LINK) || f->is(Fn_Arg::CONST)) { // std::cerr << " : " << *(dynamic_cast(a)->name); - next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); // std::cerr << " next_var = " << *next_var; @@ -190,20 +190,24 @@ struct Init_Indices_Outside : public Visitor { } } - a->init_indices(res.first, res.second, k, track); + if (*i_type == ALT) { + a->init_indices(res.first, res.second, k, track); + } else { + f->init_indices(res.first, res.second, k, track); + } // end copy and paste // std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; - } else if (a->is(Alt::SIMPLE)) { -// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); +// } else if (a->is(Alt::SIMPLE)) { +//// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); } - } else if (*i_type == FN_ARG) { - Fn_Arg::Base *f = static_cast(*i); -// std::cerr << " : Fn_Arg"; - //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; - //continue; - } else if (*i_type == SYMBOL) { - Symbol::Base *s = static_cast(*i); +// } else if (*i_type == FN_ARG) { +// Fn_Arg::Base *f = static_cast(*i); +//// std::cerr << " : Fn_Arg"; +// //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; +// //continue; +// } else if (*i_type == SYMBOL) { +// Symbol::Base *s = static_cast(*i); // std::cerr << " : Symbol"; //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; // accum_ys_center_to_left += (*s).multi_ys()(track); @@ -229,10 +233,11 @@ struct Init_Indices_Outside : public Visitor { // std::cerr << "R: " << lhs << " - " << ys << " - " << rhs; - if (*i_type == ALT) { + if ((*i_type == ALT) || (*i_type == FN_ARG)) { Alt::Base *a = static_cast(*i); + Fn_Arg::Base *f = static_cast(*i); //std::cerr << (*a).left_indices.size() << " <- Alt\n"; - if (a->is(Alt::LINK)) { + if (a->is(Alt::LINK) || f->is(Fn_Arg::CONST)) { // std::cerr << " : " << *(dynamic_cast(a)->name); next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); // std::cerr << " next_var = " << *next_var; @@ -264,20 +269,24 @@ struct Init_Indices_Outside : public Visitor { lhs += ys; } - a->init_indices(res.first, res.second, k, track); + if (*i_type == ALT) { + a->init_indices(res.first, res.second, k, track); + } else { + f->init_indices(res.first, res.second, k, track); + } // end copy and paste // std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; - } else if (a->is(Alt::SIMPLE)) { -// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); +// } else if (a->is(Alt::SIMPLE)) { +//// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); } - } else if (*i_type == FN_ARG) { - Fn_Arg::Base *f = static_cast(*i); -// std::cerr << " : Fn_Arg"; - //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; - //continue; - } else if (*i_type == SYMBOL) { - Symbol::Base *s = static_cast(*i); +// } else if (*i_type == FN_ARG) { +// Fn_Arg::Base *f = static_cast(*i); +//// std::cerr << " : Fn_Arg"; +// //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; +// //continue; +// } else if (*i_type == SYMBOL) { +// Symbol::Base *s = static_cast(*i); // std::cerr << " : Symbol"; //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; // accum_ys_center_to_left += (*s).multi_ys()(track); @@ -382,6 +391,15 @@ struct Init_Indices_Outside : public Visitor { } else if (*i_type == SYMBOL) { Symbol::Base *s = static_cast(*i); ys += (*s).multi_ys()(track); + } else if (*i_type == FN_ARG) { + Fn_Arg::Base *f = static_cast(*i); + if (f->is(Fn_Arg::CONST)) { + // TODO(sjanssen) isn't there a better method to check for constants? +// dynamic_cast(f)->alt_ref() +// if (name->rfind("CONST_", 0) != 0) { + + ys += (*f).multi_ys()(track); + } } } if (*i == end) { @@ -412,6 +430,11 @@ struct Init_Indices_Outside : public Visitor { } else if (*i_type == SYMBOL) { Symbol::Base *s = static_cast(*i); ys += (*s).multi_ys()(track); + } else if (*i_type == FN_ARG) { + Fn_Arg::Base *f = static_cast(*i); + if (f->is(Fn_Arg::CONST)) { // and not Fn_Arg::Alt + ys += (*f).multi_ys()(track); + } } } if (*i == end) { From 75f25550e88ea4f6c7cc0ce2bd0d67f444d7484d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 21 Apr 2023 15:08:45 +0200 Subject: [PATCH 056/189] adding next test from outside_looporder --- testdata/modtest/outside_indices.cc | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 testdata/modtest/outside_indices.cc diff --git a/testdata/modtest/outside_indices.cc b/testdata/modtest/outside_indices.cc new file mode 100644 index 000000000..5fe731227 --- /dev/null +++ b/testdata/modtest/outside_indices.cc @@ -0,0 +1,71 @@ +#include "../../src/driver.hh" +#include "../../src/log.hh" + +#include +#include +#include +#include + +int main(int argc, char **argv) { + std::ostringstream o; + Log log; + log.set_debug(false); + log.set_ostream(o); + + Driver driver; + + if (argc != 2) { + std::cerr << "Call " << *argv << " *.gap-file\n"; + return 1; + } + // === front + // set the file name of the gap-source-code + driver.setFilename(argv[1]); + + // parses the input file and builds the AST + driver.parse(); + + // simply gets the selected grammar, which is either the + // grammar that occurred first in the source code or is the + // one that was named in the parameters on the command line + Grammar *grammar = driver.ast.grammar(); + // Now check the semantic, which does more than the function + // name suggests. The semantic check is embedded in the algorithm + // that links the grammar graph together, and computes yield-sizes. + // If the method returns false, there are some semantic errors, + // which leads to the end of the compilation process. + bool r = grammar->check_semantic(); + if (!r) { + throw LogError("Seen semantic errors."); + } + + // inject rules for outside grammar + grammar->convert_to_outside(); + + // set approx table design + grammar->approx_table_conf(); + + // find what type of input is read + // chars, sequence of ints etc. + driver.ast.derive_temp_alphabet(); + + r = driver.ast.check_signature(); + if (!r) { + return 4; + } + + // apply this to identify standard functions like Min, Max, Exp etc. + driver.ast.derive_roles(); + + + // ------------- back ------------ + grammar->init_list_sizes(); + + grammar->init_indices(); + grammar->init_decls(); + // for cyk (ordering of NT for parsing, see page 101 of the thesis) + grammar->dep_analysis(); + + unsigned int nodeID = 1; + grammar->to_dot(&nodeID, std::cout, 3); +} From 0cc41695484054be1e5d4d3b1d19a226e683a3a0 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 21 Apr 2023 16:07:12 +0200 Subject: [PATCH 057/189] need to call the function of the base class, as otherwise Fn_Arg would aim to initialize it's Alt with inside mechanism! --- src/outside/middle_end.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index ea15867c2..b60a4924b 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -67,9 +67,9 @@ struct Init_Indices_Outside_Args : public Visitor { // f.init_indices(left, right, k, track); // } else { if ((f.alt->left_indices.at(track) != nullptr) && (f.alt->right_indices.at(track) != nullptr)) { - f.init_indices(f.alt->left_indices.at(track), f.alt->right_indices.at(track), k, track); + f.Base::init_indices(f.alt->left_indices.at(track), f.alt->right_indices.at(track), k, track); } else { - f.init_indices(left, right, k, track); + f.Base::init_indices(left, right, k, track); } } }; From 64cce1f2220159d7b965131073f583c408722cad Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 21 Apr 2023 21:29:21 +0200 Subject: [PATCH 058/189] integrating Alt::Multi, which is complicated by the fact that single track components not clearly identify as such --- src/alt.hh | 3 +++ src/outside/middle_end.hh | 57 ++++++++++++++++++++++++++++++++++++--- src/symbol.cc | 5 ++-- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index eccad04fa..20c9b86bb 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -268,6 +268,9 @@ class Base { public: void set_tracks(size_t t, size_t p); + size_t track_pos() const { + return track_pos_; + } // set to public, to allow transmission to outside pendants public: diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index b60a4924b..b307948bf 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -42,6 +42,9 @@ struct Init_Indices_Outside_Args : public Visitor { Alt::Base *topalt; Expr::Vacc *left; Expr::Vacc *right; + bool inMulti = false; + std::vector left_indices; + std::vector right_indices; Init_Indices_Outside_Args(Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { this->track = track; @@ -61,6 +64,24 @@ struct Init_Indices_Outside_Args : public Visitor { track); } + void visit(Alt::Multi &a) { + inMulti = true; + left_indices.clear(); + right_indices.clear(); + } + void visit(Alt::Base &a) { + if (inMulti && a.multi_ys().tracks() == 1) { + left_indices.push_back(a.left_indices.front()); + right_indices.push_back(a.right_indices.front()); + } + } + void visit_end(Alt::Multi &a) { + inMulti = false; + a.left_indices = left_indices; + a.right_indices = right_indices; + } + + void visit_end(Fn_Arg::Alt &f) { // if (f.alt_ref()->is(Alt::LINK) && (dynamic_cast(f.alt_ref()))->nt->is_partof_outside()) { // // fallback if linking to the ouside NT @@ -106,6 +127,9 @@ struct Init_Indices_OutsideNT : public Visitor { struct Init_Indices_Outside : public Visitor { private: int num_outside_nts = 0; + size_t track; + size_t tracks; + std::vector _left; enum Type { ALT, FN_ARG, SYMBOL }; std::vector _left_types; @@ -191,7 +215,11 @@ struct Init_Indices_Outside : public Visitor { } if (*i_type == ALT) { - a->init_indices(res.first, res.second, k, track); + if (a->multi_ys().tracks() != this->tracks) { + a->init_indices(res.first, res.second, k, 0); + } else { + a->init_indices(res.first, res.second, k, track); + } } else { f->init_indices(res.first, res.second, k, track); } @@ -270,7 +298,11 @@ struct Init_Indices_Outside : public Visitor { } if (*i_type == ALT) { - a->init_indices(res.first, res.second, k, track); + if (a->multi_ys().tracks() != this->tracks) { + a->init_indices(res.first, res.second, k, 0); + } else { + a->init_indices(res.first, res.second, k, track); + } } else { f->init_indices(res.first, res.second, k, track); } @@ -386,6 +418,13 @@ struct Init_Indices_Outside : public Visitor { if (*i_type == ALT) { Alt::Base *a = static_cast(*i); if (a->is(Alt::LINK)) { + if ((*a).multi_ys().tracks() != this->tracks) { + // must be single track + ys += (*a).multi_ys()(0); + } else { + ys += (*a).multi_ys()(track); + } + } else if (a->is(Alt::MULTI)) { ys += (*a).multi_ys()(track); } } else if (*i_type == SYMBOL) { @@ -426,6 +465,8 @@ struct Init_Indices_Outside : public Visitor { Alt::Base *a = static_cast(*i); if (a->is(Alt::LINK)) { ys += (*a).multi_ys()(track); + } else if (a->is(Alt::MULTI)) { + ys += (*a).multi_ys()(track); } } else if (*i_type == SYMBOL) { Symbol::Base *s = static_cast(*i); @@ -445,16 +486,21 @@ struct Init_Indices_Outside : public Visitor { return ys; } - Init_Indices_Outside() : num_outside_nts(0) { + Init_Indices_Outside(size_t track, size_t tracks) : num_outside_nts(0), track(track), tracks(tracks) { } void visit(Symbol::Terminal &s) { - stack_component(&s, SYMBOL); + if (s.track_pos() == this->track) { + stack_component(&s, SYMBOL); + } } void visit(Symbol::NT &s) { + if ((s.tracks() == this->tracks) || (s.track_pos() == this->track)) { stack_component(&s, SYMBOL); + } } void visit(Alt::Link &a) { +// if (a.track_pos() == track) { if (a.nt->is_partof_outside() || a.is_outside_inside_transition()) { num_outside_nts++; //std::cerr << "gefunden: " << *a.nt->name << "\n"; @@ -464,9 +510,12 @@ struct Init_Indices_Outside : public Visitor { _left_types.pop_back(); _outsideNT = &a; } +// } } void visit(Alt::Base &a) { + if ((a.multi_ys().tracks() == this->tracks) || (a.track_pos() == this->track)) { stack_component(&a, ALT); + } } void visit(Fn_Arg::Base &f) { stack_component(&f, FN_ARG); diff --git a/src/symbol.cc b/src/symbol.cc index ea8ae77a4..19d729bf0 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -751,9 +751,10 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, left_indices[track] = left; right_indices[track] = right; - for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) { + unsigned int c = 0; + for (std::list::iterator i = alts.begin(); i != alts.end(); ++i, ++c) { if ((*i)->is_partof_outside()) { - Init_Indices_Outside v = Init_Indices_Outside(); + Init_Indices_Outside v = Init_Indices_Outside(track, this->tracks_); (*i)->traverse(v); //v.assert_one_outside_nt(); //std::cerr << "NT: " << *this->name << "\n"; From ca075bda4e5c06e92f61a3504d65d28541a19f62 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 25 Apr 2023 19:05:35 +0200 Subject: [PATCH 059/189] clean up --- src/outside/middle_end.hh | 109 +------------------------------------- 1 file changed, 1 insertion(+), 108 deletions(-) diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index b307948bf..cefc629fd 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -172,16 +172,11 @@ struct Init_Indices_Outside : public Visitor { Yield::Size rhs_ys(rhs); rhs_ys += ys; -// std::cerr << "L: " << lhs << " - " << ys << " - " << rhs; - if ((*i_type == ALT) || (*i_type == FN_ARG)) { Alt::Base *a = static_cast(*i); Fn_Arg::Base *f = static_cast(*i); - //std::cerr << (*a).left_indices.size() << " <- Alt\n"; if (a->is(Alt::LINK) || f->is(Fn_Arg::CONST)) { -// std::cerr << " : " << *(dynamic_cast(a)->name); next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); -// std::cerr << " next_var = " << *next_var; // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -224,51 +219,30 @@ struct Init_Indices_Outside : public Visitor { f->init_indices(res.first, res.second, k, track); } // end copy and paste - -// std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; -// } else if (a->is(Alt::SIMPLE)) { -//// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); } -// } else if (*i_type == FN_ARG) { -// Fn_Arg::Base *f = static_cast(*i); -//// std::cerr << " : Fn_Arg"; -// //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; -// //continue; -// } else if (*i_type == SYMBOL) { -// Symbol::Base *s = static_cast(*i); -// std::cerr << " : Symbol"; - //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; -// accum_ys_center_to_left += (*s).multi_ys()(track); } - -// std::cerr << "\n"; } // RIGHT of outside NT if (_right.size() > 0) { lhs = sum_ys_right(*_right.begin(), nullptr, track); -// next_var = right; last_var = right; lhs.set(0, 0); i_type = _right_types.begin(); for (std::vector::iterator i = _right.begin(); i != _right.end(); ++i, ++i_type) { Yield::Size ys = sum_ys_right(*i, *i, track); -// Yield::Size rhs = Yield::Size(Yield::UP); //sum_ys_right(*std::next(i), nullptr, track); Yield::Size rhs = sum_ys_right(*std::next(i), nullptr, track); Yield::Size rhs_ys(rhs); rhs_ys += ys; -// std::cerr << "R: " << lhs << " - " << ys << " - " << rhs; if ((*i_type == ALT) || (*i_type == FN_ARG)) { Alt::Base *a = static_cast(*i); Fn_Arg::Base *f = static_cast(*i); - //std::cerr << (*a).left_indices.size() << " <- Alt\n"; if (a->is(Alt::LINK) || f->is(Fn_Arg::CONST)) { -// std::cerr << " : " << *(dynamic_cast(a)->name); next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); -// std::cerr << " next_var = " << *next_var; + // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -306,92 +280,11 @@ struct Init_Indices_Outside : public Visitor { } else { f->init_indices(res.first, res.second, k, track); } - // end copy and paste - -// std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; -// } else if (a->is(Alt::SIMPLE)) { -//// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); } -// } else if (*i_type == FN_ARG) { -// Fn_Arg::Base *f = static_cast(*i); -//// std::cerr << " : Fn_Arg"; -// //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; -// //continue; -// } else if (*i_type == SYMBOL) { -// Symbol::Base *s = static_cast(*i); -// std::cerr << " : Symbol"; - //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; -// accum_ys_center_to_left += (*s).multi_ys()(track); } - -// std::cerr << "\n"; } } -// std::vector::reverse_iterator ir_type = _left_types.rbegin(); -// //Expr::Base *last_var = next_index_var(k, track, NULL, left, right, ys_all, Yield::Size(), ys_all); -// for (std::vector::reverse_iterator ir = _right.rbegin(); ir != _right.rend(); ++ir, ++ir_type) { -// Yield::Size ys = sum_ys_right(*ir, *ir, track, false); -// Yield::Size rhs = sum_ys_right(*std::next(ir), nullptr, track, false); -// Yield::Size rhs_ys(rhs); -// rhs_ys += ys; -// -// std::cerr << lhs << " - " << ys << " - " << rhs; -// -// if (*i_type == ALT) { -// Alt::Base *a = static_cast(*ir); -// //std::cerr << (*a).left_indices.size() << " <- Alt\n"; -// if (a->is(Alt::LINK)) { -// std::cerr << " : " << *(dynamic_cast(a)->name); -// next_var = next_index_var(k, track, next_var, last_var, last_var, ys, lhs, rhs); -// std::cerr << " next_var = " << *next_var; -// -// // copy and paste from Alt::Simple::init_indices -// std::pair res(0, 0); -// if (lhs.low() == lhs.high()) { -// res.first = last_var->plus(lhs.low()); -// if (ys.low() == ys.high()) { -// res.second = last_var->plus(lhs.low())->plus(ys.low()); -// lhs += ys; -// } else { -// if (rhs.low() == rhs.high()) { -// res.second = next_var->minus(rhs.low()); -// lhs += ys; -// } else { -// res.second = next_var; -// lhs.set(0, 0); -// last_var = next_var; -// } -// } -// } else { -// assert(rhs_ys.low() == rhs_ys.high()); -// res.first = next_var->minus(rhs_ys.low()); -// res.second = next_var->minus(rhs.low()); -// lhs += ys; -// } -// -// a->init_indices(res.first, res.second, k, track); -// // end copy and paste -// -// std::cerr << " (left = " << *res.first << ", right = " << *res.second << ") "; -// } else if (a->is(Alt::SIMPLE)) { -// std::cerr << " : Alt::Simple " << *(dynamic_cast(a)->name); -// } -// } else if (*i_type == FN_ARG) { -// Fn_Arg::Base *f = static_cast(*ir); -// std::cerr << " : Fn_Arg"; -// //std::cerr << (*f).left_indices.size() << " <- Fn_Arg\n"; -// //continue; -// } else if (*i_type == SYMBOL) { -// Symbol::Base *s = static_cast(*ir); -// std::cerr << " : Symbol"; -// //std::cerr << (*s).left_indices.size() << " <- Symbol\n"; -//// accum_ys_center_to_left += (*s).multi_ys()(track); -// } -// -// std::cerr << "\n"; -// } - if ((_left.size() == 0) && (_right.size() == 0) && _outsideNT) { if (_outsideNT->is_outside_inside_transition()) { _outsideNT->Base::init_indices(left->plus(right), right->minus(left), k, track); From 1b03bd504a17cbeea47804db979c4a867edd75ec Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 26 Apr 2023 22:46:28 +0200 Subject: [PATCH 060/189] switch to cleaner method --- src/symbol.cc | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/symbol.cc b/src/symbol.cc index 19d729bf0..d4f09d384 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -754,18 +754,7 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, unsigned int c = 0; for (std::list::iterator i = alts.begin(); i != alts.end(); ++i, ++c) { if ((*i)->is_partof_outside()) { - Init_Indices_Outside v = Init_Indices_Outside(track, this->tracks_); - (*i)->traverse(v); - //v.assert_one_outside_nt(); - //std::cerr << "NT: " << *this->name << "\n"; - v.init_indices(left, right, k, track); - - Init_Indices_Outside_Args v2 = Init_Indices_Outside_Args(left, right, k, track); - (*i)->traverse(v2); - - Init_Indices_OutsideNT v3 = Init_Indices_OutsideNT(*i, k, track); - (*i)->traverse(v3); - + outside_init_indices(*i, left, right, k, track); } else { (*i)->init_indices(left, right, k, track); } From 92c2797f80481e98cb99898c380869b215eb782a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 26 Apr 2023 22:47:37 +0200 Subject: [PATCH 061/189] define header for outside_init_indices --- src/alt.hh | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/alt.hh b/src/alt.hh index 20c9b86bb..7cea7832c 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -50,6 +50,8 @@ // class Filter; #include "adp_mode.hh" +#include "outside/middle_end_fwd.hh" + class Grammar; class Signature_Base; @@ -331,6 +333,13 @@ class Base { void set_partof_outside() { _is_partof_outside = true; } + + virtual void outside_collect_parsers(std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + virtual void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + }; @@ -519,6 +528,15 @@ class Simple : public Base { unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + /* depth first traversal of a grammar subtree to collect all "Parser" (see + * outside/middle_end.hh comment) components left and right of the one + * outside NT link, to later set left/right indices */ + void outside_collect_parsers(std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + private: std::list *insert_index_stmts( std::list *stmts); @@ -662,6 +680,12 @@ class Link : public Base { void set_outside_inside_transition() { _is_outside_inside_transition = true; } + + void outside_collect_parsers(std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -731,6 +755,12 @@ class Block : public Base { void multi_init_calls(const Runtime::Poly &p, size_t base_tracks); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + void outside_collect_parsers(std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + }; @@ -803,6 +833,11 @@ class Multi : public Base { void init_ret_decl(unsigned int i, const std::string &prefix); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + void outside_collect_parsers(std::vector &left, + std::vector &right, + unsigned int &num_outside_nts, + size_t track); + void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; } // namespace Alt From 62fda513a3f4be396d3f084531aba01c12891a10 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 26 Apr 2023 22:47:57 +0200 Subject: [PATCH 062/189] function headers for outside_init_indices --- src/fn_arg.hh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/fn_arg.hh b/src/fn_arg.hh index a6589947a..d8ae23966 100644 --- a/src/fn_arg.hh +++ b/src/fn_arg.hh @@ -42,6 +42,7 @@ #include "expr_fwd.hh" #include "statement_fwd.hh" #include "type_fwd.hh" +#include "outside/middle_end.hh" class Visitor; @@ -155,6 +156,12 @@ class Base { void set_partof_outside() { _is_partof_outside = true; } + virtual void outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + virtual void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -204,6 +211,12 @@ class Alt : public Base { void init_ret_decl(unsigned int i, const std::string &prefix); bool choice_set(); + + void outside_collect_parsers(std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -255,6 +268,11 @@ class Const : public Base { void init_multi_ys(); bool choice_set(); + void outside_collect_parsers(std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track); + void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; } // namespace Fn_Arg From 6e38ec13f01cb48196833883b048271d8d115a8e Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 26 Apr 2023 22:49:21 +0200 Subject: [PATCH 063/189] clean methods to compute indices for outside grammar components --- src/outside/middle_end.cc | 283 +++++++++++++++++++++++++++ src/outside/middle_end.hh | 393 ++------------------------------------ 2 files changed, 303 insertions(+), 373 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 882f51cb1..8f232913e 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -23,6 +23,289 @@ #include "middle_end.hh" + +void Alt::Base::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { +} +void Alt::Simple::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { + + for (std::list::iterator i = args.begin(); i != args.end(); + ++i) { + (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track); + } +} +void Alt::Link::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { + + if (this->nt->is_partof_outside() || this->is_outside_inside_transition()) { + num_outside_nts++; + } else { + Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices)); + if (num_outside_nts < 1) { + left_parsers.push_back(p); + } else { + right_parsers.push_back(p); + } + } +} +void Alt::Block::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { + // as Blocks should have been resolved for all outside components + assert(false); +} +void Alt::Multi::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { + size_t j = 0; + assert(track < list.size()); + std::list::iterator i = list.begin(); + for (; j < track; ++i, ++j) {} + + // each component is in a single-track context + (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, 0); +} + +void Fn_Arg::Base::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { +} +void Fn_Arg::Const::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { + Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices)); + if (num_outside_nts < 1) { + left_parsers.push_back(p); + } else { + right_parsers.push_back(p); + } +} +void Fn_Arg::Alt::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track) { + alt->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track); +} + +Yield::Size sum_ys(std::vector parser, + std::vector::iterator itr_start, + std::vector::iterator itr_end, + size_t track) { + Yield::Size ys; + + for (std::vector::iterator i = itr_start; (i != parser.end()) && (i != itr_end); ++i) { + ys += (*i)->yield_size; + } + + return ys; +} + +void Alt::Base::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} +void Alt::Simple::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { + for (std::list::iterator i = args.begin(); i != args.end(); + ++i) { + (*i)->outside_uppropagate_indices(left, right, track); + } + left_indices[track] = (*args.begin())->left_indices[track]; + if (left_indices[track] == nullptr) { + // fall back if outside NT is leftmost component of alternative + left_indices[track] = left; + } + right_indices[track] = (*args.rbegin())->right_indices[track]; + if (right_indices[track] == nullptr) { + // fall back if outside NT is rightmost component of alternative + right_indices[track] = right; + } +} +void Alt::Link::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { + // Links point to grammar leaves and should already have left/right indices set in phase 2 + if (!this->nt->is_partof_outside()) { + assert(this->left_indices[track]); + assert(this->right_indices[track]); + } +} +void Alt::Block::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { + assert(false); // Alt::Block should have been resolved already +} +void Alt::Multi::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { + size_t j = 0; + assert(track < list.size()); + std::list::iterator i = list.begin(); + for (; j < track; ++i, ++j) {} + + // each component is in a single-track context + (*i)->outside_uppropagate_indices(left, right, 0); + + left_indices[track] = (*i)->left_indices[0]; + right_indices[track] = (*i)->right_indices[0]; +} +void Fn_Arg::Base::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} +void Fn_Arg::Alt::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { + alt->outside_uppropagate_indices(left, right, track); + this->left_indices[track] = alt->left_indices[track]; + this->right_indices[track] = alt->right_indices[track]; +} +void Fn_Arg::Const::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} + +void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { + std::vector left_parser; + std::vector right_parser; + unsigned int num_outside_nts = 0; + + //TODO(smj): how about has_index_overlay?! + + // phase 1: traverse whole sub-tree of alternative (can include multiple levels) and collect + // all grammar components that "parse" subwords from the input (can be empty) + alt->outside_collect_parsers(left_parser, right_parser, num_outside_nts, track); + + // by design, there must be exactly one rhs outside NT in each alternative + // only exception is the transition from outside to inside grammar parts + assert(num_outside_nts == 1); + + // phase 2: based on the collected Parsers, assign left and right indices to Parsers + Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); + Expr::Base *last_var = next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all); + Expr::Base *next_var = last_var; + + Yield::Size lhs; + // LEFT of outside NT + for (std::vector::iterator i = left_parser.begin(); i != left_parser.end(); ++i) { + Yield::Size ys = (*i)->yield_size; + Yield::Size rhs = sum_ys(left_parser, std::next(i), left_parser.end(), track); + Yield::Size rhs_ys(rhs); + rhs_ys += ys; + + next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); + + // copy and paste from Alt::Simple::init_indices + std::pair res(0, 0); + if (ys_all.low() == ys_all.high()) { + // no moving boundary between here and the outside_nt + res.first = last_var->minus(rhs_ys.low()); + res.second = last_var->minus(rhs.low()); + lhs += ys; + } else { + if (lhs.low() == lhs.high()) { + res.first = last_var->plus(lhs.low()); + if (ys.low() == ys.high()) { + res.second = last_var->plus(lhs.low())->plus(ys.low()); + lhs += ys; + } else { + if (rhs.low() == rhs.high()) { + res.second = next_var->minus(rhs.low()); + lhs += ys; + } else { + res.second = next_var; + lhs.set(0, 0); + last_var = next_var; + } + } + } else { + assert(rhs_ys.low() == rhs_ys.high()); + res.first = next_var->minus(rhs_ys.low()); + res.second = next_var->minus(rhs.low()); + lhs += ys; + } + } + if (alt->multi_ys().tracks() > (*i)->left_indices.size()) { + // must be a single track component in a multitrack context + (*i)->left_indices.at(0) = res.first; + (*i)->right_indices.at(0) = res.second; + } else { + (*i)->left_indices.at(track) = res.first; + (*i)->right_indices.at(track) = res.second; + } + } + + // RIGHT of outside NT + if (right_parser.size() > 0) { + lhs = sum_ys(right_parser, right_parser.begin(), right_parser.end(), track); + last_var = right; + lhs.set(0, 0); + for (std::vector::iterator i = right_parser.begin(); i != right_parser.end(); ++i) { + Yield::Size ys = (*i)->yield_size; + Yield::Size rhs = sum_ys(right_parser, std::next(i), right_parser.end(), track); + Yield::Size rhs_ys(rhs); + rhs_ys += ys; + + next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); + + // copy and paste from Alt::Simple::init_indices + std::pair res(0, 0); + if (lhs.low() == lhs.high()) { + res.first = last_var->plus(lhs.low()); + if (ys.low() == ys.high()) { + res.second = last_var->plus(lhs.low())->plus(ys.low()); + lhs += ys; + } else { + if (rhs.low() == rhs.high()) { + // edge case: we encounter right end but need another moving boundary for outside context + next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, Yield::Size(Yield::UP)); + + res.second = next_var->minus(rhs.low()); + lhs += ys; + } else { + res.second = next_var; + lhs.set(0, 0); + last_var = next_var; + } + } + } else { + assert(rhs_ys.low() == rhs_ys.high()); + res.first = next_var->minus(rhs_ys.low()); + res.second = next_var->minus(rhs.low()); + lhs += ys; + } + if (alt->multi_ys().tracks() > (*i)->left_indices.size()) { + // must be a single track component in a multitrack context + (*i)->left_indices.at(0) = res.first; + (*i)->right_indices.at(0) = res.second; + } else { + (*i)->left_indices.at(track) = res.first; + (*i)->right_indices.at(track) = res.second; + } + } + } + + GetOutsideLink v = GetOutsideLink(); + alt->traverse(v); + if ((left_parser.size() == 0) && (right_parser.size() == 0) && v.outside_link) { + if (v.outside_link->is_outside_inside_transition()) { + v.outside_link->Base::init_indices(left->plus(right), right->minus(left), k, track); + } else { + // must be a direct link to an non-terminal + v.outside_link->Base::init_indices(left, right, k, track); + } + } + + // Phase 3: propagate left/right indices from Parser towards the top + alt->outside_uppropagate_indices(left, right, track); + + // Phase 4: set left/right indices of outside NT to the top level left/right indices + v.outside_link->left_indices[track] = alt->left_indices[track]; + v.outside_link->right_indices[track] = alt->right_indices[track]; +} + + Expr::Base *next_index_var(unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs) { diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index cefc629fd..14872ff66 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -24,394 +24,41 @@ #ifndef SRC_OUTSIDE_MIDDLE_END_HH_ #define SRC_OUTSIDE_MIDDLE_END_HH_ -#include "../visitor.hh" -#include "../alt.hh" -#include "../fn_arg.hh" + #include "../symbol.hh" #include "../expr.hh" +#include "../fn_arg.hh" +#include "../alt.hh" #include "../statement.hh" +#include "../visitor.hh" -// copy and paste from alt.cc -Expr::Base *next_index_var(unsigned &k, size_t track, - Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, - const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs); - -struct Init_Indices_Outside_Args : public Visitor { - size_t track; - unsigned int k; - Alt::Base *topalt; - Expr::Vacc *left; - Expr::Vacc *right; - bool inMulti = false; - std::vector left_indices; - std::vector right_indices; - - Init_Indices_Outside_Args(Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { - this->track = track; - this->k = k; - this->left = left; - this->right = right; - } - - void visit_end(Alt::Simple &a) { - /* initialize left and right indices, simply by taking the - * left index of the left-most argument and - * right index of the right-most argument */ - (&a)->Base::init_indices( - (*a.args.begin())->left_indices.at(track), - (*a.args.rbegin())->right_indices.at(track), - k, - track); - } - - void visit(Alt::Multi &a) { - inMulti = true; - left_indices.clear(); - right_indices.clear(); - } - void visit(Alt::Base &a) { - if (inMulti && a.multi_ys().tracks() == 1) { - left_indices.push_back(a.left_indices.front()); - right_indices.push_back(a.right_indices.front()); - } - } - void visit_end(Alt::Multi &a) { - inMulti = false; - a.left_indices = left_indices; - a.right_indices = right_indices; - } - - - void visit_end(Fn_Arg::Alt &f) { -// if (f.alt_ref()->is(Alt::LINK) && (dynamic_cast(f.alt_ref()))->nt->is_partof_outside()) { -// // fallback if linking to the ouside NT -// f.init_indices(left, right, k, track); -// } else { - if ((f.alt->left_indices.at(track) != nullptr) && (f.alt->right_indices.at(track) != nullptr)) { - f.Base::init_indices(f.alt->left_indices.at(track), f.alt->right_indices.at(track), k, track); - } else { - f.Base::init_indices(left, right, k, track); - } - } -}; - -struct Init_Indices_OutsideNT : public Visitor { - size_t track; - unsigned int k; - Alt::Base *topalt; - - Init_Indices_OutsideNT(Alt::Base *topalt, unsigned int &k, size_t track) { - this->track = track; - this->k = k; - this->topalt = topalt; - } - -// void visit(Fn_Arg::Alt &f) { -// -// } - - void visit(Alt::Link &s) { - if (s.nt->is(Symbol::NONTERMINAL) && s.nt->is_partof_outside()) { - //std::cerr << *s.nt->name << "\n"; - if (topalt->left_indices.at(track) && topalt->right_indices.at(track)) { - (&s)->Base::init_indices( - topalt->left_indices.at(track), - topalt->right_indices.at(track), - k, - track); - } - } - } -}; - -struct Init_Indices_Outside : public Visitor { - private: - int num_outside_nts = 0; - size_t track; - size_t tracks; - - std::vector _left; - enum Type { ALT, FN_ARG, SYMBOL }; - std::vector _left_types; - std::vector _right; - std::vector _right_types; - - Alt::Link *_outsideNT = nullptr; - - void stack_component(void *ptr_component, Type t) { - if (num_outside_nts < 1) { - _left.push_back(ptr_component); - _left_types.push_back(t); - } else { - _right.push_back(ptr_component); - _right_types.push_back(t); - } - } - - void assert_one_outside_nt() { - // by design, there must be exactly one rhs outside NT in each alternative - // only exception is the transition from outside to inside grammar parts - assert(num_outside_nts == 1); - } - +class Parser { public: + Yield::Size yield_size; + std::vector &left_indices; + std::vector &right_indices; - void init_indices(Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track) { - assert_one_outside_nt(); - - Yield::Size ys_all = sum_ys_left(*_left.begin(), nullptr, track); - Expr::Base *last_var = next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all); - Expr::Base *next_var = last_var; - - Yield::Size lhs; - // LEFT of outside NT - std::vector::iterator i_type = _left_types.begin(); - for (std::vector::iterator i = _left.begin(); i != _left.end(); ++i, ++i_type) { - Yield::Size ys = sum_ys_left(*i, *i, track); - Yield::Size rhs = sum_ys_left(*std::next(i), nullptr, track); - Yield::Size rhs_ys(rhs); - rhs_ys += ys; - - if ((*i_type == ALT) || (*i_type == FN_ARG)) { - Alt::Base *a = static_cast(*i); - Fn_Arg::Base *f = static_cast(*i); - if (a->is(Alt::LINK) || f->is(Fn_Arg::CONST)) { - next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); - - // copy and paste from Alt::Simple::init_indices - std::pair res(0, 0); - if (ys_all.low() == ys_all.high()) { - // no moving boundary between here and the outside_nt - res.first = last_var->minus(rhs_ys.low()); - res.second = last_var->minus(rhs.low()); - lhs += ys; - } else { - if (lhs.low() == lhs.high()) { - res.first = last_var->plus(lhs.low()); - if (ys.low() == ys.high()) { - res.second = last_var->plus(lhs.low())->plus(ys.low()); - lhs += ys; - } else { - if (rhs.low() == rhs.high()) { - res.second = next_var->minus(rhs.low()); - lhs += ys; - } else { - res.second = next_var; - lhs.set(0, 0); - last_var = next_var; - } - } - } else { - assert(rhs_ys.low() == rhs_ys.high()); - res.first = next_var->minus(rhs_ys.low()); - res.second = next_var->minus(rhs.low()); - lhs += ys; - } - } - - if (*i_type == ALT) { - if (a->multi_ys().tracks() != this->tracks) { - a->init_indices(res.first, res.second, k, 0); - } else { - a->init_indices(res.first, res.second, k, track); - } - } else { - f->init_indices(res.first, res.second, k, track); - } - // end copy and paste - } - } - } - - - // RIGHT of outside NT - if (_right.size() > 0) { - lhs = sum_ys_right(*_right.begin(), nullptr, track); - last_var = right; - lhs.set(0, 0); - i_type = _right_types.begin(); - for (std::vector::iterator i = _right.begin(); i != _right.end(); ++i, ++i_type) { - Yield::Size ys = sum_ys_right(*i, *i, track); - Yield::Size rhs = sum_ys_right(*std::next(i), nullptr, track); - Yield::Size rhs_ys(rhs); - rhs_ys += ys; - - - if ((*i_type == ALT) || (*i_type == FN_ARG)) { - Alt::Base *a = static_cast(*i); - Fn_Arg::Base *f = static_cast(*i); - if (a->is(Alt::LINK) || f->is(Fn_Arg::CONST)) { - next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); - - - // copy and paste from Alt::Simple::init_indices - std::pair res(0, 0); - if (lhs.low() == lhs.high()) { - res.first = last_var->plus(lhs.low()); - if (ys.low() == ys.high()) { - res.second = last_var->plus(lhs.low())->plus(ys.low()); - lhs += ys; - } else { - if (rhs.low() == rhs.high()) { - // edge case: we encounter right end but need another moving boundary for outside context - next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, Yield::Size(Yield::UP)); - - res.second = next_var->minus(rhs.low()); - lhs += ys; - } else { - res.second = next_var; - lhs.set(0, 0); - last_var = next_var; - } - } - } else { - assert(rhs_ys.low() == rhs_ys.high()); - res.first = next_var->minus(rhs_ys.low()); - res.second = next_var->minus(rhs.low()); - lhs += ys; - } - - if (*i_type == ALT) { - if (a->multi_ys().tracks() != this->tracks) { - a->init_indices(res.first, res.second, k, 0); - } else { - a->init_indices(res.first, res.second, k, track); - } - } else { - f->init_indices(res.first, res.second, k, track); - } - } - } - } - } - - if ((_left.size() == 0) && (_right.size() == 0) && _outsideNT) { - if (_outsideNT->is_outside_inside_transition()) { - _outsideNT->Base::init_indices(left->plus(right), right->minus(left), k, track); - } else { - // must be a direct link to an non-terminal - _outsideNT->Base::init_indices(left, right, k, track); - } - } + Parser(Yield::Size ys, std::vector &left_indices, std::vector &right_indices) : left_indices(left_indices), right_indices(right_indices) { + this->yield_size = ys; } +}; - Yield::Size sum_ys_left(void* start, void* end, size_t track) { - Yield::Size ys; - - bool seen_start = false; - if (start == *_left.end()) { - return ys; - } - std::vector::iterator i_type = _left_types.begin(); - for (std::vector::iterator i = _left.begin(); i != _left.end(); ++i, ++i_type) { - if (*i == start) { - seen_start = true; - } - if (seen_start) { - if (*i_type == ALT) { - Alt::Base *a = static_cast(*i); - if (a->is(Alt::LINK)) { - if ((*a).multi_ys().tracks() != this->tracks) { - // must be single track - ys += (*a).multi_ys()(0); - } else { - ys += (*a).multi_ys()(track); - } - } else if (a->is(Alt::MULTI)) { - ys += (*a).multi_ys()(track); - } - } else if (*i_type == SYMBOL) { - Symbol::Base *s = static_cast(*i); - ys += (*s).multi_ys()(track); - } else if (*i_type == FN_ARG) { - Fn_Arg::Base *f = static_cast(*i); - if (f->is(Fn_Arg::CONST)) { - // TODO(sjanssen) isn't there a better method to check for constants? -// dynamic_cast(f)->alt_ref() -// if (name->rfind("CONST_", 0) != 0) { - - ys += (*f).multi_ys()(track); - } - } - } - if (*i == end) { - break; - } - } +#include "../alt.hh" - return ys; - } - Yield::Size sum_ys_right(void* start, void* end, size_t track) { - Yield::Size ys; +void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track); - bool seen_start = false; - if (start == *_right.end()) { - return ys; - } - std::vector::iterator i_type = _right_types.begin(); - for (std::vector::iterator i = _right.begin(); i != _right.end(); ++i, ++i_type) { - if (*i == start) { - seen_start = true; - } - if (seen_start) { - if (*i_type == ALT) { - Alt::Base *a = static_cast(*i); - if (a->is(Alt::LINK)) { - ys += (*a).multi_ys()(track); - } else if (a->is(Alt::MULTI)) { - ys += (*a).multi_ys()(track); - } - } else if (*i_type == SYMBOL) { - Symbol::Base *s = static_cast(*i); - ys += (*s).multi_ys()(track); - } else if (*i_type == FN_ARG) { - Fn_Arg::Base *f = static_cast(*i); - if (f->is(Fn_Arg::CONST)) { // and not Fn_Arg::Alt - ys += (*f).multi_ys()(track); - } - } - } - if (*i == end) { - break; - } - } - - return ys; - } +// copy and paste from alt.cc +Expr::Base *next_index_var(unsigned &k, size_t track, + Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, + const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs); - Init_Indices_Outside(size_t track, size_t tracks) : num_outside_nts(0), track(track), tracks(tracks) { - } +struct GetOutsideLink : public Visitor { + Alt::Link *outside_link = nullptr; - void visit(Symbol::Terminal &s) { - if (s.track_pos() == this->track) { - stack_component(&s, SYMBOL); - } - } - void visit(Symbol::NT &s) { - if ((s.tracks() == this->tracks) || (s.track_pos() == this->track)) { - stack_component(&s, SYMBOL); - } - } void visit(Alt::Link &a) { -// if (a.track_pos() == track) { if (a.nt->is_partof_outside() || a.is_outside_inside_transition()) { - num_outside_nts++; - //std::cerr << "gefunden: " << *a.nt->name << "\n"; - /* drop the link itself as it has been previously added via the - * visit(Alt::Base) call */ - _left.pop_back(); - _left_types.pop_back(); - _outsideNT = &a; + this->outside_link = &a; } -// } - } - void visit(Alt::Base &a) { - if ((a.multi_ys().tracks() == this->tracks) || (a.track_pos() == this->track)) { - stack_component(&a, ALT); - } - } - void visit(Fn_Arg::Base &f) { - stack_component(&f, FN_ARG); } }; From fcf3d52656cad189282e7b1171cabd3582fc088b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 26 Apr 2023 23:36:49 +0200 Subject: [PATCH 064/189] revert visibility back to protected for left/right_indices --- src/alt.hh | 13 +++++++++---- src/outside/middle_end.cc | 11 +++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index 7cea7832c..ea0324209 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -138,11 +138,19 @@ class Base { virtual Base *clone() = 0; - public: + protected: std::vector left_indices; std::vector right_indices; public: + Expr::Base *get_left_index(size_t track) { + assert(left_indices.size() > track); + return left_indices[track]; + } + Expr::Base *get_right_index(size_t track) { + assert(right_indices.size() > track); + return right_indices[track]; + } Statement::Var_Decl *ret_decl; inline bool is(Type t) { @@ -270,9 +278,6 @@ class Base { public: void set_tracks(size_t t, size_t p); - size_t track_pos() const { - return track_pos_; - } // set to public, to allow transmission to outside pendants public: diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 8f232913e..a6eb0db9c 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -155,14 +155,14 @@ void Alt::Multi::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right // each component is in a single-track context (*i)->outside_uppropagate_indices(left, right, 0); - left_indices[track] = (*i)->left_indices[0]; - right_indices[track] = (*i)->right_indices[0]; + left_indices[track] = (*i)->get_left_index(0); + right_indices[track] = (*i)->get_right_index(0); } void Fn_Arg::Base::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} void Fn_Arg::Alt::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { alt->outside_uppropagate_indices(left, right, track); - this->left_indices[track] = alt->left_indices[track]; - this->right_indices[track] = alt->right_indices[track]; + this->left_indices[track] = alt->get_left_index(track); + this->right_indices[track] = alt->get_right_index(track); } void Fn_Arg::Const::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} @@ -301,8 +301,7 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u alt->outside_uppropagate_indices(left, right, track); // Phase 4: set left/right indices of outside NT to the top level left/right indices - v.outside_link->left_indices[track] = alt->left_indices[track]; - v.outside_link->right_indices[track] = alt->right_indices[track]; + v.outside_link->init_indices(alt->get_left_index(track), alt->get_right_index(track), k, track); } From eba15f8d07e9fa602b502fe298ea64131f662d12 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 26 Apr 2023 23:41:23 +0200 Subject: [PATCH 065/189] newline --- src/alt.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/alt.hh b/src/alt.hh index ea0324209..66a7f5e3e 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -52,7 +52,6 @@ #include "outside/middle_end_fwd.hh" - class Grammar; class Signature_Base; class Visitor; From 7ce5750c8b6f39b6e697ddbeb75ab4f15a4ea1cc Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 27 Apr 2023 11:35:38 +0200 Subject: [PATCH 066/189] DRY: function next_index_var --- src/alt.cc | 23 ++++++++------ src/alt.hh | 10 +++--- src/outside/middle_end.cc | 67 ++++++--------------------------------- src/outside/middle_end.hh | 5 --- 4 files changed, 28 insertions(+), 77 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index 952568040..34b3c7dde 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1068,9 +1068,10 @@ void Alt::Simple::reset() { // by local ys-guards -Expr::Base *Alt::Simple::next_index_var(unsigned &k, size_t track, +Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, - const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs) { + const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, + std::list *loops) { if (ys.low() != ys.high()) { if (rhs.low() == rhs.high()) { return right; @@ -1106,13 +1107,15 @@ Expr::Base *Alt::Simple::next_index_var(unsigned &k, size_t track, cond, new Expr::Less_Eq (ivar, last_var->plus(lhs_ys.high()))); } - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), ivar, index.first); - // flag this variable as being an iterator e.g. in for-loops, - // such that it won't have a trailing indent for code generation - loopvariable->set_itr(true); - Statement::For *f = new Statement::For (loopvariable, cond); - loops.push_back(f); + if (loops != nullptr) { + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), ivar, index.first); + // flag this variable as being an iterator e.g. in for-loops, + // such that it won't have a trailing indent for code generation + loopvariable->set_itr(true); + Statement::For *f = new Statement::For (loopvariable, cond); + loops->push_back(f); + } return ivar; } } else { @@ -1144,7 +1147,7 @@ void Alt::Simple::init_indices( rhs_ys += ys; next_var = next_index_var( - k, track, next_var, last_var, right, ys, lhs, rhs); + k, track, next_var, last_var, right, ys, lhs, rhs, &this->loops); std::pair res(0, 0); if (lhs.low() == lhs.high()) { diff --git a/src/alt.hh b/src/alt.hh index 66a7f5e3e..9bfc02379 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -68,6 +68,11 @@ namespace Alt { */ enum Type { SIMPLE, LINK, BLOCK, MULTI }; +Expr::Base *next_index_var(unsigned &k, size_t track, + Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, + const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, + std::list *loops); + class Base { private: /* @@ -413,11 +418,6 @@ class Simple : public Base { void traverse(Visitor &v); private: - Expr::Base *next_index_var( - unsigned &k, size_t track, Expr::Base *next_var, - Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, - const Yield::Size &lhs, const Yield::Size &rhs); - // FIXME convert callers Yield::Poly rhs_ys_min_rest( const std::list::iterator &i, diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index a6eb0db9c..d56fe86ee 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -171,7 +171,12 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u std::vector right_parser; unsigned int num_outside_nts = 0; - //TODO(smj): how about has_index_overlay?! +// //TODO(smj): how about has_index_overlay?! +// if (alt->is(Alt::SIMPLE)) { +// if (dynamic_cast(alt)->has_index_overlay()) { +// std::cerr << "hier hab ich den Salat " << *dynamic_cast(alt)->name << " ==========\n"; +// } +// } // phase 1: traverse whole sub-tree of alternative (can include multiple levels) and collect // all grammar components that "parse" subwords from the input (can be empty) @@ -183,7 +188,7 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u // phase 2: based on the collected Parsers, assign left and right indices to Parsers Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); - Expr::Base *last_var = next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all); + Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all, nullptr); Expr::Base *next_var = last_var; Yield::Size lhs; @@ -194,7 +199,7 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u Yield::Size rhs_ys(rhs); rhs_ys += ys; - next_var = next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs); + next_var = Alt::next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs, nullptr); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -247,7 +252,7 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u Yield::Size rhs_ys(rhs); rhs_ys += ys; - next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs); + next_var = Alt::next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs, nullptr); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -259,7 +264,7 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u } else { if (rhs.low() == rhs.high()) { // edge case: we encounter right end but need another moving boundary for outside context - next_var = next_index_var(k, track, next_var, last_var, right, ys, lhs, Yield::Size(Yield::UP)); + next_var = Alt::next_index_var(k, track, next_var, last_var, right, ys, lhs, Yield::Size(Yield::UP), nullptr); res.second = next_var->minus(rhs.low()); lhs += ys; @@ -304,55 +309,3 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u v.outside_link->init_indices(alt->get_left_index(track), alt->get_right_index(track), k, track); } - -Expr::Base *next_index_var(unsigned &k, size_t track, - Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, - const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs) { - if (ys.low() != ys.high()) { - if (rhs.low() == rhs.high()) { - return right; - } else { - std::ostringstream o; - o << "t_" << track << "_k_" << k; - k++; - Expr::Vacc *ivar = new Expr::Vacc(new std::string(o.str())); - - assert(lhs.low() == lhs.high()); - std::pair index(0, 0); - - Yield::Size lhs_ys(lhs); - lhs_ys += ys; - - if (rhs.high() == Yield::UP) { - index.first = last_var->plus(lhs_ys.low()); - } else { - // e.g. second maxsize filter in grammar/forloops5 - Expr::Cond *ce = new Expr::Cond( - new Expr::Greater_Eq(right->minus( - last_var->plus(lhs_ys.low())), rhs.high()), - right->minus(rhs.high()), last_var->plus(lhs_ys.low())); - index.first = ce; - } - - index.second = right->minus(rhs.low()); - - Expr::Base *cond = new Expr::Less_Eq(ivar, index.second); - // e.g. first maxsize filter in grammar/forloops5 - if (lhs_ys.high() < Yield::UP) { - cond = new Expr::And( - cond, new Expr::Less_Eq (ivar, last_var->plus(lhs_ys.high()))); - } - - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), ivar, index.first); - // flag this variable as being an iterator e.g. in for-loops, - // such that it won't have a trailing indent for code generation - loopvariable->set_itr(true); - Statement::For *f = new Statement::For (loopvariable, cond); - //loops.push_back(f); - return ivar; - } - } else { - return next_var; - } -} diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 14872ff66..3c2f18b1f 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -47,11 +47,6 @@ class Parser { void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track); -// copy and paste from alt.cc -Expr::Base *next_index_var(unsigned &k, size_t track, - Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, - const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs); - struct GetOutsideLink : public Visitor { Alt::Link *outside_link = nullptr; From c0c6b47e3bc8fc569f34d774fb53b6b8fc427793 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 27 Apr 2023 13:31:07 +0200 Subject: [PATCH 067/189] propagate loops member --- src/alt.cc | 17 ++--- src/alt.hh | 15 ++-- src/fn_arg.hh | 9 ++- src/gapc.cc | 5 -- src/outside/middle_end.cc | 151 ++++++++++++++++---------------------- src/outside/middle_end.hh | 4 +- 6 files changed, 88 insertions(+), 113 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index 34b3c7dde..4899f2c43 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1107,15 +1107,14 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, cond, new Expr::Less_Eq (ivar, last_var->plus(lhs_ys.high()))); } - if (loops != nullptr) { - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), ivar, index.first); - // flag this variable as being an iterator e.g. in for-loops, - // such that it won't have a trailing indent for code generation - loopvariable->set_itr(true); - Statement::For *f = new Statement::For (loopvariable, cond); - loops->push_back(f); - } + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), ivar, index.first); + // flag this variable as being an iterator e.g. in for-loops, + // such that it won't have a trailing indent for code generation + loopvariable->set_itr(true); + Statement::For *f = new Statement::For (loopvariable, cond); + loops->push_back(f); + return ivar; } } else { diff --git a/src/alt.hh b/src/alt.hh index 9bfc02379..40380bfd3 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -346,7 +346,8 @@ class Base { virtual void outside_collect_parsers(std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); virtual void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -538,7 +539,8 @@ class Simple : public Base { void outside_collect_parsers(std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); private: @@ -688,7 +690,8 @@ class Link : public Base { void outside_collect_parsers(std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -762,7 +765,8 @@ class Block : public Base { void outside_collect_parsers(std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -840,7 +844,8 @@ class Multi : public Base { void outside_collect_parsers(std::vector &left, std::vector &right, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; diff --git a/src/fn_arg.hh b/src/fn_arg.hh index d8ae23966..849e9d4ec 100644 --- a/src/fn_arg.hh +++ b/src/fn_arg.hh @@ -160,7 +160,8 @@ class Base { std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); virtual void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -215,7 +216,8 @@ class Alt : public Base { void outside_collect_parsers(std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -271,7 +273,8 @@ class Const : public Base { void outside_collect_parsers(std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track); + size_t track, + std::list &simple_loops); void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); }; } // namespace Fn_Arg diff --git a/src/gapc.cc b/src/gapc.cc index 5327947d7..6dbba7673 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -644,11 +644,6 @@ class Main { } grammar->init_indices(); - unsigned int nodeID = 1; - grammar->to_dot(&nodeID, opts.plotgrammar_stream(), opts.plot_grammar); - - opts.plotgrammar_stream_->flush(); - exit(99); grammar->init_decls(); // for cyk (ordering of NT for parsing, see page 101 of the thesis) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index d56fe86ee..60d3518c5 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -28,29 +28,33 @@ void Alt::Base::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { + size_t track, + std::list &simple_loops) { } void Alt::Simple::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { + size_t track, + std::list &simple_loops + ) { for (std::list::iterator i = args.begin(); i != args.end(); ++i) { - (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track); + (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track, this->loops); } } void Alt::Link::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { + size_t track, + std::list &simple_loops) { if (this->nt->is_partof_outside() || this->is_outside_inside_transition()) { num_outside_nts++; } else { - Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices)); + Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices), simple_loops); if (num_outside_nts < 1) { left_parsers.push_back(p); } else { @@ -62,7 +66,8 @@ void Alt::Block::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { + size_t track, + std::list &simple_loops) { // as Blocks should have been resolved for all outside components assert(false); } @@ -70,28 +75,31 @@ void Alt::Multi::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { + size_t track, + std::list &simple_loops) { size_t j = 0; assert(track < list.size()); std::list::iterator i = list.begin(); for (; j < track; ++i, ++j) {} // each component is in a single-track context - (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, 0); + (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, 0, simple_loops); } void Fn_Arg::Base::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { + size_t track, + std::list &simple_loops) { } void Fn_Arg::Const::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { - Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices)); + size_t track, + std::list &simple_loops) { + Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices), simple_loops); if (num_outside_nts < 1) { left_parsers.push_back(p); } else { @@ -102,8 +110,9 @@ void Fn_Arg::Alt::outside_collect_parsers( std::vector &left_parsers, std::vector &right_parsers, unsigned int &num_outside_nts, - size_t track) { - alt->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track); + size_t track, + std::list &simple_loops) { + alt->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track, simple_loops); } Yield::Size sum_ys(std::vector parser, @@ -166,44 +175,19 @@ void Fn_Arg::Alt::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *righ } void Fn_Arg::Const::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} -void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { - std::vector left_parser; - std::vector right_parser; - unsigned int num_outside_nts = 0; - -// //TODO(smj): how about has_index_overlay?! -// if (alt->is(Alt::SIMPLE)) { -// if (dynamic_cast(alt)->has_index_overlay()) { -// std::cerr << "hier hab ich den Salat " << *dynamic_cast(alt)->name << " ==========\n"; -// } -// } - - // phase 1: traverse whole sub-tree of alternative (can include multiple levels) and collect - // all grammar components that "parse" subwords from the input (can be empty) - alt->outside_collect_parsers(left_parser, right_parser, num_outside_nts, track); - - // by design, there must be exactly one rhs outside NT in each alternative - // only exception is the transition from outside to inside grammar parts - assert(num_outside_nts == 1); - - // phase 2: based on the collected Parsers, assign left and right indices to Parsers - Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); - Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all, nullptr); - Expr::Base *next_var = last_var; - +void iterate_indices(bool is_left_not_right, std::vector *parser, unsigned int &k, size_t track, unsigned int tracks, Expr::Base *next_var, Expr::Base *last_var, Expr::Vacc *upstream_index, Yield::Size ys_all) { Yield::Size lhs; - // LEFT of outside NT - for (std::vector::iterator i = left_parser.begin(); i != left_parser.end(); ++i) { + for (std::vector::iterator i = parser->begin(); i != parser->end(); ++i) { Yield::Size ys = (*i)->yield_size; - Yield::Size rhs = sum_ys(left_parser, std::next(i), left_parser.end(), track); + Yield::Size rhs = sum_ys(*parser, std::next(i), parser->end(), track); Yield::Size rhs_ys(rhs); rhs_ys += ys; - next_var = Alt::next_index_var(k, track, next_var, last_var, left, ys, lhs, rhs, nullptr); + next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, ys, lhs, rhs, &((*i)->simple_loops)); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); - if (ys_all.low() == ys_all.high()) { + if (is_left_not_right && (ys_all.low() == ys_all.high())) { // no moving boundary between here and the outside_nt res.first = last_var->minus(rhs_ys.low()); res.second = last_var->minus(rhs.low()); @@ -216,6 +200,10 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u lhs += ys; } else { if (rhs.low() == rhs.high()) { + if (!is_left_not_right) { + // edge case: we encounter right end but need another moving boundary for outside context + next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, ys, lhs, Yield::Size(Yield::UP), &((*i)->simple_loops)); + } res.second = next_var->minus(rhs.low()); lhs += ys; } else { @@ -231,7 +219,7 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u lhs += ys; } } - if (alt->multi_ys().tracks() > (*i)->left_indices.size()) { + if (tracks > (*i)->left_indices.size()) { // must be a single track component in a multitrack context (*i)->left_indices.at(0) = res.first; (*i)->right_indices.at(0) = res.second; @@ -240,55 +228,40 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u (*i)->right_indices.at(track) = res.second; } } +} - // RIGHT of outside NT - if (right_parser.size() > 0) { - lhs = sum_ys(right_parser, right_parser.begin(), right_parser.end(), track); - last_var = right; - lhs.set(0, 0); - for (std::vector::iterator i = right_parser.begin(); i != right_parser.end(); ++i) { - Yield::Size ys = (*i)->yield_size; - Yield::Size rhs = sum_ys(right_parser, std::next(i), right_parser.end(), track); - Yield::Size rhs_ys(rhs); - rhs_ys += ys; +void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { + std::vector left_parser; + std::vector right_parser; + unsigned int num_outside_nts = 0; + +// //TODO(smj): how about has_index_overlay?! +// if (alt->is(Alt::SIMPLE)) { +// if (dynamic_cast(alt)->has_index_overlay()) { +// std::cerr << "hier hab ich den Salat " << *dynamic_cast(alt)->name << " ==========\n"; +// } +// } - next_var = Alt::next_index_var(k, track, next_var, last_var, right, ys, lhs, rhs, nullptr); + // phase 1: traverse whole sub-tree of alternative (can include multiple levels) and collect + // all grammar components that "parse" subwords from the input (can be empty) + std::list loops; + alt->outside_collect_parsers(left_parser, right_parser, num_outside_nts, track, loops); - // copy and paste from Alt::Simple::init_indices - std::pair res(0, 0); - if (lhs.low() == lhs.high()) { - res.first = last_var->plus(lhs.low()); - if (ys.low() == ys.high()) { - res.second = last_var->plus(lhs.low())->plus(ys.low()); - lhs += ys; - } else { - if (rhs.low() == rhs.high()) { - // edge case: we encounter right end but need another moving boundary for outside context - next_var = Alt::next_index_var(k, track, next_var, last_var, right, ys, lhs, Yield::Size(Yield::UP), nullptr); + // by design, there must be exactly one rhs outside NT in each alternative + // only exception is the transition from outside to inside grammar parts + assert(num_outside_nts == 1); - res.second = next_var->minus(rhs.low()); - lhs += ys; - } else { - res.second = next_var; - lhs.set(0, 0); - last_var = next_var; - } - } - } else { - assert(rhs_ys.low() == rhs_ys.high()); - res.first = next_var->minus(rhs_ys.low()); - res.second = next_var->minus(rhs.low()); - lhs += ys; - } - if (alt->multi_ys().tracks() > (*i)->left_indices.size()) { - // must be a single track component in a multitrack context - (*i)->left_indices.at(0) = res.first; - (*i)->right_indices.at(0) = res.second; - } else { - (*i)->left_indices.at(track) = res.first; - (*i)->right_indices.at(track) = res.second; - } - } + // phase 2: based on the collected Parsers, assign left and right indices to Parsers + Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); + Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all, &loops); + Expr::Base *next_var = last_var; + + // for grammar components LEFT of outside NT + iterate_indices(true, &left_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, left, ys_all); + // for grammar components RIGHT of outside NT + if (right_parser.size() > 0) { + last_var = right; + iterate_indices(false, &right_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, right, ys_all); } GetOutsideLink v = GetOutsideLink(); diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 3c2f18b1f..0c8a4abdf 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -37,9 +37,9 @@ class Parser { Yield::Size yield_size; std::vector &left_indices; std::vector &right_indices; + std::list &simple_loops; - Parser(Yield::Size ys, std::vector &left_indices, std::vector &right_indices) : left_indices(left_indices), right_indices(right_indices) { - this->yield_size = ys; + Parser(Yield::Size ys, std::vector &left_indices, std::vector &right_indices, std::list &simple_loops) : yield_size(ys), left_indices(left_indices), right_indices(right_indices), simple_loops(simple_loops) { } }; From 5f0404d1183c5a75b0218946eff260e7dc819957 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 27 Apr 2023 16:14:13 +0200 Subject: [PATCH 068/189] reverse order in which right parsers are traversed and flip YS operations, i.e. minus -> plus, first -> second --- src/alt.hh | 5 ++- src/outside/middle_end.cc | 64 +++++++++++++++++++++++++---------- src/outside/middle_end_fwd.hh | 15 ++++++++ 3 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 src/outside/middle_end_fwd.hh diff --git a/src/alt.hh b/src/alt.hh index 40380bfd3..edd9c02ee 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -424,8 +424,11 @@ class Simple : public Base { const std::list::iterator &i, const std::list::iterator &end) const; - std::list loops; + public: std::list foreach_loops; + + private: + std::list loops; std::list body_stmts; Statement::If *guards; diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 60d3518c5..8a0b6ed3e 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -58,7 +58,7 @@ void Alt::Link::outside_collect_parsers( if (num_outside_nts < 1) { left_parsers.push_back(p); } else { - right_parsers.push_back(p); + right_parsers.insert(right_parsers.begin(), p); } } } @@ -103,7 +103,7 @@ void Fn_Arg::Const::outside_collect_parsers( if (num_outside_nts < 1) { left_parsers.push_back(p); } else { - right_parsers.push_back(p); + right_parsers.insert(right_parsers.begin(), p); } } void Fn_Arg::Alt::outside_collect_parsers( @@ -187,35 +187,57 @@ void iterate_indices(bool is_left_not_right, std::vector *parser, unsig // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); - if (is_left_not_right && (ys_all.low() == ys_all.high())) { + if ((ys_all.low() == ys_all.high())) { // no moving boundary between here and the outside_nt - res.first = last_var->minus(rhs_ys.low()); - res.second = last_var->minus(rhs.low()); + if (is_left_not_right) { + res.first = last_var->minus(rhs_ys.low()); + res.second = last_var->minus(rhs.low()); + } else { + res.second = last_var->plus(rhs_ys.low()); + res.first = last_var->plus(rhs.low()); + } lhs += ys; } else { if (lhs.low() == lhs.high()) { - res.first = last_var->plus(lhs.low()); + if (is_left_not_right) { + res.first = last_var->plus(lhs.low()); + } else { + res.second = last_var->minus(lhs.low()); + } if (ys.low() == ys.high()) { - res.second = last_var->plus(lhs.low())->plus(ys.low()); + if (is_left_not_right) { + res.second = last_var->plus(lhs.low())->plus(ys.low()); + } else { + res.first = last_var->minus(lhs.low())->minus(ys.low()); + } lhs += ys; } else { if (rhs.low() == rhs.high()) { - if (!is_left_not_right) { - // edge case: we encounter right end but need another moving boundary for outside context - next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, ys, lhs, Yield::Size(Yield::UP), &((*i)->simple_loops)); + if (is_left_not_right) { + res.second = next_var->minus(rhs.low()); + } else { + res.first = next_var->plus(rhs.low()); } - res.second = next_var->minus(rhs.low()); lhs += ys; } else { - res.second = next_var; + if (is_left_not_right) { + res.second = next_var; + } else { + res.first = next_var; + } lhs.set(0, 0); last_var = next_var; } } } else { assert(rhs_ys.low() == rhs_ys.high()); - res.first = next_var->minus(rhs_ys.low()); - res.second = next_var->minus(rhs.low()); + if (is_left_not_right) { + res.first = next_var->minus(rhs_ys.low()); + res.second = next_var->minus(rhs.low()); + } else { + res.second = next_var->plus(rhs_ys.low()); + res.first = next_var->plus(rhs.low()); + } lhs += ys; } } @@ -245,6 +267,9 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u // phase 1: traverse whole sub-tree of alternative (can include multiple levels) and collect // all grammar components that "parse" subwords from the input (can be empty) std::list loops; + if (alt->is(Alt::SIMPLE)) { + loops = dynamic_cast(alt)->loops; + } alt->outside_collect_parsers(left_parser, right_parser, num_outside_nts, track, loops); // by design, there must be exactly one rhs outside NT in each alternative @@ -252,15 +277,15 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u assert(num_outside_nts == 1); // phase 2: based on the collected Parsers, assign left and right indices to Parsers + // for grammar components LEFT of outside NT Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all, &loops); Expr::Base *next_var = last_var; - - // for grammar components LEFT of outside NT iterate_indices(true, &left_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, left, ys_all); // for grammar components RIGHT of outside NT if (right_parser.size() > 0) { - last_var = right; + ys_all = sum_ys(right_parser, right_parser.begin(), right_parser.end(), track); + last_var = Alt::next_index_var(k, track, right, last_var, right, ys_all, Yield::Size(), ys_all, &loops); iterate_indices(false, &right_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, right, ys_all); } @@ -280,5 +305,10 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u // Phase 4: set left/right indices of outside NT to the top level left/right indices v.outside_link->init_indices(alt->get_left_index(track), alt->get_right_index(track), k, track); + + if (alt->is(Alt::SIMPLE)) { + dynamic_cast(alt)->loops.insert(dynamic_cast(alt)->loops.begin(), loops.begin(), loops.end()); + } + } diff --git a/src/outside/middle_end_fwd.hh b/src/outside/middle_end_fwd.hh new file mode 100644 index 000000000..01b066985 --- /dev/null +++ b/src/outside/middle_end_fwd.hh @@ -0,0 +1,15 @@ +/* + * middle_end_fwd.hh + * + * Created on: Apr 26, 2023 + * Author: sjanssen + */ + +#ifndef SRC_OUTSIDE_MIDDLE_END_FWD_HH_ +#define SRC_OUTSIDE_MIDDLE_END_FWD_HH_ + + +class Parser; + + +#endif /* SRC_OUTSIDE_MIDDLE_END_FWD_HH_ */ From 47de9bdc7967e4ce783269be6758eb15b484444d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 27 Apr 2023 16:32:50 +0200 Subject: [PATCH 069/189] linting --- src/alt.hh | 76 ++++++++-------- src/fn_arg.hh | 9 +- src/outside/grammar_transformation.cc | 2 +- src/outside/middle_end.cc | 119 +++++++++++++++++--------- src/outside/middle_end.hh | 18 ++-- src/outside/middle_end_fwd.hh | 28 ++++-- src/symbol.cc | 3 +- 7 files changed, 166 insertions(+), 89 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index edd9c02ee..55bf4db8f 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -343,13 +343,14 @@ class Base { _is_partof_outside = true; } - virtual void outside_collect_parsers(std::vector &left_parsers, - std::vector &right_parsers, - unsigned int &num_outside_nts, - size_t track, - std::list &simple_loops); - virtual void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); - + virtual void outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track, + std::list &simple_loops); + virtual void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -425,10 +426,10 @@ class Simple : public Base { const std::list::iterator &end) const; public: - std::list foreach_loops; + std::list loops; private: - std::list loops; + std::list foreach_loops; std::list body_stmts; Statement::If *guards; @@ -539,12 +540,14 @@ class Simple : public Base { /* depth first traversal of a grammar subtree to collect all "Parser" (see * outside/middle_end.hh comment) components left and right of the one * outside NT link, to later set left/right indices */ - void outside_collect_parsers(std::vector &left_parsers, - std::vector &right_parsers, - unsigned int &num_outside_nts, - size_t track, - std::list &simple_loops); - void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + void outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track, + std::list &simple_loops); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); private: std::list *insert_index_stmts( @@ -690,12 +693,14 @@ class Link : public Base { _is_outside_inside_transition = true; } - void outside_collect_parsers(std::vector &left_parsers, - std::vector &right_parsers, - unsigned int &num_outside_nts, - size_t track, - std::list &simple_loops); - void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + void outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track, + std::list &simple_loops); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -765,13 +770,14 @@ class Block : public Base { void multi_init_calls(const Runtime::Poly &p, size_t base_tracks); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); - void outside_collect_parsers(std::vector &left_parsers, - std::vector &right_parsers, - unsigned int &num_outside_nts, - size_t track, - std::list &simple_loops); - void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); - + void outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track, + std::list &simple_loops); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -844,12 +850,14 @@ class Multi : public Base { void init_ret_decl(unsigned int i, const std::string &prefix); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); - void outside_collect_parsers(std::vector &left, - std::vector &right, - unsigned int &num_outside_nts, - size_t track, - std::list &simple_loops); - void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + void outside_collect_parsers( + std::vector &left, + std::vector &right, + unsigned int &num_outside_nts, + size_t track, + std::list &simple_loops); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; } // namespace Alt diff --git a/src/fn_arg.hh b/src/fn_arg.hh index 849e9d4ec..215e2eae7 100644 --- a/src/fn_arg.hh +++ b/src/fn_arg.hh @@ -162,7 +162,8 @@ class Base { unsigned int &num_outside_nts, size_t track, std::list &simple_loops); - virtual void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + virtual void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -218,7 +219,8 @@ class Alt : public Base { unsigned int &num_outside_nts, size_t track, std::list &simple_loops); - void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -275,7 +277,8 @@ class Const : public Base { unsigned int &num_outside_nts, size_t track, std::list &simple_loops); - void outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; } // namespace Fn_Arg diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 1da6a0bf9..e2a05aee4 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -21,9 +21,9 @@ }}} */ +#include #include "grammar_transformation.hh" #include "../expr/new.hh" -#include bool Grammar::check_outside_parse_empty_word() { if (this->ast.outside_generation()) { diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 8a0b6ed3e..ff2c7e219 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -38,10 +38,10 @@ void Alt::Simple::outside_collect_parsers( size_t track, std::list &simple_loops ) { - for (std::list::iterator i = args.begin(); i != args.end(); ++i) { - (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track, this->loops); + (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, + track, this->loops); } } void Alt::Link::outside_collect_parsers( @@ -54,7 +54,8 @@ void Alt::Link::outside_collect_parsers( if (this->nt->is_partof_outside() || this->is_outside_inside_transition()) { num_outside_nts++; } else { - Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices), simple_loops); + Parser *p = new Parser(this->multi_ys()(track), this->left_indices, + this->right_indices, simple_loops); if (num_outside_nts < 1) { left_parsers.push_back(p); } else { @@ -83,7 +84,8 @@ void Alt::Multi::outside_collect_parsers( for (; j < track; ++i, ++j) {} // each component is in a single-track context - (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, 0, simple_loops); + (*i)->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, + 0, simple_loops); } void Fn_Arg::Base::outside_collect_parsers( @@ -99,7 +101,8 @@ void Fn_Arg::Const::outside_collect_parsers( unsigned int &num_outside_nts, size_t track, std::list &simple_loops) { - Parser *p = new Parser(this->multi_ys()(track), (this->left_indices), (this->right_indices), simple_loops); + Parser *p = new Parser(this->multi_ys()(track), this->left_indices, + this->right_indices, simple_loops); if (num_outside_nts < 1) { left_parsers.push_back(p); } else { @@ -112,7 +115,8 @@ void Fn_Arg::Alt::outside_collect_parsers( unsigned int &num_outside_nts, size_t track, std::list &simple_loops) { - alt->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, track, simple_loops); + alt->outside_collect_parsers(left_parsers, right_parsers, num_outside_nts, + track, simple_loops); } Yield::Size sum_ys(std::vector parser, @@ -121,15 +125,18 @@ Yield::Size sum_ys(std::vector parser, size_t track) { Yield::Size ys; - for (std::vector::iterator i = itr_start; (i != parser.end()) && (i != itr_end); ++i) { + for (std::vector::iterator i = itr_start; + (i != parser.end()) && (i != itr_end); ++i) { ys += (*i)->yield_size; } return ys; } -void Alt::Base::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} -void Alt::Simple::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { +void Alt::Base::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) {} +void Alt::Simple::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) { for (std::list::iterator i = args.begin(); i != args.end(); ++i) { (*i)->outside_uppropagate_indices(left, right, track); @@ -145,17 +152,21 @@ void Alt::Simple::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *righ right_indices[track] = right; } } -void Alt::Link::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { - // Links point to grammar leaves and should already have left/right indices set in phase 2 +void Alt::Link::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) { + // Links point to grammar leaves and should already have left/right indices + // set in phase 2 if (!this->nt->is_partof_outside()) { assert(this->left_indices[track]); assert(this->right_indices[track]); } } -void Alt::Block::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { +void Alt::Block::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) { assert(false); // Alt::Block should have been resolved already } -void Alt::Multi::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { +void Alt::Multi::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) { size_t j = 0; assert(track < list.size()); std::list::iterator i = list.begin(); @@ -167,23 +178,35 @@ void Alt::Multi::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right left_indices[track] = (*i)->get_left_index(0); right_indices[track] = (*i)->get_right_index(0); } -void Fn_Arg::Base::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} -void Fn_Arg::Alt::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) { +void Fn_Arg::Base::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) {} +void Fn_Arg::Alt::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) { alt->outside_uppropagate_indices(left, right, track); this->left_indices[track] = alt->get_left_index(track); this->right_indices[track] = alt->get_right_index(track); } -void Fn_Arg::Const::outside_uppropagate_indices(Expr::Vacc *left, Expr::Vacc *right, size_t track) {} - -void iterate_indices(bool is_left_not_right, std::vector *parser, unsigned int &k, size_t track, unsigned int tracks, Expr::Base *next_var, Expr::Base *last_var, Expr::Vacc *upstream_index, Yield::Size ys_all) { +void Fn_Arg::Const::outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track) {} + +void iterate_indices(bool is_left_not_right, + std::vector *parser, + unsigned int &k, size_t track, + unsigned int tracks, + Expr::Base *next_var, + Expr::Base *last_var, + Expr::Vacc *upstream_index, + Yield::Size ys_all) { Yield::Size lhs; - for (std::vector::iterator i = parser->begin(); i != parser->end(); ++i) { + for (std::vector::iterator i = parser->begin(); + i != parser->end(); ++i) { Yield::Size ys = (*i)->yield_size; Yield::Size rhs = sum_ys(*parser, std::next(i), parser->end(), track); Yield::Size rhs_ys(rhs); rhs_ys += ys; - next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, ys, lhs, rhs, &((*i)->simple_loops)); + next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, + ys, lhs, rhs, &((*i)->simple_loops)); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -252,7 +275,9 @@ void iterate_indices(bool is_left_not_right, std::vector *parser, unsig } } -void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track) { +void outside_init_indices( + Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, + size_t track) { std::vector left_parser; std::vector right_parser; unsigned int num_outside_nts = 0; @@ -260,40 +285,53 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u // //TODO(smj): how about has_index_overlay?! // if (alt->is(Alt::SIMPLE)) { // if (dynamic_cast(alt)->has_index_overlay()) { -// std::cerr << "hier hab ich den Salat " << *dynamic_cast(alt)->name << " ==========\n"; +// std::cerr << "hier hab ich den Salat " +// << *dynamic_cast(alt)->name << " ==========\n"; // } // } - // phase 1: traverse whole sub-tree of alternative (can include multiple levels) and collect - // all grammar components that "parse" subwords from the input (can be empty) + /* phase 1: traverse whole sub-tree of alternative (can include multiple + * levels) and collect + * all grammar components that "parse" subwords from the input (can + * be empty) */ std::list loops; if (alt->is(Alt::SIMPLE)) { loops = dynamic_cast(alt)->loops; } - alt->outside_collect_parsers(left_parser, right_parser, num_outside_nts, track, loops); + alt->outside_collect_parsers(left_parser, right_parser, num_outside_nts, + track, loops); // by design, there must be exactly one rhs outside NT in each alternative // only exception is the transition from outside to inside grammar parts assert(num_outside_nts == 1); - // phase 2: based on the collected Parsers, assign left and right indices to Parsers - // for grammar components LEFT of outside NT - Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); - Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, ys_all, Yield::Size(), ys_all, &loops); + // phase 2: based on the collected Parsers, assign left and right indices + // to Parsers for grammar components LEFT of outside NT + Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), + left_parser.end(), track); + Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, + ys_all, Yield::Size(), ys_all, + &loops); Expr::Base *next_var = last_var; - iterate_indices(true, &left_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, left, ys_all); + iterate_indices(true, &left_parser, k, track, alt->multi_ys().tracks(), + next_var, last_var, left, ys_all); // for grammar components RIGHT of outside NT if (right_parser.size() > 0) { - ys_all = sum_ys(right_parser, right_parser.begin(), right_parser.end(), track); - last_var = Alt::next_index_var(k, track, right, last_var, right, ys_all, Yield::Size(), ys_all, &loops); - iterate_indices(false, &right_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, right, ys_all); + ys_all = sum_ys(right_parser, right_parser.begin(), right_parser.end(), + track); + last_var = Alt::next_index_var(k, track, right, last_var, right, ys_all, + Yield::Size(), ys_all, &loops); + iterate_indices(false, &right_parser, k, track, alt->multi_ys().tracks(), + next_var, last_var, right, ys_all); } GetOutsideLink v = GetOutsideLink(); alt->traverse(v); - if ((left_parser.size() == 0) && (right_parser.size() == 0) && v.outside_link) { + if ((left_parser.size() == 0) && (right_parser.size() == 0) && + v.outside_link) { if (v.outside_link->is_outside_inside_transition()) { - v.outside_link->Base::init_indices(left->plus(right), right->minus(left), k, track); + v.outside_link->Base::init_indices(left->plus(right), right->minus(left), + k, track); } else { // must be a direct link to an non-terminal v.outside_link->Base::init_indices(left, right, k, track); @@ -303,12 +341,15 @@ void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, u // Phase 3: propagate left/right indices from Parser towards the top alt->outside_uppropagate_indices(left, right, track); - // Phase 4: set left/right indices of outside NT to the top level left/right indices - v.outside_link->init_indices(alt->get_left_index(track), alt->get_right_index(track), k, track); + // Phase 4: set left/right indices of outside NT to the top level left/right + // indices + v.outside_link->init_indices(alt->get_left_index(track), + alt->get_right_index(track), k, track); if (alt->is(Alt::SIMPLE)) { - dynamic_cast(alt)->loops.insert(dynamic_cast(alt)->loops.begin(), loops.begin(), loops.end()); + dynamic_cast(alt)->loops.insert( + dynamic_cast(alt)->loops.begin(), + loops.begin(), loops.end()); } - } diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 0c8a4abdf..ae67fd9bc 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -24,7 +24,9 @@ #ifndef SRC_OUTSIDE_MIDDLE_END_HH_ #define SRC_OUTSIDE_MIDDLE_END_HH_ - +#include +#include +#include #include "../symbol.hh" #include "../expr.hh" #include "../fn_arg.hh" @@ -39,13 +41,19 @@ class Parser { std::vector &right_indices; std::list &simple_loops; - Parser(Yield::Size ys, std::vector &left_indices, std::vector &right_indices, std::list &simple_loops) : yield_size(ys), left_indices(left_indices), right_indices(right_indices), simple_loops(simple_loops) { + Parser(Yield::Size ys, + std::vector &left_indices, + std::vector &right_indices, + std::list &simple_loops) : + yield_size(ys), + left_indices(left_indices), + right_indices(right_indices), + simple_loops(simple_loops) { } }; -#include "../alt.hh" - -void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track); +void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, + unsigned int &k, size_t track); struct GetOutsideLink : public Visitor { Alt::Link *outside_link = nullptr; diff --git a/src/outside/middle_end_fwd.hh b/src/outside/middle_end_fwd.hh index 01b066985..32d95ba91 100644 --- a/src/outside/middle_end_fwd.hh +++ b/src/outside/middle_end_fwd.hh @@ -1,9 +1,25 @@ -/* - * middle_end_fwd.hh - * - * Created on: Apr 26, 2023 - * Author: sjanssen - */ +/* {{{ + + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ #ifndef SRC_OUTSIDE_MIDDLE_END_FWD_HH_ #define SRC_OUTSIDE_MIDDLE_END_FWD_HH_ diff --git a/src/symbol.cc b/src/symbol.cc index d4f09d384..dd7130b4c 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -752,7 +752,8 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, right_indices[track] = right; unsigned int c = 0; - for (std::list::iterator i = alts.begin(); i != alts.end(); ++i, ++c) { + for (std::list::iterator i = alts.begin(); + i != alts.end(); ++i, ++c) { if ((*i)->is_partof_outside()) { outside_init_indices(*i, left, right, k, track); } else { From 35a3e1ccde37c01571b3f1d25b588b39486fb689 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 27 Apr 2023 17:06:00 +0200 Subject: [PATCH 070/189] adding a warning IF user defined manual index overlay AND outside grammar generation --- src/grammar.cc | 4 ++++ src/grammar.hh | 7 +++++++ src/outside/grammar_transformation.cc | 27 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/grammar.cc b/src/grammar.cc index c02cfe5d3..0609df9a0 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -499,6 +499,10 @@ bool Grammar::check_semantic() { // check that all NTs requested by the user are actually part of the grammar this->check_outside_requested_nonexisting_nts(); + // warn user about manual overlays that probably lead to wrong results when + // outside grammar generation is requested + this->check_overlays_exists(); + return r; } diff --git a/src/grammar.hh b/src/grammar.hh index 3ae56c8ea..32aa27084 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -232,6 +232,13 @@ class Grammar { void set_partof_outside() { _is_partof_outside = true; } + + /* search for Alt::Simple in the grammar that are annotated with manual index + * overlay to warn the user when requesting outside grammar that computation + * most likely will be wrong, since running indices cannot be transformed + * from inside to outside. + */ + void check_overlays_exists(); }; diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index e2a05aee4..5d8bad117 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -232,6 +232,33 @@ bool Instance::check_multiple_answer_types(bool for_outside_generation) { return num_errors == 0; } +void Grammar::check_overlays_exists() { + struct FindOverlay : public Visitor { + std::vector overlay_locations; + + void visit_begin(Alt::Simple &alt) { + if (alt.has_index_overlay() && !alt.is_partof_outside()) { + overlay_locations.push_back(alt.location); + } + } + }; + + if (this->ast.outside_generation() && (!this->is_partof_outside())) { + FindOverlay v = FindOverlay(); + this->traverse(v); + if (v.overlay_locations.size() > 0) { + for (std::vector::const_iterator i = v.overlay_locations.begin(); + i != v.overlay_locations.end(); ++i) { + Log::instance()->warning(*i, + "You requested outside grammar generation, but your inside grammar " + "contains manual index overlays. As these cannot be automatically " + "converted from an inside to an outside fashion, the resulting " + "program most likely produces wrong results!"); + } + } + } +} + /* iterates through one lhs NT and reports the first occurrence of an * Alt::Block, i.e. * - hold a pointer to the Alt::Block, From 7647b06ac3d8fddc170abe673616473248b33be6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 27 Apr 2023 17:07:33 +0200 Subject: [PATCH 071/189] remove TODO --- src/outside/middle_end.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index ff2c7e219..8fc5a4f8d 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -282,14 +282,6 @@ void outside_init_indices( std::vector right_parser; unsigned int num_outside_nts = 0; -// //TODO(smj): how about has_index_overlay?! -// if (alt->is(Alt::SIMPLE)) { -// if (dynamic_cast(alt)->has_index_overlay()) { -// std::cerr << "hier hab ich den Salat " -// << *dynamic_cast(alt)->name << " ==========\n"; -// } -// } - /* phase 1: traverse whole sub-tree of alternative (can include multiple * levels) and collect * all grammar components that "parse" subwords from the input (can From 0e885e165f52de53d573707d4acbca2bda305136 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 11:10:54 +0200 Subject: [PATCH 072/189] adding extensive debugging output (must be removed later) + fixed for loop construction --- src/alt.cc | 84 +++++++++++++++++++++++++++++++++++---- src/alt.hh | 10 +++-- src/grammar.cc | 2 +- src/outside/middle_end.cc | 42 ++++++++++++++++---- src/outside/middle_end.hh | 8 +++- src/symbol.cc | 20 ++++++++-- src/symbol.hh | 8 ++-- 7 files changed, 146 insertions(+), 28 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index 4899f2c43..82231a774 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1071,9 +1071,57 @@ void Alt::Simple::reset() { Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, - std::list *loops) { - if (ys.low() != ys.high()) { - if (rhs.low() == rhs.high()) { + std::list *loops, bool for_outside_generation, bool outmost, bool is_left_not_right) { +#ifdef LOOPDEBUG + std::cerr << " next_index_var next_var="; + if (next_var) { + std::cerr << *next_var; + } else { + std::cerr << "NULL"; + } + std::cerr << ", last_var="; + if (last_var) { + std::cerr << *last_var; + } else { + std::cerr << "NULL"; + } + std::cerr << ", lhs=" << lhs; + std::cerr << ", ys=" << ys; + std::cerr << ", rhs=" << rhs; + std::cerr << ", outmost=" << (outmost ? "yes": "no"); +//std::cerr << "\n"; +#endif + + /* only for outside NTs: + * If left/right of the rhs outside NT are grammar components with at least + * one moving boundary, we need to start leftmost/rightmost with a new + * loop variable t_x_k. + * Note that empty grammar components might occur on left/rightmost positions + * like LOC. Once we encounter these components, we already did increase k + * previously. Thus, it is not sufficient to "just" look at lhs, ys and rhs. + */ + if (for_outside_generation && + outmost && + // nothing on the left, but moving boundary on the right + (((lhs.low() == 0) && (lhs.high() == 0) && (rhs.low() != rhs.high())) || + // nothing on the right, but moving boundary on the left + ((rhs.low() == 0) && (rhs.high() == 0) && (lhs.low() != lhs.high())) + ) + ) { + outmost = true; + } else { + outmost = false; + } + +#ifdef LOOPDEBUG + std::cerr << ", outmost_l2=" << (outmost ? "yes": "no"); +#endif + + if ((ys.low() != ys.high()) || outmost) { + if ((rhs.low() == rhs.high()) && !outmost) { +#ifdef LOOPDEBUG + std::cerr << " --> " << *right << "\n"; +#endif return right; } else { std::ostringstream o; @@ -1081,13 +1129,23 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, k++; Expr::Vacc *ivar = new Expr::Vacc(new std::string(o.str())); - assert(lhs.low() == lhs.high()); + // start generating for-loop + assert((lhs.low() == lhs.high()) || outmost); std::pair index(0, 0); Yield::Size lhs_ys(lhs); lhs_ys += ys; - if (rhs.high() == Yield::UP) { + /* flip next/last variables for loops that belong to outside NTs and + * are right of the rhs outside NT, since we need to iterate towards the + * right end of the input sequence */ + if (for_outside_generation && !is_left_not_right) { + Expr::Base* tmp = last_var; + last_var = right; + right = tmp; + } + + if (outmost || (rhs.high() == Yield::UP)) { index.first = last_var->plus(lhs_ys.low()); } else { // e.g. second maxsize filter in grammar/forloops5 @@ -1102,7 +1160,7 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Expr::Base *cond = new Expr::Less_Eq(ivar, index.second); // e.g. first maxsize filter in grammar/forloops5 - if (lhs_ys.high() < Yield::UP) { + if ((lhs_ys.high() < Yield::UP) && !outmost) { cond = new Expr::And( cond, new Expr::Less_Eq (ivar, last_var->plus(lhs_ys.high()))); } @@ -1115,9 +1173,21 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Statement::For *f = new Statement::For (loopvariable, cond); loops->push_back(f); +#ifdef LOOPDEBUG + std::cerr << " --> " << *ivar << "\n"; +#endif return ivar; } } else { +#ifdef LOOPDEBUG + std::cerr << " --> "; + if (next_var) { + std::cerr << *next_var; + } else { + std::cerr << "NULL"; + } + std::cerr << "\n"; +#endif return next_var; } } @@ -1146,7 +1216,7 @@ void Alt::Simple::init_indices( rhs_ys += ys; next_var = next_index_var( - k, track, next_var, last_var, right, ys, lhs, rhs, &this->loops); + k, track, next_var, last_var, right, ys, lhs, rhs, &this->loops, false, false, false); std::pair res(0, 0); if (lhs.low() == lhs.high()) { diff --git a/src/alt.hh b/src/alt.hh index 55bf4db8f..3265a0cf5 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -68,10 +68,12 @@ namespace Alt { */ enum Type { SIMPLE, LINK, BLOCK, MULTI }; -Expr::Base *next_index_var(unsigned &k, size_t track, - Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, - const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, - std::list *loops); +Expr::Base *next_index_var( + unsigned &k, size_t track, + Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, + const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, + std::list *loops, + bool for_outside_generation, bool outmost, bool is_left_not_right); class Base { private: diff --git a/src/grammar.cc b/src/grammar.cc index 0609df9a0..af3adce4d 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -906,7 +906,7 @@ void Grammar::init_indices() { unsigned k = 0; // built up loops and boundaries to loop over inductively - (*i)->init_indices(l, r, k, idx); + (*i)->init_indices(l, r, k, idx, left_most, right_most); } } } diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 8fc5a4f8d..265ad5c26 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -124,6 +124,8 @@ Yield::Size sum_ys(std::vector parser, std::vector::iterator itr_end, size_t track) { Yield::Size ys; + // don't risk undefined yield sizes! + ys.set(0, 0); for (std::vector::iterator i = itr_start; (i != parser.end()) && (i != itr_end); ++i) { @@ -198,6 +200,7 @@ void iterate_indices(bool is_left_not_right, Expr::Vacc *upstream_index, Yield::Size ys_all) { Yield::Size lhs; + lhs.set(0, 0); for (std::vector::iterator i = parser->begin(); i != parser->end(); ++i) { Yield::Size ys = (*i)->yield_size; @@ -205,8 +208,11 @@ void iterate_indices(bool is_left_not_right, Yield::Size rhs_ys(rhs); rhs_ys += ys; +#ifdef LOOPDEBUG + std::cerr << (is_left_not_right ? "2" : "4") << ") "; +#endif next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, - ys, lhs, rhs, &((*i)->simple_loops)); + ys, lhs, rhs, &((*i)->simple_loops), true, false, is_left_not_right); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -277,7 +283,16 @@ void iterate_indices(bool is_left_not_right, void outside_init_indices( Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, - size_t track) { + size_t track, Expr::Vacc *left_most, Expr::Vacc *right_most) { +#ifdef LOOPDEBUG + if (alt->is(Alt::SIMPLE)) { + std::cerr << " alt::Simple '" << *(dynamic_cast(alt)->name) << "':\n"; + } else if (alt->is(Alt::LINK)) { + std::cerr << " alt::Link '" << *(dynamic_cast(alt)->name) << "':\n"; + } else { + std::cerr << " alt '?':\n"; + } +#endif std::vector left_parser; std::vector right_parser; unsigned int num_outside_nts = 0; @@ -301,18 +316,29 @@ void outside_init_indices( // to Parsers for grammar components LEFT of outside NT Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), left_parser.end(), track); - Expr::Base *last_var = Alt::next_index_var(k, track, left, left, right, - ys_all, Yield::Size(), ys_all, - &loops); - Expr::Base *next_var = last_var; +#ifdef LOOPDEBUG + std::cerr << "1) "; +#endif + Yield::Size ys_lhs = sum_ys(left_parser, left_parser.begin(), left_parser.begin(), track); + Yield::Size ys; + ys.set(0,0); + Expr::Base *next_var = Alt::next_index_var(k, track, left, left_most, left, + ys, ys_lhs, ys_all, + &loops, true, true, true); + Expr::Base *last_var = next_var; iterate_indices(true, &left_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, left, ys_all); // for grammar components RIGHT of outside NT if (right_parser.size() > 0) { ys_all = sum_ys(right_parser, right_parser.begin(), right_parser.end(), track); - last_var = Alt::next_index_var(k, track, right, last_var, right, ys_all, - Yield::Size(), ys_all, &loops); +#ifdef LOOPDEBUG + std::cerr << "3) "; +#endif + Yield::Size ys_rhs = sum_ys(right_parser, right_parser.begin(), right_parser.begin(), track); + last_var = Alt::next_index_var(k, track, right, right_most, right, + ys, ys_all, ys_rhs, + &loops, true, true, false); iterate_indices(false, &right_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, right, ys_all); } diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index ae67fd9bc..42c8196c8 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -52,8 +52,12 @@ class Parser { } }; -void outside_init_indices(Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, - unsigned int &k, size_t track); +void outside_init_indices( + Alt::Base *alt, // the top level alternative + Expr::Vacc *left, Expr::Vacc *right, // indices of lhs NT + unsigned int &k, size_t track, + // left/right borders of user input + Expr::Vacc *left_most, Expr::Vacc *right_most); struct GetOutsideLink : public Visitor { Alt::Link *outside_link = nullptr; diff --git a/src/symbol.cc b/src/symbol.cc index dd7130b4c..ab84803c8 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -743,20 +743,34 @@ bool Symbol::NT::is_inlineable() { } void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, - unsigned int &k, size_t track) { + unsigned int &k, size_t track, + Expr::Vacc *left_most, Expr::Vacc *right_most) { assert(track < left_indices.size()); assert(left); assert(right); left_indices[track] = left; right_indices[track] = right; - +#ifdef LOOPDEBUG +// if (this->is_partof_outside()) { + std::cerr << "init_indices for NT " << *this->name << ": (left=" << *left << ", right=" << *right << ")\n"; +// } +#endif unsigned int c = 0; for (std::list::iterator i = alts.begin(); i != alts.end(); ++i, ++c) { if ((*i)->is_partof_outside()) { - outside_init_indices(*i, left, right, k, track); + outside_init_indices(*i, left, right, k, track, left_most, right_most); } else { +#ifdef LOOPDEBUG + if ((*i)->is(Alt::SIMPLE)) { + std::cerr << " alt::Simple '" << *(dynamic_cast(*i)->name) << "':\n"; + } else if ((*i)->is(Alt::LINK)) { + std::cerr << " alt::Link '" << *(dynamic_cast(*i)->name) << "':\n"; + } else { + std::cerr << " alt '?':\n"; + } +#endif (*i)->init_indices(left, right, k, track); } } diff --git a/src/symbol.hh b/src/symbol.hh index 39051a9f7..c1d9438c3 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -438,9 +438,11 @@ class NT : public Base { void inline_nts(Grammar *grammar); bool is_inlineable(); - void init_indices(Expr::Vacc *left, Expr::Vacc *right, - unsigned int &k, size_t track); - + void init_indices( + Expr::Vacc *left, Expr::Vacc *right, + unsigned int &k, size_t track, + // pass left/right user input borders for outside NTs + Expr::Vacc *left_most, Expr::Vacc *right_most); void gen_ys_guards(std::list &ors) const; void init_guards(Code::Mode mode); From 33e655f50c95fead2c43065dd93d06f6accdd931 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 12:01:51 +0200 Subject: [PATCH 073/189] also initialize indices for Fn_Arg::Alt that lead to outside NT --- src/outside/middle_end.cc | 9 +++++++-- src/outside/middle_end.hh | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 265ad5c26..556062feb 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -361,8 +361,13 @@ void outside_init_indices( // Phase 4: set left/right indices of outside NT to the top level left/right // indices - v.outside_link->init_indices(alt->get_left_index(track), - alt->get_right_index(track), k, track); + if (v.outside_fn_arg) { + v.outside_fn_arg->init_indices(alt->get_left_index(track), + alt->get_right_index(track), k, track); + } else { + v.outside_link->init_indices(alt->get_left_index(track), + alt->get_right_index(track), k, track); + } if (alt->is(Alt::SIMPLE)) { dynamic_cast(alt)->loops.insert( diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 42c8196c8..71fb25f48 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -61,12 +61,18 @@ void outside_init_indices( struct GetOutsideLink : public Visitor { Alt::Link *outside_link = nullptr; + Fn_Arg::Alt *outside_fn_arg = nullptr; void visit(Alt::Link &a) { if (a.nt->is_partof_outside() || a.is_outside_inside_transition()) { this->outside_link = &a; } } + void visit_end(Fn_Arg::Alt &f) { + if (outside_link && !outside_fn_arg) { + this->outside_fn_arg = &f; + } + } }; #endif /* SRC_OUTSIDE_MIDDLE_END_HH_ */ From e6b392026b99eceb2bfff5bf2b24be8f1927611a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 12:02:23 +0200 Subject: [PATCH 074/189] add complete_track filter --- rtlib/filter.hh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rtlib/filter.hh b/rtlib/filter.hh index 4d4075ba5..ee23e1ec8 100644 --- a/rtlib/filter.hh +++ b/rtlib/filter.hh @@ -127,5 +127,13 @@ inline bool samesize(const Basic_Sequence &s1, return j1-i1 == j2-i2; } +// for the transition from outside parts of a outside generated grammar into +// the inside parts. +template +inline bool complete_track( + const Basic_Sequence &seq, T i, T j) { + return ((i == seq.n) && (j == seq.n)); +} + #endif // RTLIB_FILTER_HH_ From f11bad4249f066cfb848a342df5bbe0cf95b7a52 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 13:03:17 +0200 Subject: [PATCH 075/189] make function accessible from outside --- src/outside/middle_end.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 71fb25f48..701d6f7fa 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -59,6 +59,11 @@ void outside_init_indices( // left/right borders of user input Expr::Vacc *left_most, Expr::Vacc *right_most); +Yield::Size sum_ys(std::vector parser, + std::vector::iterator itr_start, + std::vector::iterator itr_end, + size_t track); + struct GetOutsideLink : public Visitor { Alt::Link *outside_link = nullptr; Fn_Arg::Alt *outside_fn_arg = nullptr; From 1a25dc3d399b151a3c3ac267caa65809313c42d3 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 13:03:51 +0200 Subject: [PATCH 076/189] store left/right most variable names at nonterminal for guard construction of outside NTs --- src/grammar.cc | 5 +++++ src/symbol.cc | 4 ++-- src/symbol.hh | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/grammar.cc b/src/grammar.cc index af3adce4d..457187c0f 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -905,6 +905,11 @@ void Grammar::init_indices() { unsigned k = 0; + if ((*i)->is_partof_outside()) { + // store names for left/right most input boundaries for outside NTs + (*i)->left_most_indices.push_back(left_most); + (*i)->right_most_indices.push_back(right_most); + } // built up loops and boundaries to loop over inductively (*i)->init_indices(l, r, k, idx, left_most, right_most); } diff --git a/src/symbol.cc b/src/symbol.cc index ab84803c8..5e788654a 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -1215,6 +1215,8 @@ struct SetADPDisabled : public Visitor { }; void Symbol::NT::codegen(AST &ast) { + std::list stmts; + // disable specialisation if needed in backtrace mode SetADPDisabled v = SetADPDisabled(ast.code_mode() == Code::Mode::BACKTRACK && tabulated, ast.code_mode().keep_cooptimal()); @@ -1245,8 +1247,6 @@ void Symbol::NT::codegen(AST &ast) { } f->add_para(*this); - std::list stmts; - subopt_header(ast, score_code, f, stmts); init_guards(ast.code_mode()); diff --git a/src/symbol.hh b/src/symbol.hh index c1d9438c3..39195153c 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -129,6 +129,8 @@ class Base { Loc location; std::vector left_indices; std::vector right_indices; + std::vector left_most_indices; + std::vector right_most_indices; bool is(Type t) const { return type == t; } From 922ad460855326c4d256e4a3558bced3af019ae4 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 13:06:09 +0200 Subject: [PATCH 077/189] create and add guards for outside NTs --- src/alt.cc | 93 ++++++++++++++++++++++++++++++++++++++++++++---------- src/alt.hh | 3 ++ 2 files changed, 80 insertions(+), 16 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index 82231a774..6a6252451 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1602,6 +1602,45 @@ void Alt::Simple::init_guards() { ret_decl_empty_block(guards); } +void Alt::Simple::init_outside_guards() { + std::list l; + assert(m_ys.tracks() == left_indices.size()); + + size_t track = 0; + for (std::vector::iterator i = left_indices.begin(); + i != left_indices.end(); ++i, ++track) { + // obtain yield sizes for components left/right of outside NT + std::vector left_parser; + std::vector right_parser; + unsigned int num_outside_nts = 0; + std::list loops; + this->outside_collect_parsers(left_parser, right_parser, num_outside_nts, + track, loops); + + // obtain outside NT + GetOutsideLink v = GetOutsideLink(); + this->traverse(v); + + // create conditions like + // if (((t_0_i >= (t_0_left_most + 6)) && ((t_0_j + 4) <= t_0_right_most))) { + l.push_back( + new Expr::Greater_Eq( + v.outside_link->nt->left_indices[track], + v.outside_link->nt->left_most_indices[track]->plus( + sum_ys(left_parser, left_parser.begin(), left_parser.end(), track).low()))); + l.push_back( + new Expr::Less_Eq( + v.outside_link->nt->right_indices[track]->plus( + sum_ys(right_parser, right_parser.begin(), right_parser.end(), track).low()), + v.outside_link->nt->right_most_indices[track])); + } + + Expr::Base *cond = Expr::seq_to_tree( + l.begin(), l.end()); + + guards_outside = new Statement::If(cond); + ret_decl_empty_block(guards_outside); +} void Alt::Base::push_back_ret_decl() { statements.push_back(ret_decl); @@ -1926,6 +1965,27 @@ std::list *Alt::Simple::add_for_loops( return stmts; } +std::list *Alt::Simple::add_guards(std::list *stmts, bool add_outside_guards) { + Statement::If *use_guards = guards; + if (add_outside_guards) { + use_guards = guards_outside; + } + if (use_guards) { + stmts->push_back(use_guards); + if (datatype->simple()->is(::Type::LIST)) { + // only call finalize on hash lists + if (!ret_decl->rhs && adp_specialization == ADP_Mode::STANDARD) { + Statement::Fn_Call *f = new Statement::Fn_Call( + Statement::Fn_Call::FINALIZE); + f->add_arg(*ret_decl); + stmts->push_back(f); + } + } + stmts = &use_guards->then; + } + return stmts; +} + void Alt::Simple::codegen(AST &ast) { // std::cout << "-----------Simple IN" << std::endl; @@ -1948,19 +2008,10 @@ void Alt::Simple::codegen(AST &ast) { init_guards(); - if (guards) { - stmts->push_back(guards); - if (datatype->simple()->is(::Type::LIST)) { - // only call finalize on hash lists - if (!ret_decl->rhs && adp_specialization == ADP_Mode::STANDARD) { - Statement::Fn_Call *f = new Statement::Fn_Call( - Statement::Fn_Call::FINALIZE); - f->add_arg(*ret_decl); - stmts->push_back(f); - } - } - stmts = &guards->then; + if (this->is_partof_outside()) { + init_outside_guards(); } + stmts = add_guards(stmts, this->is_partof_outside()); init_filter_guards(ast); @@ -2000,11 +2051,21 @@ void Alt::Simple::codegen(AST &ast) { } } - // add filter_guards - stmts = add_filter_guards(stmts, filter_guards); + if (this->is_partof_outside()) { + // add for loops for moving boundaries + stmts = add_for_loops(stmts, loops, has_index_overlay()); - // add for loops for moving boundaries - stmts = add_for_loops(stmts, loops, has_index_overlay()); + stmts = add_guards(stmts, false); + + // add filter_guards + stmts = add_filter_guards(stmts, filter_guards); + } else { + // add filter_guards + stmts = add_filter_guards(stmts, filter_guards); + + // add for loops for moving boundaries + stmts = add_for_loops(stmts, loops, has_index_overlay()); + } add_subopt_guards(stmts, ast); diff --git a/src/alt.hh b/src/alt.hh index 3265a0cf5..61d03e6cd 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -435,6 +435,7 @@ class Simple : public Base { std::list body_stmts; Statement::If *guards; + Statement::If *guards_outside; void ret_decl_empty_block(Statement::If *stmt); void deep_erase_if_backtrace( Statement::If *stmt, std::vector::iterator start, @@ -473,6 +474,8 @@ class Simple : public Base { bool has_arg_list(); void init_body(AST &ast); void init_guards(); + void init_outside_guards(); + std::list *add_guards(std::list *stmts, bool add_outside_guards); void codegen(AST &ast); void print_dot_edge(std::ostream &out, Symbol::NT &nt); From 34d4accb33f8bbcc265b323718445b5c9f7c0685 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 28 Apr 2023 13:11:31 +0200 Subject: [PATCH 078/189] linting --- src/alt.cc | 19 ++++++++++++------- src/alt.hh | 3 ++- src/outside/middle_end.cc | 19 ++++++++++++------- src/outside/middle_end.hh | 2 +- src/symbol.cc | 11 ++++++----- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index 6a6252451..c053bf508 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1071,7 +1071,8 @@ void Alt::Simple::reset() { Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, - std::list *loops, bool for_outside_generation, bool outmost, bool is_left_not_right) { + std::list *loops, + bool for_outside_generation, bool outmost, bool is_left_not_right) { #ifdef LOOPDEBUG std::cerr << " next_index_var next_var="; if (next_var) { @@ -1089,7 +1090,6 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, std::cerr << ", ys=" << ys; std::cerr << ", rhs=" << rhs; std::cerr << ", outmost=" << (outmost ? "yes": "no"); -//std::cerr << "\n"; #endif /* only for outside NTs: @@ -1216,7 +1216,8 @@ void Alt::Simple::init_indices( rhs_ys += ys; next_var = next_index_var( - k, track, next_var, last_var, right, ys, lhs, rhs, &this->loops, false, false, false); + k, track, next_var, last_var, right, ys, lhs, rhs, + &this->loops, false, false, false); std::pair res(0, 0); if (lhs.low() == lhs.high()) { @@ -1622,16 +1623,19 @@ void Alt::Simple::init_outside_guards() { this->traverse(v); // create conditions like - // if (((t_0_i >= (t_0_left_most + 6)) && ((t_0_j + 4) <= t_0_right_most))) { + // if (((t_0_i >= (t_0_left_most + 6)) && + // ((t_0_j + 4) <= t_0_right_most))) { l.push_back( new Expr::Greater_Eq( v.outside_link->nt->left_indices[track], v.outside_link->nt->left_most_indices[track]->plus( - sum_ys(left_parser, left_parser.begin(), left_parser.end(), track).low()))); + sum_ys(left_parser, left_parser.begin(), + left_parser.end(), track).low()))); l.push_back( new Expr::Less_Eq( v.outside_link->nt->right_indices[track]->plus( - sum_ys(right_parser, right_parser.begin(), right_parser.end(), track).low()), + sum_ys(right_parser, right_parser.begin(), + right_parser.end(), track).low()), v.outside_link->nt->right_most_indices[track])); } @@ -1965,7 +1969,8 @@ std::list *Alt::Simple::add_for_loops( return stmts; } -std::list *Alt::Simple::add_guards(std::list *stmts, bool add_outside_guards) { +std::list *Alt::Simple::add_guards( + std::list *stmts, bool add_outside_guards) { Statement::If *use_guards = guards; if (add_outside_guards) { use_guards = guards_outside; diff --git a/src/alt.hh b/src/alt.hh index 61d03e6cd..92b0d5234 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -475,7 +475,8 @@ class Simple : public Base { void init_body(AST &ast); void init_guards(); void init_outside_guards(); - std::list *add_guards(std::list *stmts, bool add_outside_guards); + std::list *add_guards( + std::list *stmts, bool add_outside_guards); void codegen(AST &ast); void print_dot_edge(std::ostream &out, Symbol::NT &nt); diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 556062feb..e90b8bb92 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -211,8 +211,9 @@ void iterate_indices(bool is_left_not_right, #ifdef LOOPDEBUG std::cerr << (is_left_not_right ? "2" : "4") << ") "; #endif - next_var = Alt::next_index_var(k, track, next_var, last_var, upstream_index, - ys, lhs, rhs, &((*i)->simple_loops), true, false, is_left_not_right); + next_var = Alt::next_index_var( + k, track, next_var, last_var, upstream_index, + ys, lhs, rhs, &((*i)->simple_loops), true, false, is_left_not_right); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -286,9 +287,11 @@ void outside_init_indices( size_t track, Expr::Vacc *left_most, Expr::Vacc *right_most) { #ifdef LOOPDEBUG if (alt->is(Alt::SIMPLE)) { - std::cerr << " alt::Simple '" << *(dynamic_cast(alt)->name) << "':\n"; + std::cerr << " alt::Simple '" + << *(dynamic_cast(alt)->name) << "':\n"; } else if (alt->is(Alt::LINK)) { - std::cerr << " alt::Link '" << *(dynamic_cast(alt)->name) << "':\n"; + std::cerr << " alt::Link '" + << *(dynamic_cast(alt)->name) << "':\n"; } else { std::cerr << " alt '?':\n"; } @@ -319,9 +322,10 @@ void outside_init_indices( #ifdef LOOPDEBUG std::cerr << "1) "; #endif - Yield::Size ys_lhs = sum_ys(left_parser, left_parser.begin(), left_parser.begin(), track); + Yield::Size ys_lhs = sum_ys(left_parser, left_parser.begin(), + left_parser.begin(), track); Yield::Size ys; - ys.set(0,0); + ys.set(0, 0); Expr::Base *next_var = Alt::next_index_var(k, track, left, left_most, left, ys, ys_lhs, ys_all, &loops, true, true, true); @@ -335,7 +339,8 @@ void outside_init_indices( #ifdef LOOPDEBUG std::cerr << "3) "; #endif - Yield::Size ys_rhs = sum_ys(right_parser, right_parser.begin(), right_parser.begin(), track); + Yield::Size ys_rhs = sum_ys(right_parser, right_parser.begin(), + right_parser.begin(), track); last_var = Alt::next_index_var(k, track, right, right_most, right, ys, ys_all, ys_rhs, &loops, true, true, false); diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 701d6f7fa..7fe60bc3a 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -80,4 +80,4 @@ struct GetOutsideLink : public Visitor { } }; -#endif /* SRC_OUTSIDE_MIDDLE_END_HH_ */ +#endif // SRC_OUTSIDE_MIDDLE_END_HH_ diff --git a/src/symbol.cc b/src/symbol.cc index 5e788654a..e0a58ce50 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -752,9 +752,8 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, left_indices[track] = left; right_indices[track] = right; #ifdef LOOPDEBUG -// if (this->is_partof_outside()) { - std::cerr << "init_indices for NT " << *this->name << ": (left=" << *left << ", right=" << *right << ")\n"; -// } + std::cerr << "init_indices for NT " << *this->name + << ": (left=" << *left << ", right=" << *right << ")\n"; #endif unsigned int c = 0; for (std::list::iterator i = alts.begin(); @@ -764,9 +763,11 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, } else { #ifdef LOOPDEBUG if ((*i)->is(Alt::SIMPLE)) { - std::cerr << " alt::Simple '" << *(dynamic_cast(*i)->name) << "':\n"; + std::cerr << " alt::Simple '" + << *(dynamic_cast(*i)->name) << "':\n"; } else if ((*i)->is(Alt::LINK)) { - std::cerr << " alt::Link '" << *(dynamic_cast(*i)->name) << "':\n"; + std::cerr << " alt::Link '" + << *(dynamic_cast(*i)->name) << "':\n"; } else { std::cerr << " alt '?':\n"; } From bc962b83ee290de18c81d7c83e6640b161b8650f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 1 May 2023 21:55:45 +0200 Subject: [PATCH 079/189] add the new statement "CustomeCode" to simply "print" an arbitary string as a new line of code --- src/cpp.cc | 6 ++++++ src/cpp.hh | 1 + src/printer.cc | 1 + src/printer.hh | 1 + src/statement.cc | 3 +++ src/statement.hh | 12 ++++++++++++ src/statement/base.hh | 2 +- 7 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/cpp.cc b/src/cpp.cc index 817cc0cc8..1b4136fcc 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -545,6 +545,9 @@ void Printer::Cpp::print(const Statement::Block &stmt) { stream << indent() << "}" << endl; } +void Printer::Cpp::print(const Statement::CustomeCode &stmt) { + stream << indent() << stmt.line_of_code; +} void Printer::Cpp::print(const std::list &types, const std::list &names) { @@ -1855,6 +1858,9 @@ void Printer::Cpp::header(const AST &ast) { if (ast.get_float_acc() > 0) { stream << "#define FLOAT_ACC " << ast.get_float_acc() << "\n"; } + if (ast.outside_generation()) { + stream << "#define OUTSIDE\n"; + } stream << "#define GAPC_CALL_STRING \"" << gapc_call_string << "\"" << endl; diff --git a/src/cpp.hh b/src/cpp.hh index 9873708be..2e655553c 100644 --- a/src/cpp.hh +++ b/src/cpp.hh @@ -144,6 +144,7 @@ class Cpp : public Base { void print(const Statement::Var_Assign &stmt); void print(const Statement::Fn_Call &stmt); void print(const Statement::Block &stmt); + void print(const Statement::CustomeCode &stmt); void print(const Statement::Backtrace_Decl &stmt); void print(const Statement::Backtrace_NT_Decl &stmt); void print(const Statement::Hash_Decl &stmt); diff --git a/src/printer.cc b/src/printer.cc index 1a2622890..758ca660d 100644 --- a/src/printer.cc +++ b/src/printer.cc @@ -67,6 +67,7 @@ void Printer::Base::print(const Statement::Sorter &stmt) {} void Printer::Base::print(const Statement::Var_Assign &stmt) {} void Printer::Base::print(const Statement::Fn_Call &stmt) {} void Printer::Base::print(const Statement::Block &stmt) {} +void Printer::Base::print(const Statement::CustomeCode &stmt) {} void Printer::Base::print(const Statement::Backtrace_Decl &stmt) {} void Printer::Base::print(const Statement::Backtrace_NT_Decl &stmt) {} void Printer::Base::print(const Statement::Hash_Decl &stmt) {} diff --git a/src/printer.hh b/src/printer.hh index 3f9541b7e..9d1734661 100644 --- a/src/printer.hh +++ b/src/printer.hh @@ -116,6 +116,7 @@ class Base { virtual void print(const Statement::Var_Assign &stmt); virtual void print(const Statement::Fn_Call &stmt); virtual void print(const Statement::Block &stmt); + virtual void print(const Statement::CustomeCode &stmt); virtual void print(const Statement::Backtrace_Decl &stmt); virtual void print(const Statement::Backtrace_NT_Decl &stmt); virtual void print(const Statement::Hash_Decl &stmt); diff --git a/src/statement.cc b/src/statement.cc index ce780daad..64f074939 100644 --- a/src/statement.cc +++ b/src/statement.cc @@ -138,6 +138,9 @@ void Statement::Block::print(Printer::Base &p) const { p.print(*this); } +void Statement::CustomeCode::print(Printer::Base &p) const { + p.print(*this); +} Statement::Var_Assign::Var_Assign(Var_Decl &a) : Base(VAR_ASSIGN), op_(Expr::EQ), rhs(NULL) { diff --git a/src/statement.hh b/src/statement.hh index 3e519d8ce..54fd8e6d0 100644 --- a/src/statement.hh +++ b/src/statement.hh @@ -362,6 +362,18 @@ class Block : public Block_Base { Base *copy() const; }; +class CustomeCode : public Base { + /* A "CustomeCode" statement is an arbitrary line of string that get's + * injected. Handy to leave comments in the generated code or inject + * constructs otherwise impossible. Use with care! */ + public: + std::string line_of_code; + + explicit CustomeCode(std::string line_of_code) : Base(CUSTOMECODE), line_of_code(line_of_code) { + } + + void print(Printer::Base &p) const; +}; } // namespace Statement diff --git a/src/statement/base.hh b/src/statement/base.hh index 7428921d8..f60946abe 100644 --- a/src/statement/base.hh +++ b/src/statement/base.hh @@ -50,7 +50,7 @@ namespace Statement { enum Type { RETURN, IF, VAR_DECL, BLOCK, FOR, FOREACH, VAR_ASSIGN, FN_CALL, BACKTRACE_DECL, BACKTRACE_NT_DECL, HASH_DECL, BREAK, MARKER_DECL, TABLE_DECL, CONTINUE, WHILE, - DECREASE, INCREASE, SORTER, SWITCH + DECREASE, INCREASE, SORTER, SWITCH, CUSTOMECODE, }; From 56d28bb4980f689f74b3ae4a2c10644f201809bb Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 1 May 2023 21:56:30 +0200 Subject: [PATCH 080/189] report_nts instead of just printing answers if outside mode was requested --- rtlib/generic_main.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtlib/generic_main.cc b/rtlib/generic_main.cc index 91f4a5e3d..9a55d6482 100644 --- a/rtlib/generic_main.cc +++ b/rtlib/generic_main.cc @@ -93,8 +93,12 @@ int main(int argc, char **argv) { gapc::add_event("end_computation"); +#ifndef OUTSIDE std::cout << "Answer: \n"; obj.print_result(std::cout, res); +#else + obj.report_insideoutside(std::cout); +#endif gapc::add_event("end_result_pp"); From 0d1699dacbdd9cc54e2337a7b1acc2042df54dd2 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 1 May 2023 21:57:00 +0200 Subject: [PATCH 081/189] always store left/right most index names for NTs (not only for outside NTs) --- src/grammar.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/grammar.cc b/src/grammar.cc index 457187c0f..bdb504956 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -905,11 +905,10 @@ void Grammar::init_indices() { unsigned k = 0; - if ((*i)->is_partof_outside()) { - // store names for left/right most input boundaries for outside NTs - (*i)->left_most_indices.push_back(left_most); - (*i)->right_most_indices.push_back(right_most); - } + // store names for left/right most input boundaries + (*i)->left_most_indices.push_back(left_most); + (*i)->right_most_indices.push_back(right_most); + // built up loops and boundaries to loop over inductively (*i)->init_indices(l, r, k, idx, left_most, right_most); } From 57c07cb076e7dd403cc28b93e924aab971ee8624 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 1 May 2023 21:57:47 +0200 Subject: [PATCH 082/189] collect user provided list of NTs which shall be reported --- src/ast.hh | 4 ++-- src/gapc.cc | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ast.hh b/src/ast.hh index f470b80c1..b10bb49e8 100644 --- a/src/ast.hh +++ b/src/ast.hh @@ -305,7 +305,7 @@ class AST { Printer::Checkpoint *checkpoint; - bool outside_generation() { + bool outside_generation() const { if (!outside_nt_list) { return false; } @@ -314,7 +314,7 @@ class AST { void set_outside_nt_list(std::vector *nts) { outside_nt_list = nts; } - const std::vector *get_outside_nt_list() { + std::vector *get_outside_nt_list() const { return this->outside_nt_list; } }; diff --git a/src/gapc.cc b/src/gapc.cc index 6dbba7673..cd3a39961 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -53,6 +53,7 @@ #include "printer/gap.hh" #include "specialize_grammar/create_specialized_grammar.hh" #include "outside/grammar_transformation.hh" +#include "outside/codegen.hh" namespace po = boost::program_options; @@ -698,6 +699,9 @@ class Main { hh.footer(driver.ast); hh.end_fwd_decls(); hh.header_footer(driver.ast); + if (driver.ast.outside_generation()) { + print_insideoutside_report_fn(hh, driver.ast); + } // Write out the C++ implementation file of the // compile-result. From 62dcc296931f49278cdb68c7db249c642a8315e3 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 1 May 2023 21:58:26 +0200 Subject: [PATCH 083/189] add code to generate function that reports outside results --- src/outside/codegen.cc | 178 +++++++++++++++++++++++++++++++++++++++++ src/outside/codegen.hh | 33 ++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/outside/codegen.cc create mode 100644 src/outside/codegen.hh diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc new file mode 100644 index 000000000..b8f2464af --- /dev/null +++ b/src/outside/codegen.cc @@ -0,0 +1,178 @@ +/* {{{ + + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ + +#include "codegen.hh" +#include "../statement_fwd.hh" +#include "../expr.hh" +#include "../fn_def.hh" +#include "../statement_fwd.hh" +#include "../statement/fn_call.hh" +#include "../cpp.hh" +#include "grammar_transformation.hh" + +std::list *NTs_to_report(const AST &ast) { + /* define which non-terminals shell be reported to the user + * order of user arguments (--outside_grammar) shall take precedence over + * NTs as occurring in source code of grammar. + * - User shell be warned, if outside version of NT has not been generated. + * This happens for NTs without rhs NTs. + * - User was already informed about NTs he/she requested but are not part of + * the grammar. */ + std::list *report_nts = new std::list(); + + // iterate through user arguments + for (std::vector::const_iterator name_param = ast.get_outside_nt_list()->begin(); + name_param != ast.get_outside_nt_list()->end(); ++name_param) { + if (name_param->compare(OUTSIDE_ALL) == 0) { + // edge case: user requested to report ALL non terminals, by providing the + // keyword "ALL" + for (std::list::const_iterator i = ast.grammar()->nts().begin(); i != ast.grammar()->nts().end(); ++i) { + // skip outside NTs + if ((*i)->is_partof_outside()) { + continue; + } + bool already_in = false; + for (std::list::iterator rnt = report_nts->begin(); rnt != report_nts->end(); ++rnt) { + if (*rnt == *i) { + already_in = true; + break; + } + } + if (already_in == false) { + report_nts->push_back(*i); + } + } + } else { + report_nts->push_back(dynamic_cast(ast.grammar()->NTs.find(*name_param)->second)); + } + } + + std::list nts_no_outside; + for (std::list::iterator i = report_nts->begin(); i != report_nts->end(); ++i) { + hashtable::iterator outside = ast.grammar()->NTs.find(OUTSIDE_NT_PREFIX + *(*i)->name); + if (outside == ast.grammar()->NTs.end()) { + nts_no_outside.push_back(*i); + } + } + if (nts_no_outside.size() > 0) { + std::string msg = "Outside generation of your grammar will NOT lead to outside versions of the following " + std::to_string(nts_no_outside.size()) + " non-terminals: "; + for (std::list::iterator i = nts_no_outside.begin(); i != nts_no_outside.end(); ++i) { + msg += *(*i)->name; + if (i != std::next(nts_no_outside.end())) { + msg += ", "; + } + } + msg += ", as they have no non-terminal on their right hand sides."; + Log::instance()->warning(nts_no_outside.front()->location, msg); + } + + return report_nts; +} + + +void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { + bool old_in_class = stream.in_class; + stream.in_class = true; + + std::list *report_nts = NTs_to_report(ast); + + Fn_Def *fn = new Fn_Def(new Type::RealVoid(), new std::string("report_insideoutside")); + //fn->set + // a hacky way to "inject" the non constant "std::ostream &out" parameter + // into the function + Type::TupleDef *t2 = new Type::TupleDef(Loc()); + t2->name = "std::ostream"; + fn->add_para(t2, new std::string("&out")); + + + for (std::list::iterator i = report_nts->begin(); i != report_nts->end(); ++i) { + // do the same for inside and outside version of NT + for (unsigned int inout = 0; inout <= 1; ++inout) { + Symbol::NT *nt = (*i); + if (inout == 1) { + hashtable::iterator outside_nt = ast.grammar()->NTs.find(OUTSIDE_NT_PREFIX + *nt->name); + if (outside_nt != ast.grammar()->NTs.end()) { + nt = dynamic_cast(outside_nt->second); + } else { + continue; + } + } + + Expr::Fn_Call *fn_nt = new Expr::Fn_Call((nt->code()->name)); + //Expr::Fn_Call *fn_report = new Expr::Fn_Call(new std::string("outside_report_answer")); + + // build up loops. For example: + // for (unsigned int t_0_i = t_0_left_most; t_0_i <= t_0_right_most; ++t_0_i) { + // for (unsigned int t_0_j = t_0_i; t_0_j <= t_0_right_most; ++t_0_j) { + std::list *loops = new std::list(); + std::vector *idx = new std::vector(); + for (size_t track = nt->track_pos(); track < nt->tracks(); ++track) { + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), nt->left_indices[track], nt->left_most_indices[track]); + loopvariable->set_itr(true); + Expr::Less_Eq *cond = new Expr::Less_Eq(nt->left_indices[track], nt->right_most_indices[track]); + loops->push_back(new Statement::For(loopvariable, cond)); + fn_nt->add_arg(nt->left_indices[track]); + idx->push_back(nt->left_indices[track]->vacc()->name()); + + loopvariable = new Statement::Var_Decl( + new ::Type::Size(), nt->right_indices[track], nt->left_indices[track]); + loopvariable->set_itr(true); + cond = new Expr::Less_Eq(nt->right_indices[track], nt->right_most_indices[track]); + loops->push_back(new Statement::For(loopvariable, cond)); + fn_nt->add_arg(nt->right_indices[track]); + idx->push_back(nt->right_indices[track]->vacc()->name()); + } + + std::string idx_param = ""; + for (std::vector::iterator i_idx = idx->begin(); i_idx != idx->end(); ++i_idx) { + idx_param += " << " + *(*i_idx) + " << "; + if (std::next(i_idx) != idx->end()) { + idx_param += "\",\""; + } + } + (*loops->rbegin())->statements.push_back(new Statement::CustomeCode("out << \"start answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); + + Statement::Var_Decl *res = new Statement::Var_Decl(nt->return_decl().type, "res_" + *nt->name, fn_nt); + (*loops->rbegin())->statements.push_back(res); + + // produce call of "print_result" + Statement::Fn_Call *fnp = new Statement::Fn_Call("print_result"); + fnp->add_arg(new std::string("std::cout")); + fnp->add_arg(res->name); + (*loops->rbegin())->statements.push_back(fnp); + + // nest for loops, first will then contain the others + nest_for_loops(loops->begin(), loops->end()); + // add outmost for loop into body of report function + fn->stmts.push_back(*loops->begin()); + + // produce: out << "//end answers outside_iloop(" << t_0_i << "," << t_0_j << ")\n"; + (*loops->rbegin())->statements.push_back(new Statement::CustomeCode("out << \"//end answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); + + } + } + stream << *fn << "\n"; + + stream.in_class = old_in_class; +} diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh new file mode 100644 index 000000000..819b9f940 --- /dev/null +++ b/src/outside/codegen.hh @@ -0,0 +1,33 @@ +/* {{{ + + This file is part of gapc (GAPC - Grammars, Algebras, Products - Compiler; + a system to compile algebraic dynamic programming programs) + + Copyright (C) 2011-2023 Stefan Janssen + email: stefan.m.janssen@gmail.com or stefan.janssen@computational.bio.uni-giessen.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +}}} */ + +#ifndef SRC_OUTSIDE_CODEGEN_HH_ +#define SRC_OUTSIDE_CODEGEN_HH_ + +#include "../ast.hh" +#include "../printer.hh" +#include "../cpp.hh" + +void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast); + +#endif // SRC_OUTSIDE_CODEGEN_HH_ From 73e8937476cacafe14a0c17fa18449a9b3961ce6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 14:43:01 +0200 Subject: [PATCH 084/189] remove : --- src/outside/codegen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index b8f2464af..55df0ebf0 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -168,7 +168,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { fn->stmts.push_back(*loops->begin()); // produce: out << "//end answers outside_iloop(" << t_0_i << "," << t_0_j << ")\n"; - (*loops->rbegin())->statements.push_back(new Statement::CustomeCode("out << \"//end answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); + (*loops->rbegin())->statements.push_back(new Statement::CustomeCode("out << \"//end answers " + *nt->name + "(\"" + idx_param + "\")\\n\";")); } } From b32329e61865e9989e3a0b32c239372ca631ab43 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 14:43:08 +0200 Subject: [PATCH 085/189] no outside guards if innermost NT is NOT an outside one --- src/alt.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index c053bf508..d051158b0 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1617,6 +1617,15 @@ void Alt::Simple::init_outside_guards() { std::list loops; this->outside_collect_parsers(left_parser, right_parser, num_outside_nts, track, loops); + if (num_outside_nts != 1) { + /* we branched into a pure inside context, this will always happen if + * where an inside production uses multiple non terminals on its rhs, e.g. + * an inside rule like struct = cadd(dangle, struct) will lead to two + * outside rules: outside_dangle = cadd(outside_struct, struct) and + * outside_struct = cadd(dangle, outside_struct) + * which hold inside and outside parts. */ + continue; + } // obtain outside NT GetOutsideLink v = GetOutsideLink(); @@ -1639,11 +1648,15 @@ void Alt::Simple::init_outside_guards() { v.outside_link->nt->right_most_indices[track])); } - Expr::Base *cond = Expr::seq_to_tree( - l.begin(), l.end()); + // only create guards for outside situations, but not for inside parts in an + // outside context. See above comment. + if (l.size() > 0) { + Expr::Base *cond = Expr::seq_to_tree( + l.begin(), l.end()); - guards_outside = new Statement::If(cond); - ret_decl_empty_block(guards_outside); + guards_outside = new Statement::If(cond); + ret_decl_empty_block(guards_outside); + } } void Alt::Base::push_back_ret_decl() { From 0320608c86dcadbc235fe2bcdaf1b309dd3dc773 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 14:55:04 +0200 Subject: [PATCH 086/189] move includes to header file --- src/outside/codegen.cc | 8 +------- src/outside/codegen.hh | 6 ++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 55df0ebf0..437893d0d 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -22,13 +22,7 @@ }}} */ #include "codegen.hh" -#include "../statement_fwd.hh" -#include "../expr.hh" -#include "../fn_def.hh" -#include "../statement_fwd.hh" -#include "../statement/fn_call.hh" -#include "../cpp.hh" -#include "grammar_transformation.hh" + std::list *NTs_to_report(const AST &ast) { /* define which non-terminals shell be reported to the user diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh index 819b9f940..2e78034f7 100644 --- a/src/outside/codegen.hh +++ b/src/outside/codegen.hh @@ -27,6 +27,12 @@ #include "../ast.hh" #include "../printer.hh" #include "../cpp.hh" +#include "../statement_fwd.hh" +#include "../expr.hh" +#include "../fn_def.hh" +#include "../statement_fwd.hh" +#include "../statement/fn_call.hh" +#include "grammar_transformation.hh" void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast); From 6d904536964b0f4c1529898a619edf95745f05fa Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 14:55:36 +0200 Subject: [PATCH 087/189] move function definition for Alt::Simple::init_outside_guards into outside/ subdir --- src/alt.cc | 55 -------------------------------------- src/outside/middle_end.cc | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index d051158b0..3cb937dcc 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1603,61 +1603,6 @@ void Alt::Simple::init_guards() { ret_decl_empty_block(guards); } -void Alt::Simple::init_outside_guards() { - std::list l; - assert(m_ys.tracks() == left_indices.size()); - - size_t track = 0; - for (std::vector::iterator i = left_indices.begin(); - i != left_indices.end(); ++i, ++track) { - // obtain yield sizes for components left/right of outside NT - std::vector left_parser; - std::vector right_parser; - unsigned int num_outside_nts = 0; - std::list loops; - this->outside_collect_parsers(left_parser, right_parser, num_outside_nts, - track, loops); - if (num_outside_nts != 1) { - /* we branched into a pure inside context, this will always happen if - * where an inside production uses multiple non terminals on its rhs, e.g. - * an inside rule like struct = cadd(dangle, struct) will lead to two - * outside rules: outside_dangle = cadd(outside_struct, struct) and - * outside_struct = cadd(dangle, outside_struct) - * which hold inside and outside parts. */ - continue; - } - - // obtain outside NT - GetOutsideLink v = GetOutsideLink(); - this->traverse(v); - - // create conditions like - // if (((t_0_i >= (t_0_left_most + 6)) && - // ((t_0_j + 4) <= t_0_right_most))) { - l.push_back( - new Expr::Greater_Eq( - v.outside_link->nt->left_indices[track], - v.outside_link->nt->left_most_indices[track]->plus( - sum_ys(left_parser, left_parser.begin(), - left_parser.end(), track).low()))); - l.push_back( - new Expr::Less_Eq( - v.outside_link->nt->right_indices[track]->plus( - sum_ys(right_parser, right_parser.begin(), - right_parser.end(), track).low()), - v.outside_link->nt->right_most_indices[track])); - } - - // only create guards for outside situations, but not for inside parts in an - // outside context. See above comment. - if (l.size() > 0) { - Expr::Base *cond = Expr::seq_to_tree( - l.begin(), l.end()); - - guards_outside = new Statement::If(cond); - ret_decl_empty_block(guards_outside); - } -} void Alt::Base::push_back_ret_decl() { statements.push_back(ret_decl); diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index e90b8bb92..273ac5b26 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -381,3 +381,59 @@ void outside_init_indices( } } +void Alt::Simple::init_outside_guards() { + std::list l; + assert(m_ys.tracks() == left_indices.size()); + + size_t track = 0; + for (std::vector::iterator i = left_indices.begin(); + i != left_indices.end(); ++i, ++track) { + // obtain yield sizes for components left/right of outside NT + std::vector left_parser; + std::vector right_parser; + unsigned int num_outside_nts = 0; + std::list loops; + this->outside_collect_parsers(left_parser, right_parser, num_outside_nts, + track, loops); + if (num_outside_nts != 1) { + /* we branched into a pure inside context, this will always happen if + * where an inside production uses multiple non terminals on its rhs, e.g. + * an inside rule like struct = cadd(dangle, struct) will lead to two + * outside rules: outside_dangle = cadd(outside_struct, struct) and + * outside_struct = cadd(dangle, outside_struct) + * which hold inside and outside parts. */ + continue; + } + + // obtain outside NT + GetOutsideLink v = GetOutsideLink(); + this->traverse(v); + + // create conditions like + // if (((t_0_i >= (t_0_left_most + 6)) && + // ((t_0_j + 4) <= t_0_right_most))) { + l.push_back( + new Expr::Greater_Eq( + v.outside_link->nt->left_indices[track], + v.outside_link->nt->left_most_indices[track]->plus( + sum_ys(left_parser, left_parser.begin(), + left_parser.end(), track).low()))); + l.push_back( + new Expr::Less_Eq( + v.outside_link->nt->right_indices[track]->plus( + sum_ys(right_parser, right_parser.begin(), + right_parser.end(), track).low()), + v.outside_link->nt->right_most_indices[track])); + } + + // only create guards for outside situations, but not for inside parts in an + // outside context. See above comment. + if (l.size() > 0) { + Expr::Base *cond = Expr::seq_to_tree( + l.begin(), l.end()); + + guards_outside = new Statement::If(cond); + ret_decl_empty_block(guards_outside); + } +} + From 35279303f5093680d221bb3b9f4e7a61bf24c916 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 14:55:58 +0200 Subject: [PATCH 088/189] add two outside mod tests --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 883028383..45dd3dead 100644 --- a/Makefile +++ b/Makefile @@ -131,7 +131,7 @@ gapc: src/gapc.o $(MAIN_OBJ) src/version.o src/prefix.o stats \ test_rt_tab \ -multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics outside_resolve_blocks outside_grammar: src/version.o src/prefix.o +multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser outside_checksemantics outside_resolve_blocks outside_grammar outside_indices outside_loops: src/version.o src/prefix.o backtrack: src/version.o From c4d5f4e34cffb31c5d38af00345383c57c5801bd Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 14:56:16 +0200 Subject: [PATCH 089/189] new test --- testdata/modtest/outside_loops.cc | 71 +++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 testdata/modtest/outside_loops.cc diff --git a/testdata/modtest/outside_loops.cc b/testdata/modtest/outside_loops.cc new file mode 100644 index 000000000..b0676fc48 --- /dev/null +++ b/testdata/modtest/outside_loops.cc @@ -0,0 +1,71 @@ +#include "../../src/driver.hh" +#include "../../src/log.hh" + +#include +#include +#include +#include + +int main(int argc, char **argv) { + std::ostringstream o; + Log log; + log.set_debug(false); + log.set_ostream(o); + + Driver driver; + + if (argc != 2) { + std::cerr << "Call " << *argv << " *.gap-file\n"; + return 1; + } + // === front + // set the file name of the gap-source-code + driver.setFilename(argv[1]); + + // parses the input file and builds the AST + driver.parse(); + + // simply gets the selected grammar, which is either the + // grammar that occurred first in the source code or is the + // one that was named in the parameters on the command line + Grammar *grammar = driver.ast.grammar(); + // Now check the semantic, which does more than the function + // name suggests. The semantic check is embedded in the algorithm + // that links the grammar graph together, and computes yield-sizes. + // If the method returns false, there are some semantic errors, + // which leads to the end of the compilation process. + bool r = grammar->check_semantic(); + if (!r) { + throw LogError("Seen semantic errors."); + } + + // inject rules for outside grammar + grammar->convert_to_outside(); + + // set approx table design + grammar->approx_table_conf(); + + // find what type of input is read + // chars, sequence of ints etc. + driver.ast.derive_temp_alphabet(); + + r = driver.ast.check_signature(); + if (!r) { + return 4; + } + + // apply this to identify standard functions like Min, Max, Exp etc. + driver.ast.derive_roles(); + + + // ------------- back ------------ + grammar->init_list_sizes(); + + grammar->init_indices(); + grammar->init_decls(); + // for cyk (ordering of NT for parsing, see page 101 of the thesis) + grammar->dep_analysis(); + + grammar->print_indices(); +} + From af54a46288d60b6049a00b5f51b1afff7a6bfd36 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 15:30:28 +0200 Subject: [PATCH 090/189] revert change --- src/gapc.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gapc.cc b/src/gapc.cc index cd3a39961..2427a35a8 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -645,7 +645,6 @@ class Main { } grammar->init_indices(); - grammar->init_decls(); // for cyk (ordering of NT for parsing, see page 101 of the thesis) grammar->dep_analysis(); From 9e0059e9fadd4143c2bf8b1b96bea5b49837b66d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 2 May 2023 15:35:45 +0200 Subject: [PATCH 091/189] linting --- src/outside/codegen.cc | 74 ++++++++++++++++++++++++++++-------------- src/outside/codegen.hh | 5 ++- src/statement.hh | 3 +- 3 files changed, 55 insertions(+), 27 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 437893d0d..30b8efb3d 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -35,18 +35,21 @@ std::list *NTs_to_report(const AST &ast) { std::list *report_nts = new std::list(); // iterate through user arguments - for (std::vector::const_iterator name_param = ast.get_outside_nt_list()->begin(); + for (std::vector::const_iterator name_param = + ast.get_outside_nt_list()->begin(); name_param != ast.get_outside_nt_list()->end(); ++name_param) { if (name_param->compare(OUTSIDE_ALL) == 0) { // edge case: user requested to report ALL non terminals, by providing the // keyword "ALL" - for (std::list::const_iterator i = ast.grammar()->nts().begin(); i != ast.grammar()->nts().end(); ++i) { + for (std::list::const_iterator i = + ast.grammar()->nts().begin(); i != ast.grammar()->nts().end(); ++i) { // skip outside NTs if ((*i)->is_partof_outside()) { continue; } bool already_in = false; - for (std::list::iterator rnt = report_nts->begin(); rnt != report_nts->end(); ++rnt) { + for (std::list::iterator rnt = report_nts->begin(); + rnt != report_nts->end(); ++rnt) { if (*rnt == *i) { already_in = true; break; @@ -57,20 +60,27 @@ std::list *NTs_to_report(const AST &ast) { } } } else { - report_nts->push_back(dynamic_cast(ast.grammar()->NTs.find(*name_param)->second)); + report_nts->push_back(dynamic_cast( + ast.grammar()->NTs.find(*name_param)->second)); } } std::list nts_no_outside; - for (std::list::iterator i = report_nts->begin(); i != report_nts->end(); ++i) { - hashtable::iterator outside = ast.grammar()->NTs.find(OUTSIDE_NT_PREFIX + *(*i)->name); + for (std::list::iterator i = report_nts->begin(); + i != report_nts->end(); ++i) { + hashtable::iterator outside = + ast.grammar()->NTs.find(OUTSIDE_NT_PREFIX + *(*i)->name); if (outside == ast.grammar()->NTs.end()) { nts_no_outside.push_back(*i); } } if (nts_no_outside.size() > 0) { - std::string msg = "Outside generation of your grammar will NOT lead to outside versions of the following " + std::to_string(nts_no_outside.size()) + " non-terminals: "; - for (std::list::iterator i = nts_no_outside.begin(); i != nts_no_outside.end(); ++i) { + std::string msg = "Outside generation of your grammar will NOT lead to out" + "side versions of the following " + + std::to_string(nts_no_outside.size()) + + " non-terminals: "; + for (std::list::iterator i = nts_no_outside.begin(); + i != nts_no_outside.end(); ++i) { msg += *(*i)->name; if (i != std::next(nts_no_outside.end())) { msg += ", "; @@ -90,8 +100,9 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { std::list *report_nts = NTs_to_report(ast); - Fn_Def *fn = new Fn_Def(new Type::RealVoid(), new std::string("report_insideoutside")); - //fn->set + Fn_Def *fn = new Fn_Def(new Type::RealVoid(), new std::string( + "report_insideoutside")); + // fn->set // a hacky way to "inject" the non constant "std::ostream &out" parameter // into the function Type::TupleDef *t2 = new Type::TupleDef(Loc()); @@ -99,12 +110,14 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { fn->add_para(t2, new std::string("&out")); - for (std::list::iterator i = report_nts->begin(); i != report_nts->end(); ++i) { + for (std::list::iterator i = report_nts->begin(); + i != report_nts->end(); ++i) { // do the same for inside and outside version of NT for (unsigned int inout = 0; inout <= 1; ++inout) { Symbol::NT *nt = (*i); if (inout == 1) { - hashtable::iterator outside_nt = ast.grammar()->NTs.find(OUTSIDE_NT_PREFIX + *nt->name); + hashtable::iterator outside_nt = + ast.grammar()->NTs.find(OUTSIDE_NT_PREFIX + *nt->name); if (outside_nt != ast.grammar()->NTs.end()) { nt = dynamic_cast(outside_nt->second); } else { @@ -113,41 +126,50 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { } Expr::Fn_Call *fn_nt = new Expr::Fn_Call((nt->code()->name)); - //Expr::Fn_Call *fn_report = new Expr::Fn_Call(new std::string("outside_report_answer")); // build up loops. For example: - // for (unsigned int t_0_i = t_0_left_most; t_0_i <= t_0_right_most; ++t_0_i) { - // for (unsigned int t_0_j = t_0_i; t_0_j <= t_0_right_most; ++t_0_j) { + // for (unsigned int t_0_i = t_0_left_most; + // t_0_i <= t_0_right_most; ++t_0_i) { + // for (unsigned int t_0_j = t_0_i; + // t_0_j <= t_0_right_most; ++t_0_j) { std::list *loops = new std::list(); std::vector *idx = new std::vector(); for (size_t track = nt->track_pos(); track < nt->tracks(); ++track) { Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), nt->left_indices[track], nt->left_most_indices[track]); + new ::Type::Size(), nt->left_indices[track], + nt->left_most_indices[track]); loopvariable->set_itr(true); - Expr::Less_Eq *cond = new Expr::Less_Eq(nt->left_indices[track], nt->right_most_indices[track]); + Expr::Less_Eq *cond = new Expr::Less_Eq(nt->left_indices[track], + nt->right_most_indices[track]); loops->push_back(new Statement::For(loopvariable, cond)); fn_nt->add_arg(nt->left_indices[track]); idx->push_back(nt->left_indices[track]->vacc()->name()); loopvariable = new Statement::Var_Decl( - new ::Type::Size(), nt->right_indices[track], nt->left_indices[track]); + new ::Type::Size(), nt->right_indices[track], + nt->left_indices[track]); loopvariable->set_itr(true); - cond = new Expr::Less_Eq(nt->right_indices[track], nt->right_most_indices[track]); + cond = new Expr::Less_Eq(nt->right_indices[track], + nt->right_most_indices[track]); loops->push_back(new Statement::For(loopvariable, cond)); fn_nt->add_arg(nt->right_indices[track]); idx->push_back(nt->right_indices[track]->vacc()->name()); } std::string idx_param = ""; - for (std::vector::iterator i_idx = idx->begin(); i_idx != idx->end(); ++i_idx) { + for (std::vector::iterator i_idx = idx->begin(); + i_idx != idx->end(); ++i_idx) { idx_param += " << " + *(*i_idx) + " << "; if (std::next(i_idx) != idx->end()) { idx_param += "\",\""; } } - (*loops->rbegin())->statements.push_back(new Statement::CustomeCode("out << \"start answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); + (*loops->rbegin())->statements.push_back(new Statement::CustomeCode( + "out << \"start answers " + *nt->name + "(\"" + idx_param + + "\"):\\n\";")); - Statement::Var_Decl *res = new Statement::Var_Decl(nt->return_decl().type, "res_" + *nt->name, fn_nt); + Statement::Var_Decl *res = new Statement::Var_Decl( + nt->return_decl().type, "res_" + *nt->name, fn_nt); (*loops->rbegin())->statements.push_back(res); // produce call of "print_result" @@ -161,9 +183,11 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { // add outmost for loop into body of report function fn->stmts.push_back(*loops->begin()); - // produce: out << "//end answers outside_iloop(" << t_0_i << "," << t_0_j << ")\n"; - (*loops->rbegin())->statements.push_back(new Statement::CustomeCode("out << \"//end answers " + *nt->name + "(\"" + idx_param + "\")\\n\";")); - + // produce: out << "//end answers outside_iloop(" << t_0_i << "," + // << t_0_j << ")\n"; + (*loops->rbegin())->statements.push_back(new Statement::CustomeCode( + "out << \"//end answers " + *nt->name + "(\"" + idx_param + + "\")\\n\";")); } } stream << *fn << "\n"; diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh index 2e78034f7..a497fb348 100644 --- a/src/outside/codegen.hh +++ b/src/outside/codegen.hh @@ -24,13 +24,16 @@ #ifndef SRC_OUTSIDE_CODEGEN_HH_ #define SRC_OUTSIDE_CODEGEN_HH_ +#include +#include +#include + #include "../ast.hh" #include "../printer.hh" #include "../cpp.hh" #include "../statement_fwd.hh" #include "../expr.hh" #include "../fn_def.hh" -#include "../statement_fwd.hh" #include "../statement/fn_call.hh" #include "grammar_transformation.hh" diff --git a/src/statement.hh b/src/statement.hh index 54fd8e6d0..979087c1e 100644 --- a/src/statement.hh +++ b/src/statement.hh @@ -369,7 +369,8 @@ class CustomeCode : public Base { public: std::string line_of_code; - explicit CustomeCode(std::string line_of_code) : Base(CUSTOMECODE), line_of_code(line_of_code) { + explicit CustomeCode(std::string line_of_code) : + Base(CUSTOMECODE), line_of_code(line_of_code) { } void print(Printer::Base &p) const; From da8ab0e6e182dc4b747de002a3a4cd87fe19d7b7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:36:31 +0200 Subject: [PATCH 092/189] fixed position of keyword "const" --- src/symbol.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/symbol.hh b/src/symbol.hh index 39195153c..6906a9675 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -258,7 +258,7 @@ class Base { bool is_rhs, Symbol::NT *axiom, int plot_grammar); - const bool is_partof_outside() { + bool is_partof_outside() const { return _is_partof_outside; } void set_partof_outside() { From a917335036bfac4e9b794f58e461a9dae6e7a09f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:36:57 +0200 Subject: [PATCH 093/189] adding iloopSumMax filter for regression tests --- testdata/gapc_filter/singlefold.hh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/testdata/gapc_filter/singlefold.hh b/testdata/gapc_filter/singlefold.hh index 12704b8ea..bc05817ab 100644 --- a/testdata/gapc_filter/singlefold.hh +++ b/testdata/gapc_filter/singlefold.hh @@ -9,4 +9,14 @@ inline bool basepair(const Basic_Sequence &seq, T i, T j) return basepairing(seq, i, j); } +//in the Vienna Package, iloop regions are restricted such that their _combined_ length, i.e. |left region| + |right region| cannot exceed 30 bases. +//our restrictions is usually more relaxed, because each region may have up to 30 bases individually, i.e. 60 bases for both regions in the worst case. +//with iloopSumMax we can enforce the Vienna behaviour +template +inline bool iloopSumMax(int size, const Basic_Sequence &seq, T lb_i, T lb_j, T lr_i, T lr_j, T x_i, T x_j, T rr_i, T rr_j, T rb_i, T rb_j) { + assert(lr_i < lr_j); + assert(rr_i < rr_j); + return ((lr_j-lr_i) + (rr_j-rr_i)) <= unsigned(size); +} + #endif From 154ca0eb17f522018d6336c1ab2f87d475c8bfd5 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:37:21 +0200 Subject: [PATCH 094/189] only add outside guards if a) index and outmost index are not identical and b) calling NT is of correct dimension, i.e. uses this index at all --- src/outside/middle_end.cc | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 273ac5b26..ce4186c7a 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -412,18 +412,30 @@ void Alt::Simple::init_outside_guards() { // create conditions like // if (((t_0_i >= (t_0_left_most + 6)) && // ((t_0_j + 4) <= t_0_right_most))) { - l.push_back( - new Expr::Greater_Eq( - v.outside_link->nt->left_indices[track], - v.outside_link->nt->left_most_indices[track]->plus( - sum_ys(left_parser, left_parser.begin(), - left_parser.end(), track).low()))); - l.push_back( - new Expr::Less_Eq( - v.outside_link->nt->right_indices[track]->plus( - sum_ys(right_parser, right_parser.begin(), - right_parser.end(), track).low()), - v.outside_link->nt->right_most_indices[track])); + if (!this->outside_lhsNT->tables()[track].delete_left_index()) { + // no guard if left index is identical with leftmost index + if (v.outside_link->nt->left_indices[track] != + v.outside_link->nt->left_most_indices[track]) { + l.push_back( + new Expr::Greater_Eq( + v.outside_link->nt->left_indices[track], + v.outside_link->nt->left_most_indices[track]->plus( + sum_ys(left_parser, left_parser.begin(), + left_parser.end(), track).low()))); + } + } + if (!this->outside_lhsNT->tables()[track].delete_right_index()) { + // no guard if right index is identical with rightmost index + if (v.outside_link->nt->right_indices[track] != + v.outside_link->nt->right_most_indices[track]) { + l.push_back( + new Expr::Less_Eq( + v.outside_link->nt->right_indices[track]->plus( + sum_ys(right_parser, right_parser.begin(), + right_parser.end(), track).low()), + v.outside_link->nt->right_most_indices[track])); + } + } } // only create guards for outside situations, but not for inside parts in an From 1eb5147058d6474e0b3db532e0adcf10d12fe617 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:38:19 +0200 Subject: [PATCH 095/189] store original yield size of inside grammar for outside components for correct inside guard construction for outside NTs + also let Alt::Simple outside elements know their lhs NT for correct outside guard construction --- src/alt.cc | 14 +++++++++++++- src/alt.hh | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/alt.cc b/src/alt.cc index 3cb937dcc..d3b484fbb 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -84,6 +84,8 @@ Alt::Base *Alt::Simple::clone() { i != args.end(); ++i) { a->args.push_back((*i)->clone()); } + // necessary to construct correct guards for outside code generation + this->m_ys_inside = this->m_ys; return a; } @@ -1586,6 +1588,9 @@ void Alt::Simple::init_guards() { std::list l; assert(m_ys.tracks() == left_indices.size()); Yield::Multi::iterator k = m_ys.begin(); + if (this->is_partof_outside()) { + k = m_ys_inside.begin(); + } std::vector::iterator j = right_indices.begin(); for (std::vector::iterator i = left_indices.begin(); i != left_indices.end(); ++i, ++j, ++k) { @@ -2609,7 +2614,14 @@ void Alt::Simple::init_multi_ys() { void Alt::Link::init_multi_ys() { - m_ys = nt->multi_ys(); + if (nt->is_partof_outside()) { + m_ys.set_tracks(tracks_); + for (Yield::Multi::iterator i = m_ys.begin(); i != m_ys.end(); ++i) { + *i = Yield::Size(0, Yield::UP); + } + } else { + m_ys = nt->multi_ys(); + } Base::init_multi_ys(); } diff --git a/src/alt.hh b/src/alt.hh index 92b0d5234..56c2d8cb6 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -559,6 +559,16 @@ class Simple : public Base { std::list *insert_index_stmts( std::list *stmts); std::list *inner_code; + + // a copy of the original inside yield sizes, without re-execution of yield + // size analysis with the outside compontents added to the grammar. + Yield::Multi m_ys_inside; + + public: + // a reference to the left hand side non terminal from which this alternative + // get's "called". Necessary to construct correct outside guards, i.e. + // we need to know the table dimension of the lhs NT. + Symbol::NT *outside_lhsNT; }; From e597301149b6319e331ca24a0c4ebf4d31da0f8f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:41:42 +0200 Subject: [PATCH 096/189] allow correct yield size re-analysis + inform Alt::Simple about their calling lhs NTs --- src/outside/grammar_transformation.cc | 39 ++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 5d8bad117..6ccac75ae 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -481,6 +481,22 @@ struct Count_parseComponents : public Visitor { } }; +/* let all Alt::Simple grammar elements know which left hand NT called this + * alternative. Necessary to construct proper outside guards, which need to know + * lhs NT table dimensions. + */ +struct Propagate_lhsNT : public Visitor { + Symbol::NT *lhsNT; + + Propagate_lhsNT(Symbol::NT *lhsNT) : lhsNT(lhsNT) { + } + + void visit_begin(Alt::Simple &alt) { + alt.outside_lhsNT = this->lhsNT; + } +}; + + /* iterates through the rhs alternatives of an NT and creates a clone of an * alternative where ONE (but not all) rhs NT is swapped with the lhs NT, e.g. * struct = cadd(dangle, weak) | sadd(BASE, struct) will result in @@ -575,7 +591,13 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { // d) - alt_clones->push_back(std::make_pair(outside_rhs_nt, topalt->clone())); + Alt::Base *topaltclone = topalt->clone(); + /* if the topaltclone is Alt::Simple, we need to let it know its lhs + * calling NT (or better its table dimensions) for downstream + * construction of outside guards in the generated code */ + Propagate_lhsNT vlhsnt = Propagate_lhsNT(outside_rhs_nt); + topaltclone->traverse(vlhsnt); + alt_clones->push_back(std::make_pair(outside_rhs_nt, topaltclone)); // e) alt.nt = orig_rhs_nt; @@ -708,6 +730,7 @@ struct Collect_and_Insert_outside_axioms : public Visitor { Alt::Link *link = new Alt::Link((*i)->name, Loc()); link->name = (*i)->name; link->set_tracks((*i)->tracks(), (*i)->track_pos()); + link->m_ys = Yield::Multi((*i)->tracks()); link->top_level = Bool(true); if ((*i)->ntargs().size() > 0) { link->set_ntparas(Loc(), sync_ntparams((*i)->ntargs())); @@ -746,7 +769,7 @@ struct Collect_and_Insert_outside_axioms : public Visitor { * inside axiom and the source is the outside_ version of the original inside * axiom (not the outside axiom). However, */ -void inject_outside_inside_transition( +Alt::Link *inject_outside_inside_transition( Grammar *grammar, hashtable &outside_nts, std::string name_inside_axiom) { @@ -800,6 +823,10 @@ void inject_outside_inside_transition( // finally add this new transition to the list of alternatives lhs_outside->alts.push_back(link); + + // return pointer to the new outside_inside transition to later initialize + // multi yield sizes, once the linked NT has been initialized + return link; } void Grammar::convert_to_outside() { @@ -842,7 +869,8 @@ void Grammar::convert_to_outside() { /* inject one alternative to the inside axiom which enables the transition * from outside parts into the original inside part of the grammar */ - inject_outside_inside_transition(this, outside_nts, name_inside_axiom); + Alt::Link *ln_transition = inject_outside_inside_transition( + this, outside_nts, name_inside_axiom); // now add the new outside NTs to the grammar for (hashtable::iterator i = outside_nts.begin(); @@ -872,6 +900,11 @@ void Grammar::convert_to_outside() { (*i).second->init_links(*this); } + // initialize m_ys arrays for newly constructed axiom + outside->inside + // transition + this->axiom->init_multi_ys(); + ln_transition->init_multi_ys(); + /* initialize yield sizes for the outside-inside transition, which is one of * the alternatives of the new outside axiom. * Can only be done AFTER links have been initialized, i.e. nt members are From 3b14cb29e698053487bcbca81e32191cd60de37d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:42:33 +0200 Subject: [PATCH 097/189] only add outside guards if a) index and outmost index are not identical and b) calling NT is of correct dimension, i.e. uses this index at all --- src/outside/codegen.cc | 44 ++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 30b8efb3d..7177ac324 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -135,25 +135,31 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { std::list *loops = new std::list(); std::vector *idx = new std::vector(); for (size_t track = nt->track_pos(); track < nt->tracks(); ++track) { - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), nt->left_indices[track], - nt->left_most_indices[track]); - loopvariable->set_itr(true); - Expr::Less_Eq *cond = new Expr::Less_Eq(nt->left_indices[track], - nt->right_most_indices[track]); - loops->push_back(new Statement::For(loopvariable, cond)); - fn_nt->add_arg(nt->left_indices[track]); - idx->push_back(nt->left_indices[track]->vacc()->name()); - - loopvariable = new Statement::Var_Decl( - new ::Type::Size(), nt->right_indices[track], - nt->left_indices[track]); - loopvariable->set_itr(true); - cond = new Expr::Less_Eq(nt->right_indices[track], - nt->right_most_indices[track]); - loops->push_back(new Statement::For(loopvariable, cond)); - fn_nt->add_arg(nt->right_indices[track]); - idx->push_back(nt->right_indices[track]->vacc()->name()); + if (!nt->tables()[track].delete_left_index() || !nt->tables()[track].delete_right_index()) { + // linear and quadratic tables + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), nt->left_indices[track], + nt->left_most_indices[track]); + loopvariable->set_itr(true); + Expr::Less_Eq *cond = new Expr::Less_Eq(nt->left_indices[track], + nt->right_most_indices[track]); + loops->push_back(new Statement::For(loopvariable, cond)); + fn_nt->add_arg(nt->left_indices[track]); + idx->push_back(nt->left_indices[track]->vacc()->name()); + + if (!nt->tables()[track].delete_left_index() && !nt->tables()[track].delete_right_index()) { + // only quadratic tables + loopvariable = new Statement::Var_Decl( + new ::Type::Size(), nt->right_indices[track], + nt->left_indices[track]); + loopvariable->set_itr(true); + cond = new Expr::Less_Eq(nt->right_indices[track], + nt->right_most_indices[track]); + loops->push_back(new Statement::For(loopvariable, cond)); + fn_nt->add_arg(nt->right_indices[track]); + idx->push_back(nt->right_indices[track]->vacc()->name()); + } + } } std::string idx_param = ""; From e38954c1c50457a8c4f4e460449034e5407efb27 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:43:12 +0200 Subject: [PATCH 098/189] start adding regression tests --- testdata/regresstest/config | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index 63321e5da..70ac337c3 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -481,3 +481,34 @@ check_new_old_eq eraseanswers.gap unused ins_count_failing "AC" eraseanswer check_new_old_eq eraseanswers.gap unused ins_count_working "AC" eraseanswer check_new_old_eq eraseanswers_product.gap unused ins "CaaG" eraseanswer_one check_new_old_eq eraseanswers_product.gap unused ins "CaaaG" eraseanswer_four + +# results have been verified against "RNAfold -p -d0 --bppmThreshold=0" v2.4.17 and Stefan's manual python outside version of nodangle +GRAMMAR=../../grammar_outside +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +check_new_old_eq nodangle.gap unused mfe "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +check_new_old_eq nodangle.gap unused count "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside + +# check that fn_arg (with alt) instead of only alt gets initialized +check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside_overlay + + + + + + + + + + + + +GAPC="../../../gapc --outside_grammar ALL" +CPPFLAGS_EXTRA="" +LDLIBS_EXTRA="" +check_new_old_eq hmm_sonneregen.gap unused count "SS" outside +check_new_old_eq hmm_sonneregen.gap unused fwd "SS" outside +check_new_old_eq hmm_sonneregen.gap unused fwd "SSRR" outside_ssrr + +# example in which inside and outside NTs have different dimensions +#check_new_old_eq tmhmm_debug.gap unused count "AA" outside_report From 691a96bb56fdff0202766dc42260c800c4835f9a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:57:12 +0200 Subject: [PATCH 099/189] handle constant tables --- src/outside/codegen.cc | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 7177ac324..4c74a82ae 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -170,30 +170,36 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { idx_param += "\",\""; } } - (*loops->rbegin())->statements.push_back(new Statement::CustomeCode( + std::list *stmts = &((*loops->rbegin())->statements); + + stmts->push_back(new Statement::CustomeCode( "out << \"start answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); Statement::Var_Decl *res = new Statement::Var_Decl( nt->return_decl().type, "res_" + *nt->name, fn_nt); - (*loops->rbegin())->statements.push_back(res); + stmts->push_back(res); // produce call of "print_result" Statement::Fn_Call *fnp = new Statement::Fn_Call("print_result"); fnp->add_arg(new std::string("std::cout")); fnp->add_arg(res->name); - (*loops->rbegin())->statements.push_back(fnp); - - // nest for loops, first will then contain the others - nest_for_loops(loops->begin(), loops->end()); - // add outmost for loop into body of report function - fn->stmts.push_back(*loops->begin()); + stmts->push_back(fnp); // produce: out << "//end answers outside_iloop(" << t_0_i << "," // << t_0_j << ")\n"; - (*loops->rbegin())->statements.push_back(new Statement::CustomeCode( + stmts->push_back(new Statement::CustomeCode( "out << \"//end answers " + *nt->name + "(\"" + idx_param + "\")\\n\";")); + + // nest for loops, first will then contain the others + if (loops->size() > 0) { + nest_for_loops(loops->begin(), loops->end()); + // add outmost for loop into body of report function + fn->stmts.push_back(*loops->begin()); + } else { + fn->stmts = *stmts; + } } } stream << *fn << "\n"; From 57a20353b5944356716d83580be52737f1b7596d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 11:59:28 +0200 Subject: [PATCH 100/189] linting --- src/outside/codegen.cc | 11 +++++++---- src/outside/grammar_transformation.cc | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 4c74a82ae..ddb5ff171 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -135,19 +135,22 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { std::list *loops = new std::list(); std::vector *idx = new std::vector(); for (size_t track = nt->track_pos(); track < nt->tracks(); ++track) { - if (!nt->tables()[track].delete_left_index() || !nt->tables()[track].delete_right_index()) { + if (!nt->tables()[track].delete_left_index() || + !nt->tables()[track].delete_right_index()) { // linear and quadratic tables Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), nt->left_indices[track], nt->left_most_indices[track]); loopvariable->set_itr(true); - Expr::Less_Eq *cond = new Expr::Less_Eq(nt->left_indices[track], - nt->right_most_indices[track]); + Expr::Less_Eq *cond = new Expr::Less_Eq( + nt->left_indices[track], + nt->right_most_indices[track]); loops->push_back(new Statement::For(loopvariable, cond)); fn_nt->add_arg(nt->left_indices[track]); idx->push_back(nt->left_indices[track]->vacc()->name()); - if (!nt->tables()[track].delete_left_index() && !nt->tables()[track].delete_right_index()) { + if (!nt->tables()[track].delete_left_index() && + !nt->tables()[track].delete_right_index()) { // only quadratic tables loopvariable = new Statement::Var_Decl( new ::Type::Size(), nt->right_indices[track], diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 6ccac75ae..80480b01b 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -488,7 +488,7 @@ struct Count_parseComponents : public Visitor { struct Propagate_lhsNT : public Visitor { Symbol::NT *lhsNT; - Propagate_lhsNT(Symbol::NT *lhsNT) : lhsNT(lhsNT) { + explicit Propagate_lhsNT(Symbol::NT *lhsNT) : lhsNT(lhsNT) { } void visit_begin(Alt::Simple &alt) { From 62005023284d2bb2a871a1e8936b87399c319d62 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 13:08:46 +0200 Subject: [PATCH 101/189] activate test --- testdata/regresstest/config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index 70ac337c3..da6c30eee 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -510,5 +510,5 @@ check_new_old_eq hmm_sonneregen.gap unused count "SS" outside check_new_old_eq hmm_sonneregen.gap unused fwd "SS" outside check_new_old_eq hmm_sonneregen.gap unused fwd "SSRR" outside_ssrr -# example in which inside and outside NTs have different dimensions -#check_new_old_eq tmhmm_debug.gap unused count "AA" outside_report +# example in which inside and outside NTs have different dimensions, don't use tmhmm_debug.gap as new semantic checks will prevent producing code +check_new_old_eq tmhmm_debug_nil.gap unused count "AA" outside_report From 85748ece1c20213f9bdbe375b35af7b41fc5af68 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 13:23:31 +0200 Subject: [PATCH 102/189] add new grammar --- testdata/grammar_outside/tmhmm_debug_nil.gap | 161 +++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 testdata/grammar_outside/tmhmm_debug_nil.gap diff --git a/testdata/grammar_outside/tmhmm_debug_nil.gap b/testdata/grammar_outside/tmhmm_debug_nil.gap new file mode 100644 index 000000000..ec617ae12 --- /dev/null +++ b/testdata/grammar_outside/tmhmm_debug_nil.gap @@ -0,0 +1,161 @@ +type Rope = extern + +signature sig_tmhmm(alphabet, answer) { + answer silent_step(answer); + answer step(char, answer, answer); + answer nil(void); + answer trans(float, answer); + answer only(float, alphabet); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_viterbi implements sig_tmhmm(alphabet=char, answer=float) { + float silent_step(float x) { + return x; + } + float step(char label, float e, float t) { + return e*t; + } + float nil(void) { + return 1; + } + float trans(float prob, float x) { + return prob * x; + } + float only(float prob, char emission) { + return prob; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_viterbi_bit extends alg_viterbi { + float step(char label, float e, float t) { + return log(1.0/e) + t; + } + float nil(void) { + return 0.0; + } + float trans(float prob, float x) { + return log(1.0/prob) + x; + } + choice [float] h([float] candidates) { + return list(minimum(candidates)); + } +} + +algebra alg_label implements sig_tmhmm(alphabet=char, answer=Rope) { + Rope silent_step(Rope x) { + return x; + } + Rope step(char label, Rope e, Rope t) { + Rope res; + append(res, label); + append(res, t); + return res; + } + Rope nil(void) { + Rope res; + return res; + } + Rope trans(float prob, Rope x) { + return x; + } + Rope only(float prob, char emission) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +grammar gra_tmhmm uses sig_tmhmm(axiom = state_begin) { + state_begin = silent_step(transitions_begin) # h; + transitions_begin = + trans(CONST_FLOAT(0.549251), state_in10) | + trans(CONST_FLOAT(0.207469), state_outglob10) | + trans(CONST_FLOAT(0.24328), state_out10) | + nil(EMPTY) + # h; + state_in10 = step(CONST_CHAR('i'), emissions_in10, { transitions_in10 | nil(EMPTY) }) # h; + emissions_in10 = + only(CONST_FLOAT(0.0713632), CHAR('A')) | + only(CONST_FLOAT(0.0336358), CHAR('Y')) + # h; + transitions_in10 = + trans(CONST_FLOAT(0.995851), state_in11) | + trans(CONST_FLOAT(0.00111283), state_in29) | + trans(CONST_FLOAT(0.00303586), state_ohelixi1) + # h; + state_in11 = step(CONST_CHAR('i'), emissions_in10, { transitions_in11 | nil(EMPTY) }) # h; + transitions_in11 = + trans(CONST_FLOAT(0.976066), nil(EMPTY)) | + trans(CONST_FLOAT(0.0239339), nil(EMPTY)) | + trans(CONST_FLOAT(1.08323e-09), state_in29) + # h; + state_in29 = step(CONST_CHAR('i'), emissions_in10, { transitions_in29 | nil(EMPTY) }) # h; + transitions_in29 = + trans(CONST_FLOAT(1.0), state_ohelixi1) + # h; + state_ohelixi1 = step(CONST_CHAR('M'), emissions_ohelixi1, transitions_ohelixi1) # h; + emissions_ohelixi1 = + only(CONST_FLOAT(0.0890049), CHAR('A')) | + only(CONST_FLOAT(0.0661077), CHAR('Y')) + # h; + transitions_ohelixi1 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) + # h; + state_outglob10 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob10 | nil(EMPTY) }) # h; + emissions_outglob10 = + only(CONST_FLOAT(0.0693743), CHAR('A')) | + only(CONST_FLOAT(0.0275), CHAR('Y')) + # h; + transitions_outglob10 = + trans(CONST_FLOAT(1.0), state_outglob11) | + trans(CONST_FLOAT(0.0), state_outglob29) | + trans(CONST_FLOAT(0.0), state_ihelixo1) + # h; + state_outglob11 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob11 | nil(EMPTY) }) # h; + transitions_outglob11 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) | + trans(CONST_FLOAT(0.0), nil(EMPTY)) | + trans(CONST_FLOAT(0.0), state_outglob29) + # h; + state_outglob29 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob29 | nil(EMPTY) }) # h; + transitions_outglob29 = + trans(CONST_FLOAT(1.0), state_ihelixo1) + # h; + state_ihelixo1 = step(CONST_CHAR('M'), emissions_out10, transitions_ihelixo1) # h; + transitions_ihelixo1 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) + # h; + state_out10 = step(CONST_CHAR('o'), emissions_out10, { transitions_out10 | nil(EMPTY) }) # h; + emissions_out10 = + only(CONST_FLOAT(0.0690346), CHAR('A')) | + only(CONST_FLOAT(0.0346461), CHAR('Y')) + # h; + transitions_out10 = + trans(CONST_FLOAT(1.0), state_out11) | + trans(CONST_FLOAT(3.54571e-14), state_out29) | + trans(CONST_FLOAT(0.0), state_ihelixo1) + # h; + state_out11 = step(CONST_CHAR('o'), emissions_out10, { transitions_out11 | nil(EMPTY) }) # h; + transitions_out11 = + trans(CONST_FLOAT(0.910217), nil(EMPTY)) | + trans(CONST_FLOAT(0.0495866), nil(EMPTY)) | + trans(CONST_FLOAT(0.0401965), state_out29) + # h; + state_out29 = step(CONST_CHAR('o'), emissions_out10, { transitions_out29 | nil(EMPTY) }) # h; + transitions_out29 = + trans(CONST_FLOAT(1.0), state_ihelixo1) + # h; +} + +instance dummy = gra_tmhmm(alg_enum); +instance count = gra_tmhmm(alg_count); From 6c0f857e8b20dbb1f743b98e5f20ce6fd6010a25 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 13:29:26 +0200 Subject: [PATCH 103/189] add function to execute two track tests --- testdata/regresstest/run.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/testdata/regresstest/run.sh b/testdata/regresstest/run.sh index a41e0c7eb..18300ddab 100755 --- a/testdata/regresstest/run.sh +++ b/testdata/regresstest/run.sh @@ -166,6 +166,35 @@ check_new_old_eq() rm -f string.o } +check_new_old_eq_twotrack() +{ + if [[ `echo $1$3$5 | grep $FILTER` != $1$3$5 ]]; then + return + fi + + # work around 1 sec timestamp filesystems ... WTF?!? + sleep 1 + + echo +------------------------------------------------------------------------------+ + failed=0 + temp=$failed + + cpp_base=${1%%.*} + build_cpp $GRAMMAR/$1 $cpp_base $3 + run_cpp_two_track $cpp_base $3 $4 $5 $6 + cmp_new_old_output $cpp_base $REF $3 $5 $6 + + if [ $temp != $failed ]; then + echo --++--FAIL--++-- + err_count=$((err_count+1)) + else + echo OK + succ_count=$((succ_count+1)) + fi + echo +------------------------------------------------------------------------------+ + rm -f string.o +} + run_check_feature() { out=$1.$2.$3.$4 From 85d2caf70e71056dabf002e973c565551d7c711d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 17:35:56 +0200 Subject: [PATCH 104/189] test against branch outside_v2 --- .github/workflows/c-cpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 581dee234..87735400c 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -31,7 +31,7 @@ jobs: run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip - name: Checkout truth - run: git clone --branch master https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure @@ -79,7 +79,7 @@ jobs: - name: add random Haskell lib run: cabal install --lib random - name: Checkout truth - run: git clone --branch master https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure From 5c7272274ece75ea1dc15ad3b49bad57fe1992ac Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 17:48:45 +0200 Subject: [PATCH 105/189] fix case destinction for outside guard initialization --- src/outside/codegen.cc | 45 ++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index ddb5ff171..add6a0604 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -135,28 +135,32 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { std::list *loops = new std::list(); std::vector *idx = new std::vector(); for (size_t track = nt->track_pos(); track < nt->tracks(); ++track) { - if (!nt->tables()[track].delete_left_index() || - !nt->tables()[track].delete_right_index()) { - // linear and quadratic tables - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), nt->left_indices[track], - nt->left_most_indices[track]); - loopvariable->set_itr(true); - Expr::Less_Eq *cond = new Expr::Less_Eq( - nt->left_indices[track], - nt->right_most_indices[track]); - loops->push_back(new Statement::For(loopvariable, cond)); - fn_nt->add_arg(nt->left_indices[track]); - idx->push_back(nt->left_indices[track]->vacc()->name()); - - if (!nt->tables()[track].delete_left_index() && - !nt->tables()[track].delete_right_index()) { + if (!nt->tables()[track].delete_left_index()) { + // we don't need a for loop, if left index is leftmost end + // (which is constant) + if (nt->left_indices[track] != nt->left_most_indices[track]) { + // linear and quadratic tables + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), nt->left_indices[track], + nt->left_most_indices[track]); + loopvariable->set_itr(true); + Expr::Less_Eq *cond = new Expr::Less_Eq( + nt->left_indices[track], + nt->right_most_indices[track]); + loops->push_back(new Statement::For(loopvariable, cond)); + fn_nt->add_arg(nt->left_indices[track]); + idx->push_back(nt->left_indices[track]->vacc()->name()); + } + } + + if (!nt->tables()[track].delete_right_index()) { + if (nt->right_indices[track] != nt->right_most_indices[track]) { // only quadratic tables - loopvariable = new Statement::Var_Decl( + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), nt->right_indices[track], nt->left_indices[track]); loopvariable->set_itr(true); - cond = new Expr::Less_Eq(nt->right_indices[track], + Expr::Less_Eq *cond = new Expr::Less_Eq(nt->right_indices[track], nt->right_most_indices[track]); loops->push_back(new Statement::For(loopvariable, cond)); fn_nt->add_arg(nt->right_indices[track]); @@ -173,7 +177,10 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { idx_param += "\",\""; } } - std::list *stmts = &((*loops->rbegin())->statements); + std::list *stmts = new std::list(); + if (loops->size() > 0) { + stmts = &((*loops->rbegin())->statements); + } stmts->push_back(new Statement::CustomeCode( "out << \"start answers " + *nt->name + "(\"" + idx_param + From 5bfb8bb1434f172f50312b2a02f2496c10da704b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 20:50:18 +0200 Subject: [PATCH 106/189] fix return type --- src/outside/codegen.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index add6a0604..48c43fd49 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -187,7 +187,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { "\"):\\n\";")); Statement::Var_Decl *res = new Statement::Var_Decl( - nt->return_decl().type, "res_" + *nt->name, fn_nt); + (*nt->code_list().begin())->return_type, "res_" + *nt->name, fn_nt); stmts->push_back(res); // produce call of "print_result" From 7f7e6a27e2bb47dd4327418774fd8542eb4c7869 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 20:50:31 +0200 Subject: [PATCH 107/189] add external functions for tests --- testdata/gapc_filter/RFmini_data.hh | 83 ++++++++++++++++++++++ testdata/gapc_filter/ext_hmm.hh | 102 ++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 testdata/gapc_filter/RFmini_data.hh create mode 100644 testdata/gapc_filter/ext_hmm.hh diff --git a/testdata/gapc_filter/RFmini_data.hh b/testdata/gapc_filter/RFmini_data.hh new file mode 100644 index 000000000..750f6f362 --- /dev/null +++ b/testdata/gapc_filter/RFmini_data.hh @@ -0,0 +1,83 @@ + +#ifndef CMPROBS_HH +#define CMPROBS_HH + +inline int charToIndex(char a) { + if ((a == 'A') || (a == 'a')) return 0; + if ((a == 'C') || (a == 'c')) return 1; + if ((a == 'G') || (a == 'g')) return 2; + if ((a == 'U') || (a == 'u')) return 3; + return 99; +} +inline int charToIndex(char a, char b) { + if (((a == 'A') || (a == 'a')) && ((b == 'A') || (b == 'a'))) return 0; + if (((a == 'A') || (a == 'a')) && ((b == 'C') || (b == 'c'))) return 1; + if (((a == 'A') || (a == 'a')) && ((b == 'G') || (b == 'g'))) return 2; + if (((a == 'A') || (a == 'a')) && ((b == 'U') || (b == 'u'))) return 3; + if (((a == 'C') || (a == 'c')) && ((b == 'A') || (b == 'a'))) return 4; + if (((a == 'C') || (a == 'c')) && ((b == 'C') || (b == 'c'))) return 5; + if (((a == 'C') || (a == 'c')) && ((b == 'G') || (b == 'g'))) return 6; + if (((a == 'C') || (a == 'c')) && ((b == 'U') || (b == 'u'))) return 7; + if (((a == 'G') || (a == 'g')) && ((b == 'A') || (b == 'a'))) return 8; + if (((a == 'G') || (a == 'g')) && ((b == 'C') || (b == 'c'))) return 9; + if (((a == 'G') || (a == 'g')) && ((b == 'G') || (b == 'g'))) return 10; + if (((a == 'G') || (a == 'g')) && ((b == 'U') || (b == 'u'))) return 11; + if (((a == 'U') || (a == 'u')) && ((b == 'A') || (b == 'a'))) return 12; + if (((a == 'U') || (a == 'u')) && ((b == 'C') || (b == 'c'))) return 13; + if (((a == 'U') || (a == 'u')) && ((b == 'G') || (b == 'g'))) return 14; + if (((a == 'U') || (a == 'u')) && ((b == 'U') || (b == 'u'))) return 15; + return 99; +} +static const float emissions[21][4] = { + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, +}; +inline float getEmission(int pos, char a) { + return emissions[pos][charToIndex(a)]; +} +static const float pair_emissions[21][16] = { + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.981, -8.618, 2.903, -4.869, -6.316, -8.108, 2.094, -7.200, -7.986, -4.905, -8.133, -6.722, -3.042, -8.451, -4.018, -6.800}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {1.986, -6.270, -7.785, -2.585, -9.584, -10.804, -5.093, -7.806, 2.908, 2.062, -8.009, -3.561, -5.179, -9.057, -6.956, -6.389}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, +}; +inline float getPairEmission(int pos, char a, char b) { + return pair_emissions[pos][charToIndex(a, b)]; +} +#endif diff --git a/testdata/gapc_filter/ext_hmm.hh b/testdata/gapc_filter/ext_hmm.hh new file mode 100644 index 000000000..f9afeb5a1 --- /dev/null +++ b/testdata/gapc_filter/ext_hmm.hh @@ -0,0 +1,102 @@ +#ifndef EXT_HMM_HH +#define EXT_HMM_HH + +template +inline +T negexpsum(T t) { + return t; +} + +template +inline +typename std::iterator_traits::value_type negexpsum(Itr begin, Itr end) { + typename std::iterator_traits::value_type n; + if (begin == end) { + empty(n); + return n; + } + assert(!isEmpty(*begin)); + n = exp(-1.0 * *begin); + ++begin; + for (; begin != end; ++begin) { + assert(!isEmpty(*begin)); + n += exp(-1.0 * *begin); + } + assert((n > 0 && "Your algebra produces (partial) candidates with negative " + "score, which cannot be logarithmized. Avoid h=negexpsum or " + "ensure all positive values!")); + return -1.0 * log(n); +} + +template +inline +typename std::iterator_traits::value_type +negexpsum(std::pair &p) { + return negexpsum(p.first, p.second); +} + +const static double THRESHOLD = 0.000000001; +inline List_Ref > filterLowProbLabels(List_Ref > candidates_orig) { + //return candidates_orig; + // do nothing if there is just one candidate at all + if (candidates_orig.ref().size() <= 1) { + return candidates_orig; + } + + List_Ref > candidates; + // obtain most probable candidate up to here + double bestValue = (*candidates_orig.ref().begin()).second; + for (List_Ref >::iterator i = candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { + if (bestValue > (*i).second) { + bestValue = (*i).second; + } + } + + // only keep candidates that are not smaller than the best candidate times THRESHOLD + // a value that should be changable by the user instead of hard coding it here + for (List_Ref >::iterator i = candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { + if ((*i).second <= (bestValue + log(1/THRESHOLD))) { + candidates.ref().push_back(*i); + } + } + return candidates; +} + +//template +//struct filterLowProbLabels2 { +// double bestValue; +// filterLowProbLabels2() : bestValue(0.0) { +// } +// void update(const T &src) { +// if (src.second > bestValue) { +// bestValue = src.second; +// } +// } +// bool ok(const T &x) const { +// return x.second <= lowProbabilityFilter(); +//// //sum = sum + x.second; +//// //return true; +//// double thresh = pow(22.56 * lowProbabilityFilter(), (x.first.size()-1)); +//// //double thresh = 0.1 * sum; +////// if (sum > 0) { +//// std::cerr << sum << ", " << x.second << "\t" << x.first << "\n"; +////// } +////// if (x.second != 1.0) { +////// std::cerr << (thresh > x.second) << "\t" << thresh << "\t" << x.second << "\n"; +////// } +//// //std::cerr << (pow(0.01, x.first.size())) << " " << x.second << "\n"; // "thresh: " << x.second << ", sum: " << sum << "\n"; +//// //return (sum > 0.01) || (count <= 1); +//// return true; //x.second > 0.3; +//// return (x.second > thresh) || (x.second == 1.0); +//// //return x.second > 0.5; +// } +//}; +// +//template +//inline double getPfuncValue(std::pair x) { +// return sum_elems(x.second.pf); +//} + + + +#endif From fea16c4f0adb54293fb824f43eb6d174a8f43c17 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 20:51:07 +0200 Subject: [PATCH 108/189] add more tests --- testdata/regresstest/config | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index da6c30eee..c1f3738c7 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -512,3 +512,40 @@ check_new_old_eq hmm_sonneregen.gap unused fwd "SSRR" outside_ssrr # example in which inside and outside NTs have different dimensions, don't use tmhmm_debug.gap as new semantic checks will prevent producing code check_new_old_eq tmhmm_debug_nil.gap unused count "AA" outside_report + +# example with multiple tracks for outside report function +check_new_old_eq_twotrack alignments.gap unused count "AAAA" outside_2track "BBB" +check_new_old_eq_twotrack alignments.gap unused sim_enum "AA" outside_undefvar "B" + +# example with parameterized terminals e.g. ROPE("manfred") +check_new_old_eq elmamun.gap unused count "1+2*3" outside_elm + +# check correct indices for multiple CONST_FLOAT args for outside generation; caused by incorrectly set yield size when replacing NTs +check_new_old_eq nonzero_constsize.gap unused count "G" outside_constissue + +# test if outside to inside transitions works also for constant non-terminal tables, i.e. those missing t_0_i t_0_j parameters which should be replaced via dummies in this one and only situation +check_new_old_eq constAxiom.gap unused enum "G" outside_out2in + +# check TMHMM outside with real sequence which previously revealed < 1.0 prob sums +CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA +##check_new_old_eq tmhmm.gap unused fwd_scaled "MENLNMDLLYMAAAVMMGLAAIGAAIGIGILGGKFLEGAARQPDLIPLLRTQFFIVMGLVDAIPMIAVGLGLYVMFAVA" outside_tmhmm + +#check_new_old_eq RFmini.gap unused enum "G" outside_cm +##check_new_old_eq RFmini.gap unused count "G" outside_cm + +# Results can be converted into probabilities via nt_inside(i,j) + nt_outside(i,j) - axiom(0,n) - axiom(0,0) +# where axiom(0,0) is the pfunc value of the empty word. This words because we are in log2-space. +# Converted to probabilities: 2^nt_inside(i,j) * 2^nt_outside(i,j) / 2^axiom(0,n) / 2^axiom(0,0) +# The important aspect is that we have to also normalize by axiom(0,0) since the inside result of +# the empty word "" != 0 <-- log2-space but will be integrated in each and every outside candidate +##check_new_old_eq RFmini.gap unused inside "G" outside_cm + +# more extensive example as before, also checked against cm_OutsideAlign of Infernal +GAPC="../../../gapc --outside_grammar state_MR_3 --outside_grammar state_MP_6 --outside_grammar state_S_0 --outside_grammar state_E_120" +##check_new_old_eq RF00005.gap unused inside "GACGGUAU" outside_cm5 + +GAPC="../../../gapc --outside_grammar a_1 --outside_grammar a_47 --outside_grammar a_82" +# not yet explored +##check_new_old_eq acmsearch_RF00005.gap unused inside "GACGGUAU" outside_acm + +CPPFLAGS_EXTRA="" \ No newline at end of file From 42b1acdbfbf123b12ffe113811d1cbbf6ceee5dd Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 23:10:17 +0200 Subject: [PATCH 109/189] activate more tests --- testdata/regresstest/config | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index c1f3738c7..99c022827 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -528,24 +528,24 @@ check_new_old_eq constAxiom.gap unused enum "G" outside_out2in # check TMHMM outside with real sequence which previously revealed < 1.0 prob sums CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA -##check_new_old_eq tmhmm.gap unused fwd_scaled "MENLNMDLLYMAAAVMMGLAAIGAAIGIGILGGKFLEGAARQPDLIPLLRTQFFIVMGLVDAIPMIAVGLGLYVMFAVA" outside_tmhmm +check_new_old_eq tmhmm.gap unused fwd_scaled "MENLNMDLLYMAAAVMMGLAAIGAAIGIGILGGKFLEGAARQPDLIPLLRTQFFIVMGLVDAIPMIAVGLGLYVMFAVA" outside_tmhmm -#check_new_old_eq RFmini.gap unused enum "G" outside_cm -##check_new_old_eq RFmini.gap unused count "G" outside_cm +check_new_old_eq RFmini.gap unused enum "G" outside_cm +check_new_old_eq RFmini.gap unused count "G" outside_cm # Results can be converted into probabilities via nt_inside(i,j) + nt_outside(i,j) - axiom(0,n) - axiom(0,0) # where axiom(0,0) is the pfunc value of the empty word. This words because we are in log2-space. # Converted to probabilities: 2^nt_inside(i,j) * 2^nt_outside(i,j) / 2^axiom(0,n) / 2^axiom(0,0) # The important aspect is that we have to also normalize by axiom(0,0) since the inside result of # the empty word "" != 0 <-- log2-space but will be integrated in each and every outside candidate -##check_new_old_eq RFmini.gap unused inside "G" outside_cm +check_new_old_eq RFmini.gap unused inside "G" outside_cm # more extensive example as before, also checked against cm_OutsideAlign of Infernal GAPC="../../../gapc --outside_grammar state_MR_3 --outside_grammar state_MP_6 --outside_grammar state_S_0 --outside_grammar state_E_120" -##check_new_old_eq RF00005.gap unused inside "GACGGUAU" outside_cm5 +check_new_old_eq RF00005.gap unused inside "GACGGUAU" outside_cm5 GAPC="../../../gapc --outside_grammar a_1 --outside_grammar a_47 --outside_grammar a_82" # not yet explored -##check_new_old_eq acmsearch_RF00005.gap unused inside "GACGGUAU" outside_acm +check_new_old_eq acmsearch_RF00005.gap unused inside "GACGGUAU" outside_acm CPPFLAGS_EXTRA="" \ No newline at end of file From 229f684aaedf5973eb4f7c46c3bfa45c33f4015d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 4 May 2023 23:10:47 +0200 Subject: [PATCH 110/189] adding more filters for example grammars --- .../acmsearch_RF00005_probabilities.hh | 1985 +++++++++++++++++ testdata/gapc_filter/isntimes.hh | 30 + 2 files changed, 2015 insertions(+) create mode 100644 testdata/gapc_filter/acmsearch_RF00005_probabilities.hh create mode 100644 testdata/gapc_filter/isntimes.hh diff --git a/testdata/gapc_filter/acmsearch_RF00005_probabilities.hh b/testdata/gapc_filter/acmsearch_RF00005_probabilities.hh new file mode 100644 index 000000000..4cd51ca5f --- /dev/null +++ b/testdata/gapc_filter/acmsearch_RF00005_probabilities.hh @@ -0,0 +1,1985 @@ +#ifndef MCMPROBS_HH +#define MCMPROBS_HH + +//learned transition and emission probabilities for 'RF00005'. + +inline int charToIndex(char a) { + if ((a == 'A') || (a == 'a')) return 0; + if ((a == 'C') || (a == 'c')) return 1; + if ((a == 'G') || (a == 'g')) return 2; + if ((a == 'U') || (a == 'u')) return 3; + return 99; +} +inline int charToIndex(char a, char b) { + if (((a == 'A') || (a == 'a')) && ((b == 'A') || (b == 'a'))) return 0; + if (((a == 'A') || (a == 'a')) && ((b == 'C') || (b == 'c'))) return 1; + if (((a == 'A') || (a == 'a')) && ((b == 'G') || (b == 'g'))) return 2; + if (((a == 'A') || (a == 'a')) && ((b == 'U') || (b == 'u'))) return 3; + if (((a == 'C') || (a == 'c')) && ((b == 'A') || (b == 'a'))) return 4; + if (((a == 'C') || (a == 'c')) && ((b == 'C') || (b == 'c'))) return 5; + if (((a == 'C') || (a == 'c')) && ((b == 'G') || (b == 'g'))) return 6; + if (((a == 'C') || (a == 'c')) && ((b == 'U') || (b == 'u'))) return 7; + if (((a == 'G') || (a == 'g')) && ((b == 'A') || (b == 'a'))) return 8; + if (((a == 'G') || (a == 'g')) && ((b == 'C') || (b == 'c'))) return 9; + if (((a == 'G') || (a == 'g')) && ((b == 'G') || (b == 'g'))) return 10; + if (((a == 'G') || (a == 'g')) && ((b == 'U') || (b == 'u'))) return 11; + if (((a == 'U') || (a == 'u')) && ((b == 'A') || (b == 'a'))) return 12; + if (((a == 'U') || (a == 'u')) && ((b == 'C') || (b == 'c'))) return 13; + if (((a == 'U') || (a == 'u')) && ((b == 'G') || (b == 'g'))) return 14; + if (((a == 'U') || (a == 'u')) && ((b == 'U') || (b == 'u'))) return 15; + return 99; +} +static const float transition_INS[114] = { + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -9.27842101362396, + -11.7150755128311, + -11.7150755128311, + -11.7142170042988, + 0, + -6.04886843113505, + 0, + -6.04911619848597, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + 0, + 0, + 0, + -1.83554758834624, + -11.7142170042988, + -11.7142170042988, + -11.454711832166, + 0, + 0, + -1.99158527698333, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7142170042988, + 0, + -6.46668479422329, + 0, + -9.89149423054478, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + -11.7142170042988, + 0, + -8.97077555960928, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + 0, + -9.73957133229954, + -11.7142170042988, + -11.9340832481215, + 0, + -3.10977853650155, + -11.4557394650617, + -11.4557394650617, + -11.4557394650617, + -11.4557394650617, + 0, + -5.35023176460691, + -11.454711832166, + -11.454711832166, + -11.454711832166, + -11.454711832166, + -1.5920976413332, + -7.78568565418503, + 0, + 0, + -3.15592197385827, + -11.4541977410938, + -11.4541977410938, + -11.4541977410938, + -11.4541977410938, + 0, + -5.39293284870118, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -7.35544197924373, + -11.7150755128311, + -11.7142170042988, + 0, + -10.5277770460398, + -11.7142170042988, + -11.7142170042988, + 0, + -7.81843491859719, + -11.7142170042988, + 0, + 0, + -6.5524860812714, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + 0, + -6.27749987149177, + 0, + -9.34038843361145, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + -11.7137875583784, + 0, + -7.23027254512234, + -11.7137875583784 +}; +inline float getTransition_INS(int pos) { + return transition_INS[pos-1]; +} +static const float emission_INS[114][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +inline float getEmission_INS(int pos, char a) { + return emission_INS[pos-1][charToIndex(a)]; +} +static const char consensus_INS[114] = { + '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' +}; +inline char getConsensus_INS(int pos) { + return consensus_INS[pos-1]; +} +static const float transition_NIL[114] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + 0, + -0.00168859522615523, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.00655293049007992, + 0, + 0, + -0.171684975244692, + -0.000514274329127762, + -0.000514274329127762, + -0.000514274329127762, + -0.000514274329127762, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + 0, + -0.0187185913112858, + 0, + -0.00222726885176205, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + -0.000429573791255782, + 0, + 0, + -0.000429573791255782 +}; +inline float getTransition_NIL(int pos) { + return transition_NIL[pos-1]; +} +static const float emission_NIL[114][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +inline float getEmission_NIL(int pos, char a) { + return emission_NIL[pos-1][charToIndex(a)]; +} +static const char consensus_NIL[114] = { + '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' +}; +inline char getConsensus_NIL(int pos) { + return consensus_NIL[pos-1]; +} +static const float transition_MAT[114] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.00349966370260687, + 0, + -0.0419035549249495, + 0, + 0, + 0, + 0, + 0, + -0.00340764425414578, + -0.0127584494907517, + -0.196783956314071, + 0, + 0, + 0, + -0.561858602866827, + -0.0879858148247409, + -0.2599588501246, + -0.184098635469782, + 0, + 0, + -0.430702157767299, + 0, + 0, + 0, + 0, + -0.00510270104735458, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.000859019711611433, + 0, + -0.00330786787855662, + -0.000859019711611433, + -0.000859019711611433, + -0.000859019711611433, + -0.000859019711611433, + -0.000859019711611433, + 0, + 0, + 0, + 0, + 0, + 0, + -0.203824122971645, + -0.0104510293542547, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.308012957679441, + -0.238006527850705, + -0.759934441775404, + -0.066082361301037, + -0.587121066479019, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.0366832675706433, + 0, + 0, + 0, + 0, + 0, + 0, + -0.0619368754046086, + 0, + -0.00325874999172237, + -0.00428067069849689, + -0.00293525068104741, + 0, + -0.0134077657988658, + -0.0410276352264734, + 0, + 0, + -0.133001876908042, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.0428032592892852, + 0 +}; +inline float getTransition_MAT(int pos) { + return transition_MAT[pos-1]; +} +static const float emission_MAT[114][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-2.4920585769606, -6.47036474980536, -3.33643849787516, 1.89218522142495}, + {0, 0, 0, 0}, + {1.03542712265564, -2.85980724595235, 0.750725212736773, -2.94469751929858}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1.90641268948116, -6.49100411825746, -3.38376821872922, -2.79265458189952}, + {0.760358965060502, -3.44650760756121, 0.935049049781041, -1.72544523016668}, + {-1.23149275789388, -0.357923108771789, -2.98518013252369, 1.41551299253663}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.82467343011755, -3.34767494893745, 1.79378065531256, -2.71557356815552}, + {-2.40923498665009, -3.22477079853062, 1.7813014043474, -1.902837361915}, + {-2.01434040708811, -0.730985936964696, -3.54909170849629, 1.61567495070349}, + {0.647140245944378, 0.0166089808252715, -2.92523672296032, 0.36816674231097}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1.68649126831648, -3.78405060869615, -0.934861966628626, -2.42983716365698}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0.637009736346049, -2.93646243378649, 0.987632214737567, -1.59360958646654}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-3.38784740354105, 1.2712924067486, -5.07067423302112, 0.546890330989002}, + {0, 0, 0, 0}, + {-10.7137875583784, -3.74284347865549, -10.7137875583784, 1.97236698798532}, + {-2.18082036174288, -0.627234879598764, 0.309663777185578, 0.920380807217418}, + {0.38346871105317, -0.135604214884109, -0.289169275762514, -0.0486153326031034}, + {0.609710319072397, -0.559089106688617, -0.355771297911057, 0.0198654271806174}, + {1.5821374965175, -7.87711290315466, -0.0245100746255326, -5.75939814930213}, + {1.49462023957187, -0.758367495244279, -3.1192321648013, -1.07141892728805}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0.756200405575541, -0.889117796377022, -1.60091588452477, 0.527422507116949}, + {0.167576652263699, -2.94357254407698, 1.0445367761872, -0.547636850621791}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.3263932888662, -1.44334224033831, -0.00597943262084921, 1.16198936361647}, + {0.0628468141253798, -0.418658105269201, -2.9531175722018, 1.05535270792705}, + {1.41161158820372, -1.7595235487793, -1.98572683723115, -0.336742950750635}, + {0.577972768975213, -1.07793849623254, -0.942291955334594, 0.597544606950452}, + {0.451465665584771, -2.22478578612639, -0.860029967736323, 0.901262443057504}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-2.10359358245381, 0.985437306484005, -2.64214348263489, 0.702408093713198}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-2.59901371153194, -3.33273524359236, -4.59348818175021, 1.88529081387053}, + {0, 0, 0, 0}, + {-2.7097088115393, -3.91653498298785, -2.59014513120548, 1.85393482842303}, + {-1.39802613373229, 1.71210254135168, -4.09408505654296, -1.80783984746946}, + {0.691181712632092, -3.28903897810506, 1.10034653685935, -2.84656564245194}, + {0, 0, 0, 0}, + {1.90386600762074, -4.01756678915429, -4.66303522616507, -2.67449174959137}, + {0.965816073373551, -1.66127304832618, -0.106373440181538, -0.318772536473363}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-2.9635329210641, -0.993631026182039, -4.87859900915325, 1.73794388857019}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1.14000666774651, -2.64232288095642, 0.19729204121856, -1.03072183763345}, + {0, 0, 0, 0} +}; +inline float getEmission_MAT(int pos, char a) { + return emission_MAT[pos-1][charToIndex(a)]; +} +static const char consensus_MAT[114] = { + '.', '.', '.', '.', '.', '.', '.', '.', 'U', '.', 'A', '.', '.', '.', '.', '.', 'A', 'G', 'U', '.', '.', '.', 'G', 'G', 'U', 'A', '.', '.', 'A', '.', '.', '.', '.', 'G', '.', '.', '.', '.', '.', '.', '.', 'C', '.', 'U', 'U', 'A', 'A', 'A', 'A', '.', '.', '.', '.', '.', '.', 'A', 'G', '.', '.', '.', '.', '.', '.', '.', '.', 'U', 'U', 'A', 'U', 'U', '.', '.', '.', '.', '.', '.', '.', '.', '.', 'C', '.', '.', '.', '.', '.', '.', 'U', '.', 'U', 'C', 'G', '.', 'A', 'A', '.', '.', 'U', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', 'A', '.' +}; +inline char getConsensus_MAT(int pos) { + return consensus_MAT[pos-1]; +} +static const float transition_DEL[114] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -8.87817394509401, + 0, + -6.20844392803255, + 0, + 0, + 0, + 0, + 0, + -8.92202911280715, + -6.8771559144773, + -2.97472708796591, + 0, + 0, + 0, + -4.56026945676262, + -4.08639666872053, + -2.60304583419111, + -3.06558296702247, + 0, + 0, + -7.23526094672286, + 0, + 0, + 0, + 0, + -8.27288829994943, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -11.7142170042988, + 0, + -11.7166658524657, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + -11.7142170042988, + 0, + 0, + 0, + 0, + 0, + 0, + -2.92734473156494, + -7.16620536429387, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -2.38164706094507, + -2.72044460248737, + -1.28940206029443, + -4.49279879003049, + -8.56457930353676, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -9.57953284241501, + 0, + 0, + 0, + 0, + 0, + 0, + -4.58293577882499, + 0, + -9.30688428704102, + -8.55158795853804, + -9.17095881283659, + 0, + -7.69663966855204, + -5.17188811722355, + 0, + 0, + -3.69125785405874, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -5.46924500200732, + 0 +}; +inline float getTransition_DEL(int pos) { + return transition_DEL[pos-1]; +} +static const float emission_DEL[114][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +inline float getEmission_DEL(int pos, char a) { + return emission_DEL[pos-1][charToIndex(a)]; +} +static const char consensus_DEL[114] = { + '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' +}; +inline char getConsensus_DEL(int pos) { + return consensus_DEL[pos-1]; +} +static const float transition_PK[114] = { + -0.00656277688771539, + -0.00171752824396981, + -0.00171752824396981, + -0.00171752824396981, + 0, + -0.00361343666224916, + -0.00171752824396981, + -0.00306960664618154, + 0, + 0, + 0, + 0, + -0.0232421173803277, + -0.00171752824396981, + -0.00299758498429668, + -0.00171752824396981, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.0204982923248839, + 0, + -0.00280806909416814, + -0.00171752824396981, + -0.00279451612708457, + -0.0024145000503424, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -1.22294935726172, + -0.710064735546608, + -0.518350894409654, + -0.537165496058232, + -0.377025626829114, + 0, + -0.30088495759632, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.0118676218671745, + -0.00171752824396981, + -0.00171752824396981, + 0, + -0.0197023183360829, + -0.0728932592203077, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +inline float getTransition_PK(int pos) { + return transition_PK[pos-1]; +} +static const float emission_PK[114][16] = { + {-6.60908079415301, -4.12290157831702, -4.48741021151871, 1.21309966095171, -4.41586855391075, -4.99446690427395, 0.283581433240386, -6.47000115862424, -8.711527166232, 3.27361320519027, -6.09465307336837, 0.49315290501025, 0.104021729851864, -8.711527166232, -8.711527166232, -3.50651048087939}, + {-8.71636231849831, -4.65765276656937, -8.71636231849831, 1.23643236523696, -3.92416475312857, -5.61718529060843, 2.35436399856008, -5.84964837370429, -8.71636231849831, 2.46315598671316, -8.71636231849831, -0.402055070508206, 0.957631083102156, -7.46594511601114, -2.70823518733355, -7.46594511601114}, + {-4.85126589714268, -5.21450276202508, -5.38945529611208, 2.00196099411352, -4.4808688021655, -5.85783727712423, 2.01135495523976, -5.11290478926855, -8.71636231849831, 2.06472291872637, -5.10933758960029, -1.05239915389175, 1.49713081454059, -6.15513563810565, -2.20540255877271, -4.80058630045938}, + {-3.30648154961084, -5.19023562376085, -6.45257876431216, 1.74630727025044, -3.61872087328513, -4.72791214985256, 1.51363505682695, -6.42377936223569, -6.12418215868402, 2.48857011502017, -8.71636231849831, -0.455778436006373, 1.3919085184308, -8.71636231849831, -0.962268886735713, -5.56483186188244}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-4.3853183321281, -4.36233073928673, -5.28920872580287, 2.28175352404631, -3.76222407099144, -5.69170049647995, 1.54921864766212, -5.45281387692378, -5.779088334209, 2.04425559076283, -4.97678679472563, -0.546339339557273, 1.30951516778034, -7.17369786657618, -0.815624957465243, -4.06348999505597}, + {-5.38945529611208, -4.87247589992041, -3.39922441246814, 1.75738754453822, -4.04935812359833, -6.07023647790909, 1.32885167644806, -7.17369786657618, -8.71636231849831, 1.81762960509319, -8.71636231849831, -0.35601068950764, 2.04818307140107, -8.71636231849831, 0.191071051064967, -1.83029830006657}, + {-8.71501305411181, -4.58546370491314, -8.71501305411181, 2.53265377700946, -8.71501305411181, -8.71501305411181, -0.959803565538051, -8.71501305411181, -6.13983006309753, 2.51481002264927, -8.71501305411181, -0.778452271164834, 1.72105160518419, -8.71501305411181, -8.71501305411181, -5.07490334013118}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-8.71636231849831, -5.47944803529063, -4.22555686508435, 0.0302397291740647, -8.71636231849831, -8.71636231849831, 0.628219603411845, -5.48736945243065, -3.49187008014353, 3.44424995648719, -4.39912337254317, 0.48578524782188, -0.339113808884964, -8.71636231849831, -5.03771650799157, -3.5900688523172}, + {-8.71636231849831, -3.12888572792941, -7.48846543660413, -1.03813766675467, -8.71636231849831, -8.71636231849831, 3.24200245419753, -8.71636231849831, -8.71636231849831, -0.370108067748898, -8.71636231849831, -4.05746927826427, 2.19725735724269, -4.01525583874839, -1.41089904889703, -4.05746927826427}, + {-3.8589610799619, -4.80670051537305, -8.71508492581211, 0.71212558785002, -2.73181664914924, -8.71508492581211, 1.90865978624013, -8.71508492581211, -4.98293418322919, 1.84890130835252, -8.71508492581211, -4.50442901958313, 2.60940015264899, -8.71508492581211, -0.843518998883421, -8.71508492581211}, + {1.33196218990531, -3.13766652355298, -3.32573307956659, -0.634196875059482, -3.31779031903055, -4.45558518016831, 1.75252440166795, -6.01244445590882, 1.95923344141962, -2.79932559246577, -4.53919386709455, -1.26406460407023, 1.38864835219632, -4.54503230872325, 0.45326688278077, -0.805484937143985}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-2.56069454752856, -3.65931767330046, -3.96899955283815, 1.38619793742062, -2.8710060996606, -5.25719318022575, 2.27393236200631, -2.77626555506801, -3.74388989231196, -0.30622280187448, -8.71356316940792, 0.609826718652964, 2.20580310081941, -3.46122050816919, -0.741133909539416, -2.22313732200639}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-8.71636231849831, -8.71636231849831, -8.71636231849831, 1.39161443462993, -8.71636231849831, -5.31992765457882, 2.53964882837154, -4.35679421409295, -8.71636231849831, 0.413645838101345, -8.71636231849831, -1.10361234923009, 2.33568484459055, -8.71636231849831, -1.15486547333393, -2.49891106262211}, + {-4.23256346272539, -3.37884183703647, -8.71636231849831, 2.18947925342695, -5.34630349280643, -5.87968766327455, 0.689385854740842, -8.71636231849831, -8.71636231849831, 2.46635835872994, -8.71636231849831, -2.80170220074326, 1.93426157909946, -8.71636231849831, -5.61718529060843, -3.16968563104058}, + {-5.74173149452111, -4.44541144184977, -8.71528757188497, 1.04846703402605, -6.64165509912693, -8.71528757188497, 1.44897828184515, -6.04916706319308, -8.71528757188497, 3.25953090120382, -8.71528757188497, -0.04004854675199, -1.74342336478137, -8.71528757188497, -2.61514176093497, -3.49477213588575}, + {-4.84522485098844, -3.43905162122646, -3.23367097951154, 2.75117150241655, -5.39383086053385, -8.71566679693716, 1.47638184266597, -8.71566679693716, -5.96571843338298, 1.42157744427863, -5.28171696872659, -1.66736378244527, 1.3138550744817, -6.59515753804732, -1.10406579398942, -2.14491999198764}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-6.42571853779741, -6.42571853779741, -1.88088364092335, 1.14200611429412, -1.94606136689675, -6.42571853779741, 0.972755977200436, -6.42571853779741, -6.42571853779741, 1.06558589327552, 0.580913497883728, -1.24066097887976, 1.75163291174421, -6.42571853779741, 1.78537999924705, -1.31036029132462}, + {-6.75822361672778, -2.80807699129682, -6.75822361672778, 1.26139905512881, -6.75822361672778, -6.75822361672778, -0.13739781159697, -6.75822361672778, -6.75822361672778, 3.05076832017245, -6.75822361672778, -0.406844139275718, 1.77298111889791, -6.75822361672778, -6.75822361672778, -6.75822361672778}, + {-6.94838187007307, -6.94838187007307, -6.94838187007307, 1.62068056615331, -6.94838187007307, -6.94838187007307, 1.91010177159214, -6.94838187007307, -6.94838187007307, 2.6032195123379, -6.94838187007307, -0.98571559306759, 1.07181671873199, -6.94838187007307, -1.31470683814333, -6.94838187007307}, + {-6.92971101855924, -6.92971101855924, -6.92971101855924, 1.43900360739982, -2.45005384765858, -6.92971101855924, 2.00219260740891, -2.20873376097643, -6.92971101855924, 2.15754156156027, -6.92971101855924, -0.00970379600818551, 1.51947795314353, -6.92971101855924, -1.01181000506035, -6.92971101855924}, + {-7.08868484403618, -7.08868484403618, -7.08868484403618, 0.57348703914753, -1.58150795786463, -7.08868484403618, 2.53857825868038, -2.64001873299994, -7.08868484403618, 1.98694048379375, -7.08868484403618, -1.53856935951024, 1.49795960660791, -7.08868484403618, 0.02258662856285, -7.08868484403618}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-0.658868413313561, -7.19938037523355, -7.19938037523355, 0.331070950116404, -0.777081629726399, -7.19938037523355, 1.71010943072693, -7.19938037523355, -0.741491524273313, 0.620716023213197, -0.0165424652892273, -1.53467904519069, 1.79538834571108, -0.478513979723628, 0.168267985643063, 0.530102012205168}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-5.11614943858233, -6.18511326988717, -8.70623341419599, 2.10980755098777, -5.62862986201713, -8.70623341419599, 0.890969598729971, -8.70623341419599, -8.70623341419599, 2.7519881187833, -8.70623341419599, 1.0894676186101, -0.634236226000939, -3.59225886523733, -2.97773283509752, -4.79829369981831}, + {-8.71636231849831, -5.60974901388318, -8.71636231849831, 1.80022034157922, -6.77705216177713, -8.71636231849831, 2.15175274819109, -8.71636231849831, -8.71636231849831, 1.16136754132635, -8.71636231849831, -0.258657082669017, 2.05867366082083, -3.13586273712329, -0.895423293749133, -2.83870989748452}, + {-8.71636231849831, -3.79718608631489, -8.71636231849831, 2.31960003302799, -8.71636231849831, -8.71636231849831, 1.02890446880483, -6.52868533315446, -7.04872651216834, 2.57731256199153, -6.14605169619748, -1.55033912391913, 0.993821814337381, -8.71636231849831, -1.25496394296251, -2.93119935387287}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-8.70680513218898, -3.15580262176512, -8.70680513218898, 1.59645251926543, -4.87010348742126, -8.70680513218898, -1.66671403115297, -4.75665850675801, -4.18212031854679, 3.50505608086595, -8.70680513218898, -2.79852601671669, -0.373375384308045, -8.70680513218898, -3.05692441640905, -5.55318584503851}, + {-8.64533835813642, -3.22062674051936, -8.64533835813642, -1.11042307560867, -3.00820012960591, -4.62252800118107, -5.96185425144063, -5.12974627392096, -8.64533835813642, 3.89499248206999, -6.54446342380699, -3.83470924053665, -2.90526682606326, -4.06095652633297, -5.13725991217018, -4.91402717230099}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; +inline float getEmission_PK(int pos, char a, char b) { + return emission_PK[pos-1][charToIndex(a, b)]; +} +static const char consensus_PK[114][2] = { + {'G','C'}, {'G','C'}, {'G','C'}, {'G','C'}, {'.','.'}, {'A','U'}, {'U','A'}, {'A','U'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'G','C'}, {'C','G'}, {'U','A'}, {'G','A'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'C','G'}, {'.','.'}, {'C','G'}, {'G','C'}, {'G','C'}, {'A','U'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'U','G'}, {'G','C'}, {'G','C'}, {'G','C'}, {'C','G'}, {'.','.'}, {'U','A'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'G','C'}, {'C','G'}, {'G','C'}, {'.','.'}, {'G','C'}, {'G','C'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'} +}; +inline char getConsensus_PK(int pos, int leftRight) { + return consensus_PK[pos-1][leftRight]; +} +static const float transition_Lr[114] = { + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -11.7169714212494, + -11.7150755128311, + -9.66351361889786, + 0, + 0, + 0, + 0, + -11.7366001019675, + -11.7150755128311, + -9.72300876507791, + -11.7150755128311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -8.81986023794255, + 0, + -11.7161660536813, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -4.97911341679445, + -4.65021576958092, + -5.97374364763613, + -2.43841072507744, + -3.58497942253878, + 0, + -11.4910331325829, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -7.0979028430555, + -11.7150755128311, + -11.7150755128311, + 0, + -11.7234831272814, + -9.68249590531583, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +inline float getTransition_Lr(int pos) { + return transition_Lr[pos-1]; +} +static const float emission_Lr[114][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.36332398261526, -1.36332398261526, -1.36332398261526, 1.50281065679893}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.31558498686858, 1.48269979161902, -1.31558498686858, -1.31558498686858}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-2.09125802383642, 1.72070403694614, -2.09125802383642, -2.09125802383642}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-4.69609261177586, -4.69609261177586, 1.95764244211373, -4.69609261177586}, + {-4.8437066250348, 0.0141131024184804, 0.960150949507978, 0.0141131024184804}, + {-3.57572327883913, -3.57572327883913, -3.57572327883913, 1.90627253858649}, + {0.491935561399407, 0.55933822041567, -0.618651083722627, -1.09296500809028}, + {0.252732113754849, 1.40701243919016, -2.83865429249518, -5.88913356842684}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {1.91268492517269, -3.67479166539621, -3.67479166539621, -3.67479166539621}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.34805037339588, 1.49647890266884, -1.34805037339588, -1.34805037339588}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +inline float getEmission_Lr(int pos, char a) { + return emission_Lr[pos-1][charToIndex(a)]; +} +static const char consensus_Lr[114][2] = { + {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'U','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'C','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'C','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'G','.'}, {'G','.'}, {'U','.'}, {'C','.'}, {'C','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'A','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'C','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'} +}; +inline char getConsensus_Lr(int pos, int leftRight) { + return consensus_Lr[pos-1][leftRight]; +} +static const float transition_lR[114] = { + -8.09935269013284, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -11.7169714212494, + -11.7150755128311, + -11.7150755128311, + 0, + 0, + 0, + 0, + -11.7366001019675, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -11.7310512869962, + 0, + -11.7161660536813, + -11.7150755128311, + -9.90533209335196, + -10.3244961394781, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -2.03381696405079, + -1.91350923035586, + -2.44405533460957, + -4.0234547511495, + -5.16544504071276, + 0, + -3.60717667176639, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -11.7234831272814, + -8.85039367349072, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +inline float getTransition_lR(int pos) { + return transition_lR[pos-1]; +} +static const float emission_lR[114][4] = { + {0.014500063741495, -2.72885700674174, -2.72885700674174, 1.4266446439044}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.17178306328819, -1.17178306328819, -1.17178306328819, 1.41596563359021}, + {-0.856722616788065, 1.22859291775126, -0.856722616788065, -0.856722616788065}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-1.20381481936645, -1.407474942016, 0.615199335495587, 0.728689956448877}, + {-3.46481691416225, -7.54802353442095, 0.783696517074879, 1.12601471349121}, + {-1.45645620807147, -0.272603019599286, 0.665004757499518, 0.289497884522051}, + {0.35922464138632, -5.4571280830775, -1.04833081425044, 1.14468128370714}, + {1.41339065907704, -4.34456131110192, 0.307932275154057, -4.34456131110192}, + {0, 0, 0, 0}, + {0.0814155290496774, -1.65892228543662, 1.13935546079498, -1.24317195441834}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {-2.05028439570583, 0.190203658564044, 1.24865764772631, -2.05028439570583}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +inline float getEmission_lR(int pos, char a) { + return emission_lR[pos-1][charToIndex(a)]; +} +static const char consensus_lR[114][2] = { + {'U','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'U','.'}, {'C','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'U','.'}, {'U','.'}, {'G','.'}, {'U','.'}, {'A','.'}, {'.','.'}, {'G','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'G','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'} +}; +inline char getConsensus_lR(int pos, int leftRight) { + return consensus_lR[pos-1][leftRight]; +} +static const float transition_bg[114] = { + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -11.7169714212494, + -11.7150755128311, + -11.7150755128311, + 0, + 0, + 0, + 0, + -11.7366001019675, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -11.7310512869962, + 0, + -11.7161660536813, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -2.47522321375137, + -3.58933553508609, + -3.29624437101872, + -3.95362753140998, + -3.07796715320674, + 0, + -3.62017614186889, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -11.7150755128311, + -11.7150755128311, + -11.7150755128311, + 0, + -7.18634520542587, + -4.4551511343302, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; +inline float getTransition_bg(int pos) { + return transition_bg[pos-1]; +} +static const float emission_bg[114][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; +inline float getEmission_bg(int pos, char a) { + return emission_bg[pos-1][charToIndex(a)]; +} +static const char consensus_bg[114][2] = { + {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'}, {'.','.'} +}; +inline char getConsensus_bg(int pos, int leftRight) { + return consensus_bg[pos-1][leftRight]; +} + +#endif diff --git a/testdata/gapc_filter/isntimes.hh b/testdata/gapc_filter/isntimes.hh new file mode 100644 index 000000000..7cb308693 --- /dev/null +++ b/testdata/gapc_filter/isntimes.hh @@ -0,0 +1,30 @@ +#ifndef ISNTIMES_HH +#define ISNTIMES_HH + +template +inline bool isntimes(const Basic_Sequence &seq, T i, T j, alphabet x, unsigned int size) +{ + if (j +inline bool isAnyBase(const Basic_Sequence<> &seq, T i, T j) { + if (j Date: Fri, 5 May 2023 08:07:15 +0200 Subject: [PATCH 111/189] add missing header file --- testdata/gapc_filter/RF00005_data.hh | 495 +++++++++++++++++++++++++++ 1 file changed, 495 insertions(+) create mode 100644 testdata/gapc_filter/RF00005_data.hh diff --git a/testdata/gapc_filter/RF00005_data.hh b/testdata/gapc_filter/RF00005_data.hh new file mode 100644 index 000000000..280bc6449 --- /dev/null +++ b/testdata/gapc_filter/RF00005_data.hh @@ -0,0 +1,495 @@ + +#ifndef CMPROBS_HH +#define CMPROBS_HH + +inline int charToIndex(char a) { + if ((a == 'A') || (a == 'a')) return 0; + if ((a == 'C') || (a == 'c')) return 1; + if ((a == 'G') || (a == 'g')) return 2; + if ((a == 'U') || (a == 'u')) return 3; + return 99; +} +inline int charToIndex(char a, char b) { + if (((a == 'A') || (a == 'a')) && ((b == 'A') || (b == 'a'))) return 0; + if (((a == 'A') || (a == 'a')) && ((b == 'C') || (b == 'c'))) return 1; + if (((a == 'A') || (a == 'a')) && ((b == 'G') || (b == 'g'))) return 2; + if (((a == 'A') || (a == 'a')) && ((b == 'U') || (b == 'u'))) return 3; + if (((a == 'C') || (a == 'c')) && ((b == 'A') || (b == 'a'))) return 4; + if (((a == 'C') || (a == 'c')) && ((b == 'C') || (b == 'c'))) return 5; + if (((a == 'C') || (a == 'c')) && ((b == 'G') || (b == 'g'))) return 6; + if (((a == 'C') || (a == 'c')) && ((b == 'U') || (b == 'u'))) return 7; + if (((a == 'G') || (a == 'g')) && ((b == 'A') || (b == 'a'))) return 8; + if (((a == 'G') || (a == 'g')) && ((b == 'C') || (b == 'c'))) return 9; + if (((a == 'G') || (a == 'g')) && ((b == 'G') || (b == 'g'))) return 10; + if (((a == 'G') || (a == 'g')) && ((b == 'U') || (b == 'u'))) return 11; + if (((a == 'U') || (a == 'u')) && ((b == 'A') || (b == 'a'))) return 12; + if (((a == 'U') || (a == 'u')) && ((b == 'C') || (b == 'c'))) return 13; + if (((a == 'U') || (a == 'u')) && ((b == 'G') || (b == 'g'))) return 14; + if (((a == 'U') || (a == 'u')) && ((b == 'U') || (b == 'u'))) return 15; + return 99; +} +static const float emissions[227][4] = { + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.967, -1.762, 0.127, -0.603}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {-0.245, -0.619, -0.992, 1.001}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.232, -0.364, -0.344, 0.334}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {-1.820, -4.082, -2.351, 1.791}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {1.129, -2.503, 0.522, -2.312}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.797, -0.772, -1.416, 0.380}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.271, -2.060, 0.792, -0.282}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.603, -2.320, 0.645, -0.480}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-1.828, 0.976, -2.145, 0.609}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {-0.043, 0.441, -0.742, 0.103}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {-1.717, -2.581, -3.687, 1.787}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-1.901, -2.867, -2.450, 1.771}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-0.776, 1.547, -3.413, -1.324}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.711, -2.398, 0.934, -1.928}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {1.824, -2.680, -3.033, -2.468}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.973, -1.119, -0.690, -0.063}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-2.268, -1.024, -4.138, 1.698}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.232, -0.043, -0.423, 0.149}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {1.792, -4.422, -2.541, -1.645}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.666, -2.273, 0.835, -1.244}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-0.563, -0.298, -2.598, 1.229}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-1.088, -2.493, 1.635, -2.025}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-1.735, -2.296, 1.633, -1.345}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-1.587, -0.860, -2.982, 1.580}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {1.688, -3.294, -1.536, -1.599}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.683, -2.722, 0.793, -0.970}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {-0.163, 0.616, -0.875, 0.042}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.368, -0.385, -0.191, 0.094}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.225, -0.363, -0.352, 0.346}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {0.0, 0.0, 0.0, 0.0}, + {0.368, -0.385, -0.191, 0.094}, + {0.251, -0.082, -0.397, 0.145}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, + {-2.829, 1.248, -4.245, 0.518}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-6.408, -3.367, -7.171, 1.958}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {-1.730, -0.660, 0.415, 0.793}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.264, -0.063, -0.290, 0.034}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.507, -0.440, -0.526, 0.199}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {1.656, -5.193, -0.360, -4.593}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {1.517, -0.862, -2.536, -1.270}, + {0.0, 0.0, 0.0, 0.0}, + {0.000, 0.000, 0.000, 0.000}, + {0.000, 0.000, 0.000, 0.000}, +}; +inline float getEmission(int pos, char a) { + return emissions[pos][charToIndex(a)]; +} +static const float pair_emissions[227][16] = { + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-5.364, -3.089, -4.327, 1.380, -3.808, -4.601, 0.302, -4.695, -6.319, 3.165, -5.456, 0.495, 0.320, -5.774, -4.107, -3.653}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-6.007, -4.160, -5.951, 1.497, -4.299, -5.407, 2.066, -5.173, -6.133, 2.581, -6.530, -0.771, 0.996, -5.787, -2.677, -4.763}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.248, -3.450, -3.395, 2.144, -3.133, -4.398, 1.760, -3.669, -3.855, 1.775, -3.934, -0.650, 1.490, -3.635, -1.280, -2.611}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.221, -3.413, -3.535, 1.722, -2.977, -3.650, 1.427, -3.771, -3.398, 2.245, -4.398, -0.248, 1.432, -3.897, -0.505, -2.806}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.472, -2.910, -3.298, 2.334, -2.865, -3.884, 1.561, -3.745, -3.505, 1.638, -3.961, -0.809, 1.348, -3.685, -0.565, -2.502}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.394, -3.984, -3.723, 1.568, -2.885, -4.444, 1.480, -4.093, -4.044, 1.659, -4.615, -0.375, 2.136, -4.127, -0.039, -1.657}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-6.166, -3.166, -5.989, 2.553, -7.067, -6.589, -0.358, -6.661, -5.268, 2.491, -6.669, -0.828, 1.504, -5.848, -4.163, -4.220}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-3.854, -4.558, -5.947, 2.137, -4.877, -6.553, 0.809, -6.612, -6.367, 2.775, -6.628, 0.743, -0.271, -3.669, -2.651, -4.070}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-4.666, -4.173, -4.824, 1.843, -4.040, -5.672, 2.065, -4.967, -4.849, 1.244, -5.407, -0.370, 1.918, -4.134, -0.764, -1.473}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-5.903, -3.408, -5.802, 2.181, -6.466, -6.449, 0.850, -5.574, -5.510, 2.656, -5.702, -0.845, 1.069, -5.715, -1.692, -2.625}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-6.161, -2.671, -5.979, 1.682, -4.238, -6.575, -1.024, -5.274, -3.362, 3.395, -6.664, -1.585, -0.233, -5.834, -2.993, -3.844}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-6.091, -2.555, -5.909, 0.014, -2.422, -4.254, -1.966, -4.716, -6.348, 3.744, -5.330, -1.897, -1.507, -3.823, -3.341, -4.875}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-6.151, -4.431, -3.700, 0.635, -7.080, -6.572, 0.534, -4.868, -4.084, 3.314, -4.822, 0.708, -0.271, -5.831, -3.270, -2.447}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-6.442, -5.026, -5.615, -0.442, -5.322, -7.289, 3.134, -5.973, -6.306, 0.420, -6.820, -3.345, 2.133, -4.092, -1.261, -4.187}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.956, -3.236, -5.498, 0.763, -2.438, -6.346, 1.852, -5.433, -4.783, 1.324, -6.017, -3.202, 2.763, -5.656, -0.526, -4.430}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.671, -2.885, -1.628, 0.325, -2.963, -3.779, 1.747, -3.851, 1.255, -0.689, -3.286, -0.364, 1.696, -3.043, 0.401, -0.995}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.237, -2.053, -3.155, 1.253, -2.279, -3.398, 2.076, -1.914, -3.153, 0.023, -4.318, 0.413, 2.214, -2.674, -0.614, -1.686}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-5.608, -5.549, -5.706, 1.290, -5.005, -3.722, 2.496, -3.844, -5.660, 0.382, -6.200, -1.388, 2.386, -5.869, -0.958, -2.332}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-4.525, -2.838, -5.648, 2.002, -4.830, -4.261, 0.835, -6.105, -5.916, 2.561, -6.293, -2.010, 1.817, -5.606, -3.378, -3.507}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-5.176, -3.076, -5.982, 1.354, -6.059, -6.578, 1.193, -5.535, -6.417, 3.221, -6.665, -0.241, -1.060, -5.837, -2.639, -3.364}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {-2.699, -2.468, -3.094, 2.445, -3.539, -4.541, 1.514, -4.041, -2.655, 1.418, -3.793, -1.041, 1.370, -3.433, -0.480, -1.862}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, +}; +inline float getPairEmission(int pos, char a, char b) { + return pair_emissions[pos][charToIndex(a, b)]; +} +#endif From cb29c449bc75f21f53d9bd077371231b117b863e Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 08:11:21 +0200 Subject: [PATCH 112/189] activate first CYK test --- testdata/regresstest/config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index 99c022827..72ddcaa64 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -493,6 +493,9 @@ check_new_old_eq nodangle.gap unused count "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outsi check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside_overlay +# same as above, but with CYK code generation +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside From a7967cff58ed075c82bbc67bd81517ce93eec9ef Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 12:46:29 +0200 Subject: [PATCH 113/189] first version to generate CYK code (not yet for openMP nor outside) --- src/outside/codegen.cc | 121 ++++++++++++++++++++++++++++++++++++++++- src/outside/codegen.hh | 1 + 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 48c43fd49..64dfcb5d9 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -212,7 +212,126 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { } } } - stream << *fn << "\n"; + stream << *fn << endl; stream.in_class = old_in_class; } + + +Fn_Def *print_CYK(const AST &ast) { + Fn_Def *fn_cyk = new Fn_Def(new Type::RealVoid(), new std::string("cyk")); + + std::list::const_iterator it_stmt_n = (*ast.grammar()->topological_ord().begin())->table_decl->ns().begin(); + std::vector::const_iterator it_stmt_seq = ast.seq_decls.begin(); + for (size_t track = 0; track < ast.grammar()->axiom->tracks(); ++track, ++it_stmt_n, ++it_stmt_seq) { + std::list *stmts_const = new std::list(); + std::list *stmts_linear = new std::list(); + std::list *stmts_quadratic = new std::list(); + + // A: quadratic loops + Statement::For *loop_quadratic_outer = nullptr; + Statement::For *loop_quadratic_inner = nullptr; + Statement::For *loop_linear = nullptr; + Statement::Var_Decl *t_i = nullptr; + Statement::Var_Decl *t_j = nullptr; + for (std::list::const_iterator it_nt = ast.grammar()->topological_ord().begin(); it_nt != ast.grammar()->topological_ord().end(); ++it_nt) { + if ((*it_nt)->is_tabulated()) { + if (!(*it_nt)->tables()[track].delete_right_index()) { + if (!loop_quadratic_outer) { + // create outer J loop + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), + (*it_nt)->right_indices[track], + (*it_nt)->left_most_indices[track]); + loopvariable->set_itr(true); + Expr::Less *cond = new Expr::Less( + (*it_nt)->right_indices[track], + (*it_nt)->right_most_indices[track]); + loop_quadratic_outer = new Statement::For(loopvariable, cond); + loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// A: quadratic loops")); + + t_j = (*loopvariable).clone(); + t_j->rhs = (*it_nt)->right_most_indices[track]; + t_j->set_itr(false); + } + } + + if (!(*it_nt)->tables()[track].delete_right_index() && + !(*it_nt)->tables()[track].delete_left_index()) { + if (!loop_quadratic_inner) { + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), + (*it_nt)->left_indices[track], + (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))); + loopvariable->set_itr(true); + Expr::Greater *cond = new Expr::Greater( + (*it_nt)->left_indices[track], + new Expr::Const(1)); + loop_quadratic_inner = new Statement::For(loopvariable, cond); + loop_quadratic_inner->decrement = true; + + loop_linear = dynamic_cast(loop_quadratic_inner->copy()); + + t_i = (*loopvariable).clone(); + t_i->rhs = new Expr::Const(1); + t_i->set_itr(false); + } + } + + // produce: nt_tabulate_iloop(t_0_i-1, t_0_j); + std::list *args = new std::list(); + // t_0_i - 1 + Statement::Var_Decl *idx_i = (*loop_quadratic_inner->var_decl).clone(); + idx_i->set_itr(false); + if (!(*it_nt)->tables()[track].delete_left_index()) { + args->push_back((new Expr::Vacc(*idx_i))->minus(new Expr::Const(1))); + } + // t_0_j + Statement::Var_Decl *idx_j = (*loop_quadratic_outer->var_decl).clone(); + idx_j->set_itr(false); + if (!(*it_nt)->tables()[track].delete_right_index()) { + args->push_back(new Expr::Vacc(*idx_j)); + } + Statement::Fn_Call *nt_call = new Statement::Fn_Call((*(*it_nt)->code_list().rbegin())->name, args, Loc()); + //stmts->push_back(nt_call); + + if (!(*it_nt)->tables()[track].delete_right_index() && + !(*it_nt)->tables()[track].delete_left_index()) { + stmts_quadratic->push_back(nt_call); + } + if (!(*it_nt)->tables()[track].delete_right_index() || + !(*it_nt)->tables()[track].delete_left_index()) { + stmts_linear->push_back(nt_call); + } + stmts_const->push_back(nt_call); + } + } + + if (loop_quadratic_outer && loop_quadratic_inner) { + loop_quadratic_inner->statements = *stmts_quadratic; + std::list *loops = new std::list(); + loops->push_back(loop_quadratic_outer); + loops->push_back(loop_quadratic_inner); + nest_for_loops(loops->begin(), loops->end()); + + loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// B: inner quadratic loops")); + loop_quadratic_outer->statements.push_back(t_i); + loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_quadratic->begin(), stmts_quadratic->end()); + + fn_cyk->stmts.push_back(*loops->begin()); + } + + if (loop_linear) { + fn_cyk->stmts.push_back(new Statement::CustomeCode("// C: linear loops")); + fn_cyk->stmts.push_back(t_j); + loop_linear->statements = *stmts_linear; + fn_cyk->stmts.push_back(loop_linear); + } + + fn_cyk->stmts.push_back(new Statement::CustomeCode("// D: constant loops")); + fn_cyk->stmts.push_back(t_i); + fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_const->begin(), stmts_const->end()); + } + + return fn_cyk; +} diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh index a497fb348..68621d26a 100644 --- a/src/outside/codegen.hh +++ b/src/outside/codegen.hh @@ -38,5 +38,6 @@ #include "grammar_transformation.hh" void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast); +Fn_Def *print_CYK(const AST &ast); #endif // SRC_OUTSIDE_CODEGEN_HH_ From 6ad9ed66d73296b7d56f4769f7ff4bcbc50ff80b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 14:08:00 +0200 Subject: [PATCH 114/189] add checkpointing --- src/outside/codegen.cc | 111 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 64dfcb5d9..b51c8743f 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -221,12 +221,53 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { Fn_Def *print_CYK(const AST &ast) { Fn_Def *fn_cyk = new Fn_Def(new Type::RealVoid(), new std::string("cyk")); + if (ast.checkpoint && ast.checkpoint->cyk) { + /* + define a boolean marker (as an int) for every loop idx + to allow for the loading of the checkpointed loop indices; + if the user wants to load a checkpoint (load_checkpoint == true) + and the loaded idx value doesn't equal the default value 0 + (meaning that the checkpointed program made enough progress + to get to the loop where the current idx lives), + the markers will be set to "false" (== 0), which indicates + that the respective loop idx hasn't been loaded yet and + should be loaded when it is first requested; + if the user does not want to load a checkpoint + (load_checkpoint == false) or the load idx values are still 0, + the respective markers will be set to "true" (== 1); + this means that all idx values are already assumed to be + loaded and won't be loaded when they are first requested; + this ensures that the idx values start at whatever value + they would normally start with + */ + for (size_t track_i = 0; track_i < ast.grammar()->axiom->tracks(); ++track_i) { + fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_i_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_i;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_j_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_j;")); + } + fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef _OPENMP")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("unsigned int tile_size = 32;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("tile_size = TILE_SIZE;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_loaded = !load_checkpoint || !outer_loop_1_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_loaded = !load_checkpoint || !outer_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_loaded = !load_checkpoint || !inner_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_start = (outer_loop_1_idx_loaded++) ? 0 : outer_loop_1_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_start = (outer_loop_2_idx_loaded++) ? tile_size : outer_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_start = inner_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); + } + + fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifndef _OPENMP")); + std::list::const_iterator it_stmt_n = (*ast.grammar()->topological_ord().begin())->table_decl->ns().begin(); std::vector::const_iterator it_stmt_seq = ast.seq_decls.begin(); for (size_t track = 0; track < ast.grammar()->axiom->tracks(); ++track, ++it_stmt_n, ++it_stmt_seq) { std::list *stmts_const = new std::list(); std::list *stmts_linear = new std::list(); std::list *stmts_quadratic = new std::list(); + std::list *stmts_checkpoint_outer = new std::list(); + std::list *stmts_checkpoint_inner = new std::list(); // A: quadratic loops Statement::For *loop_quadratic_outer = nullptr; @@ -238,11 +279,40 @@ Fn_Def *print_CYK(const AST &ast) { if ((*it_nt)->is_tabulated()) { if (!(*it_nt)->tables()[track].delete_right_index()) { if (!loop_quadratic_outer) { + Statement::Var_Decl *checkpoint_help_var = nullptr; + if (ast.checkpoint && ast.checkpoint->cyk) { + /* + in checkpointing mode, the loop indices + (e.g. t_0_i and t_0_j in single-track mode; + names can differ in multi-track mode) + are members of the out class instead of local loop variables + so they can be archived/loaded; + if they are loaded, the loop variable (e.g. t_0_j) starts + from whatever value was loaded from the checkpoint, + which is handled through a marker + for every loop variable (e.g. "t_0_j_loaded"); + initially, all of these marker values are set to 0, which will + set each loop variable to whatever value was loaded from the checkpoint; + after that, the respective marker value will be set to 1, + so the loop variable will be set to whatever + value is usually would be set to + */ + checkpoint_help_var = new Statement::Var_Decl( + new ::Type::Size(), + "help_" + *(*it_nt)->right_indices[track]->vacc()->name(), + (*it_nt)->right_indices[track]); + stmts_checkpoint_outer->push_back(checkpoint_help_var); + stmts_checkpoint_outer->push_back( + new Statement::If( + (new Expr::Vacc(new std::string("t_" + std::to_string(track) + "_j_loaded")))->plus(new Expr::Const(1)), + new Statement::Var_Assign(*checkpoint_help_var, (*it_nt)->left_most_indices[track]))); + } + // create outer J loop Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), (*it_nt)->right_indices[track], - (*it_nt)->left_most_indices[track]); + checkpoint_help_var ? new Expr::Vacc(checkpoint_help_var->name) : (*it_nt)->left_most_indices[track]); loopvariable->set_itr(true); Expr::Less *cond = new Expr::Less( (*it_nt)->right_indices[track], @@ -259,10 +329,33 @@ Fn_Def *print_CYK(const AST &ast) { if (!(*it_nt)->tables()[track].delete_right_index() && !(*it_nt)->tables()[track].delete_left_index()) { if (!loop_quadratic_inner) { + Statement::Var_Decl *checkpoint_help_var = nullptr; + if (ast.checkpoint && ast.checkpoint->cyk) { + /* + in checkpointing mode, the inner loop variable (e.g. t_0_i) + is either regularly set to e.g. t_0_j + 1 or to whatever value + was loaded from the checkpoint archive; + however, this loaded checkpoint value will only be the start value + for t_0_i in the first inner loop pass; + afterwards it will regularly be set to t_0_j + 1; + */ + checkpoint_help_var = new Statement::Var_Decl( + new ::Type::Size(), + "help_" + *(*it_nt)->left_indices[track]->vacc()->name(), + (*it_nt)->left_indices[track]); + stmts_checkpoint_inner->push_back(checkpoint_help_var); + //loop_quadratic_outer->statements.push_back(checkpoint_help_var); + //loop_quadratic_outer->push_back( + stmts_checkpoint_inner->push_back( + new Statement::If( + (new Expr::Vacc(new std::string("t_" + std::to_string(track) + "_i_loaded")))->plus(new Expr::Const(1)), + new Statement::Var_Assign(*checkpoint_help_var, (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))))); + } + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), (*it_nt)->left_indices[track], - (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))); + checkpoint_help_var ? new Expr::Vacc(checkpoint_help_var->name) : (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))); loopvariable->set_itr(true); Expr::Greater *cond = new Expr::Greater( (*it_nt)->left_indices[track], @@ -307,7 +400,17 @@ Fn_Def *print_CYK(const AST &ast) { } } + if (ast.checkpoint && ast.checkpoint->cyk) { + Statement::CustomeCode *mutex = new Statement::CustomeCode("std::lock_guard lock(mutex);"); + stmts_quadratic->push_front(mutex); + stmts_linear->push_front(mutex); + stmts_const->push_front(mutex); + } + if (loop_quadratic_outer && loop_quadratic_inner) { + fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_checkpoint_outer->begin(), stmts_checkpoint_outer->end()); + + loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); loop_quadratic_inner->statements = *stmts_quadratic; std::list *loops = new std::list(); loops->push_back(loop_quadratic_outer); @@ -323,6 +426,7 @@ Fn_Def *print_CYK(const AST &ast) { if (loop_linear) { fn_cyk->stmts.push_back(new Statement::CustomeCode("// C: linear loops")); + fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); fn_cyk->stmts.push_back(t_j); loop_linear->statements = *stmts_linear; fn_cyk->stmts.push_back(loop_linear); @@ -333,5 +437,8 @@ Fn_Def *print_CYK(const AST &ast) { fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_const->begin(), stmts_const->end()); } + fn_cyk->stmts.push_back(new Statement::CustomeCode("#else")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); + return fn_cyk; } From e8cb6f7ae62c1ef5a4852ada78f5e60fe7c48cd6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 22:15:27 +0200 Subject: [PATCH 115/189] allow for decrements --- src/cpp.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/cpp.cc b/src/cpp.cc index 1b4136fcc..2aec630bc 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -48,6 +48,7 @@ #include "grammar.hh" #include "options.hh" +#include "outside/codegen.hh" static std::string make_comments(const std::string &s, const std::string &c) { @@ -81,7 +82,11 @@ void Printer::Cpp::print(const Statement::For &stmt) { stream << *stmt.var_decl; stream << ' ' << *stmt.cond << "; "; if (!stmt.inc) { - stream << "++" << *stmt.var_decl->name << ")"; + if (!stmt.decrement) { + stream << "++" << *stmt.var_decl->name << ")"; + } else { + stream << *stmt.var_decl->name << "--" << ")"; + } } else { bool t = in_fn_head; in_fn_head = true; @@ -546,7 +551,10 @@ void Printer::Cpp::print(const Statement::Block &stmt) { } void Printer::Cpp::print(const Statement::CustomeCode &stmt) { - stream << indent() << stmt.line_of_code; + if (stmt.line_of_code.at(0) != '#') { + stream << indent(); + } + stream << stmt.line_of_code; } void Printer::Cpp::print(const std::list &types, @@ -2617,7 +2625,8 @@ void Printer::Cpp::footer(const AST &ast) { stream << indent() << " public:" << endl; inc_indent(); } - print_cyk_fn(ast); + //print_cyk_fn(ast); + stream << *print_CYK(ast) << endl; print_id(); } From 0c1b8567b688ad2b3bdb2b1d85d48f7e725bfdd4 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 22:15:44 +0200 Subject: [PATCH 116/189] also allow -- not only ++ in For --- src/statement.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/statement.hh b/src/statement.hh index 979087c1e..237e44b75 100644 --- a/src/statement.hh +++ b/src/statement.hh @@ -272,6 +272,7 @@ class For : public Block_Base { Var_Decl *var_decl; Expr::Base *cond; Statement::Base *inc; + bool decrement = false; For(Var_Decl *v, Expr::Base* e) : Block_Base(FOR), var_decl(v), cond(e), inc(NULL) { From b9327d1cabaed4d3c7ab000465fee9c887dfde7a Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 22:16:08 +0200 Subject: [PATCH 117/189] CYK should now also produce openMP code --- src/outside/codegen.cc | 249 +++++++++++++++++++++++++++++++---------- 1 file changed, 191 insertions(+), 58 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index b51c8743f..0187c98d5 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -217,48 +217,10 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { stream.in_class = old_in_class; } - -Fn_Def *print_CYK(const AST &ast) { - Fn_Def *fn_cyk = new Fn_Def(new Type::RealVoid(), new std::string("cyk")); - - if (ast.checkpoint && ast.checkpoint->cyk) { - /* - define a boolean marker (as an int) for every loop idx - to allow for the loading of the checkpointed loop indices; - if the user wants to load a checkpoint (load_checkpoint == true) - and the loaded idx value doesn't equal the default value 0 - (meaning that the checkpointed program made enough progress - to get to the loop where the current idx lives), - the markers will be set to "false" (== 0), which indicates - that the respective loop idx hasn't been loaded yet and - should be loaded when it is first requested; - if the user does not want to load a checkpoint - (load_checkpoint == false) or the load idx values are still 0, - the respective markers will be set to "true" (== 1); - this means that all idx values are already assumed to be - loaded and won't be loaded when they are first requested; - this ensures that the idx values start at whatever value - they would normally start with - */ - for (size_t track_i = 0; track_i < ast.grammar()->axiom->tracks(); ++track_i) { - fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_i_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_i;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_j_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_j;")); - } - fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef _OPENMP")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("unsigned int tile_size = 32;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("tile_size = TILE_SIZE;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_loaded = !load_checkpoint || !outer_loop_1_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_loaded = !load_checkpoint || !outer_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_loaded = !load_checkpoint || !inner_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_start = (outer_loop_1_idx_loaded++) ? 0 : outer_loop_1_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_start = (outer_loop_2_idx_loaded++) ? tile_size : outer_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_start = inner_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); - } - - fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifndef _OPENMP")); +std::vector *> *CYK_body(const AST &ast, Expr::Vacc *tile_size, Expr::Vacc *z, Expr::Vacc *var_x, std::string *maxtilen) { + std::list *res_quadratic = new std::list(); + std::list *res_linear = new std::list(); + std::list *res_const = new std::list(); std::list::const_iterator it_stmt_n = (*ast.grammar()->topological_ord().begin())->table_decl->ns().begin(); std::vector::const_iterator it_stmt_seq = ast.seq_decls.begin(); @@ -273,6 +235,7 @@ Fn_Def *print_CYK(const AST &ast) { Statement::For *loop_quadratic_outer = nullptr; Statement::For *loop_quadratic_inner = nullptr; Statement::For *loop_linear = nullptr; + Statement::For *loop_omp_j = nullptr; Statement::Var_Decl *t_i = nullptr; Statement::Var_Decl *t_j = nullptr; for (std::list::const_iterator it_nt = ast.grammar()->topological_ord().begin(); it_nt != ast.grammar()->topological_ord().end(); ++it_nt) { @@ -309,14 +272,21 @@ Fn_Def *print_CYK(const AST &ast) { } // create outer J loop + Expr::Base *init_j = (*it_nt)->left_most_indices[track]; + if (tile_size) { + init_j = z; + } + if (checkpoint_help_var) { + init_j = new Expr::Vacc(checkpoint_help_var->name); + } Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), (*it_nt)->right_indices[track], - checkpoint_help_var ? new Expr::Vacc(checkpoint_help_var->name) : (*it_nt)->left_most_indices[track]); + init_j); loopvariable->set_itr(true); Expr::Less *cond = new Expr::Less( (*it_nt)->right_indices[track], - (*it_nt)->right_most_indices[track]); + tile_size ? z->plus(tile_size) : (*it_nt)->right_most_indices[track]); loop_quadratic_outer = new Statement::For(loopvariable, cond); loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// A: quadratic loops")); @@ -352,14 +322,28 @@ Fn_Def *print_CYK(const AST &ast) { new Statement::Var_Assign(*checkpoint_help_var, (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))))); } + Expr::Base *init_i = (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1)); + if (tile_size && var_x) { + init_i = var_x; + } + if (checkpoint_help_var) { + init_i = new Expr::Vacc(checkpoint_help_var->name); + } Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), (*it_nt)->left_indices[track], - checkpoint_help_var ? new Expr::Vacc(checkpoint_help_var->name) : (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))); + init_i); loopvariable->set_itr(true); + Expr::Base *greater = new Expr::Const(1); + if (tile_size) { + greater = z; + if (var_x) { + greater = var_x->minus(tile_size); + } + } Expr::Greater *cond = new Expr::Greater( (*it_nt)->left_indices[track], - new Expr::Const(1)); + greater); loop_quadratic_inner = new Statement::For(loopvariable, cond); loop_quadratic_inner->decrement = true; @@ -371,6 +355,18 @@ Fn_Def *print_CYK(const AST &ast) { } } + if (loop_omp_j == nullptr) { + Statement::Var_Decl *loopvar_j = new Statement::Var_Decl( + new ::Type::Size(), + (*it_nt)->right_indices[track], + new Expr::Vacc(maxtilen)); + loopvar_j->set_itr(true); + Expr::Less_Eq *cond = new Expr::Less_Eq( + (*it_nt)->right_indices[track], + (*it_nt)->right_most_indices[track]); + loop_omp_j = new Statement::For(loopvar_j, cond); + } + // produce: nt_tabulate_iloop(t_0_i-1, t_0_j); std::list *args = new std::list(); // t_0_i - 1 @@ -408,7 +404,7 @@ Fn_Def *print_CYK(const AST &ast) { } if (loop_quadratic_outer && loop_quadratic_inner) { - fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_checkpoint_outer->begin(), stmts_checkpoint_outer->end()); + res_quadratic->insert(res_quadratic->end(), stmts_checkpoint_outer->begin(), stmts_checkpoint_outer->end()); loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); loop_quadratic_inner->statements = *stmts_quadratic; @@ -417,27 +413,164 @@ Fn_Def *print_CYK(const AST &ast) { loops->push_back(loop_quadratic_inner); nest_for_loops(loops->begin(), loops->end()); - loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// B: inner quadratic loops")); - loop_quadratic_outer->statements.push_back(t_i); - loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_quadratic->begin(), stmts_quadratic->end()); + if (!tile_size) { + loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// B: inner quadratic loops")); + loop_quadratic_outer->statements.push_back(t_i); + loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_quadratic->begin(), stmts_quadratic->end()); + } - fn_cyk->stmts.push_back(*loops->begin()); + res_quadratic->push_back(*loops->begin()); } if (loop_linear) { - fn_cyk->stmts.push_back(new Statement::CustomeCode("// C: linear loops")); - fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); - fn_cyk->stmts.push_back(t_j); loop_linear->statements = *stmts_linear; - fn_cyk->stmts.push_back(loop_linear); + if (!maxtilen) { + res_linear->push_back(new Statement::CustomeCode("// C: linear loops")); + res_linear->insert(res_linear->end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); + res_linear->push_back(t_j); + res_linear->push_back(loop_linear); + } else { + loop_omp_j->statements.push_back(loop_linear); + res_linear->push_back(loop_omp_j); + } } - fn_cyk->stmts.push_back(new Statement::CustomeCode("// D: constant loops")); - fn_cyk->stmts.push_back(t_i); - fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts_const->begin(), stmts_const->end()); + res_const->push_back(new Statement::CustomeCode("// D: constant loops")); + res_const->push_back(t_i); + res_const->insert(res_const->end(), stmts_const->begin(), stmts_const->end()); + } + + std::vector *> *res = new std::vector *>(); + res->push_back(res_quadratic); + res->push_back(res_linear); + res->push_back(res_const); + + return res; +} + +std::list *get_tile_computation(const AST &ast, size_t track, Statement::Var_Decl *tile_size, std::string *name_maxtilen) { + std::list *res = new std::list(); + + + res->push_back(tile_size); + res->push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); + res->push_back(new Statement::Var_Assign(*tile_size, new Expr::Const("TILE_SIZE"))); + res->push_back(new Statement::CustomeCode("#endif")); + res->push_back(new Statement::Fn_Call(Statement::Fn_Call::ASSERT, *tile_size)); + Statement::Var_Decl *max_tiles = new Statement::Var_Decl( + new Type::Size(), + "max_tiles", + new Expr::Div(ast.grammar()->axiom->right_indices[track]->vacc(), new Expr::Vacc(*tile_size))); + res->push_back(max_tiles); + Statement::Var_Decl *max_tiles_n = new Statement::Var_Decl( + new Type::Int(), + *name_maxtilen, + new Expr::Times(new Expr::Vacc(*max_tiles), new Expr::Vacc(*tile_size))); + res->push_back(max_tiles_n); + + return res; +} + +Fn_Def *print_CYK(const AST &ast) { + Fn_Def *fn_cyk = new Fn_Def(new Type::RealVoid(), new std::string("cyk")); + + if (ast.checkpoint && ast.checkpoint->cyk) { + /* + define a boolean marker (as an int) for every loop idx + to allow for the loading of the checkpointed loop indices; + if the user wants to load a checkpoint (load_checkpoint == true) + and the loaded idx value doesn't equal the default value 0 + (meaning that the checkpointed program made enough progress + to get to the loop where the current idx lives), + the markers will be set to "false" (== 0), which indicates + that the respective loop idx hasn't been loaded yet and + should be loaded when it is first requested; + if the user does not want to load a checkpoint + (load_checkpoint == false) or the load idx values are still 0, + the respective markers will be set to "true" (== 1); + this means that all idx values are already assumed to be + loaded and won't be loaded when they are first requested; + this ensures that the idx values start at whatever value + they would normally start with + */ + for (size_t track_i = 0; track_i < ast.grammar()->axiom->tracks(); ++track_i) { + fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_i_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_i;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_j_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_j;")); + } + fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef _OPENMP")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("unsigned int tile_size = 32;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("tile_size = TILE_SIZE;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_loaded = !load_checkpoint || !outer_loop_1_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_loaded = !load_checkpoint || !outer_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_loaded = !load_checkpoint || !inner_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_start = (outer_loop_1_idx_loaded++) ? 0 : outer_loop_1_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_start = (outer_loop_2_idx_loaded++) ? tile_size : outer_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_start = inner_loop_2_idx;")); + fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); + } + + fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifndef _OPENMP")); + + std::vector *> *body = CYK_body(ast, nullptr, nullptr, nullptr, nullptr); + for (std::vector *>::const_iterator it_s = body->begin(); it_s != body->end(); ++it_s) { + fn_cyk->stmts.insert(fn_cyk->stmts.end(), (*it_s)->begin(), (*it_s)->end()); } fn_cyk->stmts.push_back(new Statement::CustomeCode("#else")); + // FIXME abstract from unsigned int, int -> perhaps wait for OpenMP 3 + // since OpenMP < 3 doesn't allow unsigned int in workshared fors + fn_cyk->stmts.push_back(new Statement::CustomeCode("#pragma omp parallel")); + Statement::Block *blk_omp = new Statement::Block(); + // FIXME adjust for multi-track (> 1 track) + unsigned int track = 0; + Statement::Var_Decl *tile_size = new Statement::Var_Decl( + new Type::Size(), + "tile_size", + new Expr::Const(32)); + std::string *maxtilen = new std::string("max_tiles_n"); + std::list *stmts_tile = get_tile_computation(ast, track, tile_size, maxtilen); + blk_omp->statements.insert(blk_omp->statements.end(), stmts_tile->begin(), stmts_tile->end()); + blk_omp->push_back(new Statement::CustomeCode("#pragma omp for")); + blk_omp->push_back(new Statement::CustomeCode("// OPENMP < 3 requires signed int here ...")); + + // for loops + Expr::Vacc *var_z = new Expr::Vacc(new std::string("z")); + body = CYK_body(ast, new Expr::Vacc(*tile_size), var_z, nullptr, nullptr); + + // this loop was too complicated to be realized via proper Statements + blk_omp->push_back(new Statement::CustomeCode("for (int z = 0; z < max_tiles_n; z+=tile_size)")); + Statement::Block *blk_loop_tile = new Statement::Block(); + blk_loop_tile->statements.insert(blk_loop_tile->statements.end(), body->at(0)->begin(), body->at(0)->end()); + blk_omp->push_back(blk_loop_tile); + + blk_omp->push_back(new Statement::CustomeCode("for (int z = tile_size; z < max_tiles_n; z+=tile_size)")); + Statement::Block *blk_loop_tile2_outer = new Statement::Block(); + blk_loop_tile2_outer->statements.push_back(new Statement::CustomeCode("#pragma omp for")); + blk_loop_tile2_outer->statements.push_back(new Statement::CustomeCode("for (int y = z; y < max_tiles_n; y+=tile_size)")); + Statement::Block *blk_loop_tile2_inner = new Statement::Block(); + Expr::Vacc *var_y = new Expr::Vacc(new std::string("y")); + Statement::Var_Decl *var_x = new Statement::Var_Decl( + new Type::Size(), + "x", + var_y->minus(var_z)->plus(new Expr::Vacc(*tile_size))); + blk_loop_tile2_inner->statements.push_back(var_x); + body = CYK_body(ast, new Expr::Vacc(*tile_size), var_y, new Expr::Vacc(*var_x), nullptr); + blk_loop_tile2_inner->statements.insert(blk_loop_tile2_inner->statements.end(), body->at(0)->begin(), body->at(0)->end()); + blk_loop_tile2_outer->statements.push_back(blk_loop_tile2_inner); + blk_omp->push_back(blk_loop_tile2_outer); + + blk_omp->push_back(new Statement::CustomeCode("// end parallel")); + + blk_omp->statements.insert(blk_omp->statements.end(), stmts_tile->begin(), stmts_tile->end()); + body = CYK_body(ast, nullptr, nullptr, nullptr, maxtilen); + + blk_omp->statements.insert(blk_omp->statements.end(), body->at(1)->begin(), body->at(1)->end()); + + + fn_cyk->stmts.push_back(blk_omp); + //fn_cyk->stmts.push_back(new Statement::CustomeCode("} // end parallel")); fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); return fn_cyk; From 8f333f2c35e27b2fb46f2eb29c5f728968f528ef Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 5 May 2023 23:10:33 +0200 Subject: [PATCH 118/189] reduce to only 5 randomly selected NTs to keep truth file small --- testdata/regresstest/config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index 99c022827..8586f6881 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -527,8 +527,11 @@ check_new_old_eq nonzero_constsize.gap unused count "G" outside_constissue check_new_old_eq constAxiom.gap unused enum "G" outside_out2in # check TMHMM outside with real sequence which previously revealed < 1.0 prob sums +# to not exceed file size of truth, just report 5 random NTs CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA +GAPC="../../../gapc --outside_grammar state_in21 --outside_grammar state_ihelixi7 --outside_grammar state_ihelix5 --outside_grammar state_in13 --outside_grammar state_outglob14 " check_new_old_eq tmhmm.gap unused fwd_scaled "MENLNMDLLYMAAAVMMGLAAIGAAIGIGILGGKFLEGAARQPDLIPLLRTQFFIVMGLVDAIPMIAVGLGLYVMFAVA" outside_tmhmm +GAPC="../../../gapc --outside_grammar ALL" check_new_old_eq RFmini.gap unused enum "G" outside_cm check_new_old_eq RFmini.gap unused count "G" outside_cm From 59d436d2e2bb171c153b9bf8df51e32c44184c93 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 9 May 2023 12:42:37 +0200 Subject: [PATCH 119/189] add checkpointing --- src/outside/codegen.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 0187c98d5..1b4f11b66 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -452,10 +452,12 @@ std::list *get_tile_computation(const AST &ast, size_t track, std::list *res = new std::list(); - res->push_back(tile_size); - res->push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); - res->push_back(new Statement::Var_Assign(*tile_size, new Expr::Const("TILE_SIZE"))); - res->push_back(new Statement::CustomeCode("#endif")); + if (!(ast.checkpoint && ast.checkpoint->cyk)) { + res->push_back(tile_size); + res->push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); + res->push_back(new Statement::Var_Assign(*tile_size, new Expr::Const("TILE_SIZE"))); + res->push_back(new Statement::CustomeCode("#endif")); + } res->push_back(new Statement::Fn_Call(Statement::Fn_Call::ASSERT, *tile_size)); Statement::Var_Decl *max_tiles = new Statement::Var_Decl( new Type::Size(), @@ -532,7 +534,11 @@ Fn_Def *print_CYK(const AST &ast) { std::string *maxtilen = new std::string("max_tiles_n"); std::list *stmts_tile = get_tile_computation(ast, track, tile_size, maxtilen); blk_omp->statements.insert(blk_omp->statements.end(), stmts_tile->begin(), stmts_tile->end()); - blk_omp->push_back(new Statement::CustomeCode("#pragma omp for")); + if (ast.checkpoint && ast.checkpoint->cyk) { + blk_omp->push_back(new Statement::CustomeCode("#pragma omp for ordered schedule(dynamic)")); + } else { + blk_omp->push_back(new Statement::CustomeCode("#pragma omp for")); + } blk_omp->push_back(new Statement::CustomeCode("// OPENMP < 3 requires signed int here ...")); // for loops @@ -540,8 +546,15 @@ Fn_Def *print_CYK(const AST &ast) { body = CYK_body(ast, new Expr::Vacc(*tile_size), var_z, nullptr, nullptr); // this loop was too complicated to be realized via proper Statements - blk_omp->push_back(new Statement::CustomeCode("for (int z = 0; z < max_tiles_n; z+=tile_size)")); + if (ast.checkpoint && ast.checkpoint->cyk) { + blk_omp->push_back(new Statement::CustomeCode("for (int z = outer_loop_1_idx_start; z < max_tiles_n; z+=tile_size)")); + } else { + blk_omp->push_back(new Statement::CustomeCode("for (int z = 0; z < max_tiles_n; z+=tile_size)")); + } Statement::Block *blk_loop_tile = new Statement::Block(); + if (ast.checkpoint && ast.checkpoint->cyk) { + blk_loop_tile->statements.push_back(new Statement::CustomeCode("mutex.lock_shared()")); + } blk_loop_tile->statements.insert(blk_loop_tile->statements.end(), body->at(0)->begin(), body->at(0)->end()); blk_omp->push_back(blk_loop_tile); From 1959555e1dc7fd279ac94f359d8e423b471a86f8 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 17 May 2023 11:04:00 +0200 Subject: [PATCH 120/189] avoid duplicate definition --- src/statement.hh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/statement.hh b/src/statement.hh index efe17d8b5..a4b0eb6a7 100644 --- a/src/statement.hh +++ b/src/statement.hh @@ -363,19 +363,6 @@ class Block : public Block_Base { Base *copy() const; }; -class CustomeCode : public Base { - /* A "CustomeCode" statement is an arbitrary line of string that get's - * injected. Handy to leave comments in the generated code or inject - * constructs otherwise impossible. Use with care! */ - public: - std::string line_of_code; - - explicit CustomeCode(std::string line_of_code) : - Base(CUSTOMECODE), line_of_code(line_of_code) { - } - - void print(Printer::Base &p) const; -}; class CustomeCode : public Base { /* A "CustomeCode" statement is an arbitrary line of string that get's From cfb3552eb8b788d2bc3d4811e561b00e7df78fc6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 17 May 2023 14:37:11 +0200 Subject: [PATCH 121/189] remove CYK old fashioned stub --- src/cpp.cc | 3 +- src/outside/codegen.cc | 371 ----------------------------------------- src/outside/codegen.hh | 1 - 3 files changed, 1 insertion(+), 374 deletions(-) diff --git a/src/cpp.cc b/src/cpp.cc index 2aec630bc..1d5a67f9e 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -2625,8 +2625,7 @@ void Printer::Cpp::footer(const AST &ast) { stream << indent() << " public:" << endl; inc_indent(); } - //print_cyk_fn(ast); - stream << *print_CYK(ast) << endl; + print_cyk_fn(ast); print_id(); } diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 1b4f11b66..7c96c6d88 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -217,374 +217,3 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { stream.in_class = old_in_class; } -std::vector *> *CYK_body(const AST &ast, Expr::Vacc *tile_size, Expr::Vacc *z, Expr::Vacc *var_x, std::string *maxtilen) { - std::list *res_quadratic = new std::list(); - std::list *res_linear = new std::list(); - std::list *res_const = new std::list(); - - std::list::const_iterator it_stmt_n = (*ast.grammar()->topological_ord().begin())->table_decl->ns().begin(); - std::vector::const_iterator it_stmt_seq = ast.seq_decls.begin(); - for (size_t track = 0; track < ast.grammar()->axiom->tracks(); ++track, ++it_stmt_n, ++it_stmt_seq) { - std::list *stmts_const = new std::list(); - std::list *stmts_linear = new std::list(); - std::list *stmts_quadratic = new std::list(); - std::list *stmts_checkpoint_outer = new std::list(); - std::list *stmts_checkpoint_inner = new std::list(); - - // A: quadratic loops - Statement::For *loop_quadratic_outer = nullptr; - Statement::For *loop_quadratic_inner = nullptr; - Statement::For *loop_linear = nullptr; - Statement::For *loop_omp_j = nullptr; - Statement::Var_Decl *t_i = nullptr; - Statement::Var_Decl *t_j = nullptr; - for (std::list::const_iterator it_nt = ast.grammar()->topological_ord().begin(); it_nt != ast.grammar()->topological_ord().end(); ++it_nt) { - if ((*it_nt)->is_tabulated()) { - if (!(*it_nt)->tables()[track].delete_right_index()) { - if (!loop_quadratic_outer) { - Statement::Var_Decl *checkpoint_help_var = nullptr; - if (ast.checkpoint && ast.checkpoint->cyk) { - /* - in checkpointing mode, the loop indices - (e.g. t_0_i and t_0_j in single-track mode; - names can differ in multi-track mode) - are members of the out class instead of local loop variables - so they can be archived/loaded; - if they are loaded, the loop variable (e.g. t_0_j) starts - from whatever value was loaded from the checkpoint, - which is handled through a marker - for every loop variable (e.g. "t_0_j_loaded"); - initially, all of these marker values are set to 0, which will - set each loop variable to whatever value was loaded from the checkpoint; - after that, the respective marker value will be set to 1, - so the loop variable will be set to whatever - value is usually would be set to - */ - checkpoint_help_var = new Statement::Var_Decl( - new ::Type::Size(), - "help_" + *(*it_nt)->right_indices[track]->vacc()->name(), - (*it_nt)->right_indices[track]); - stmts_checkpoint_outer->push_back(checkpoint_help_var); - stmts_checkpoint_outer->push_back( - new Statement::If( - (new Expr::Vacc(new std::string("t_" + std::to_string(track) + "_j_loaded")))->plus(new Expr::Const(1)), - new Statement::Var_Assign(*checkpoint_help_var, (*it_nt)->left_most_indices[track]))); - } - - // create outer J loop - Expr::Base *init_j = (*it_nt)->left_most_indices[track]; - if (tile_size) { - init_j = z; - } - if (checkpoint_help_var) { - init_j = new Expr::Vacc(checkpoint_help_var->name); - } - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), - (*it_nt)->right_indices[track], - init_j); - loopvariable->set_itr(true); - Expr::Less *cond = new Expr::Less( - (*it_nt)->right_indices[track], - tile_size ? z->plus(tile_size) : (*it_nt)->right_most_indices[track]); - loop_quadratic_outer = new Statement::For(loopvariable, cond); - loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// A: quadratic loops")); - - t_j = (*loopvariable).clone(); - t_j->rhs = (*it_nt)->right_most_indices[track]; - t_j->set_itr(false); - } - } - - if (!(*it_nt)->tables()[track].delete_right_index() && - !(*it_nt)->tables()[track].delete_left_index()) { - if (!loop_quadratic_inner) { - Statement::Var_Decl *checkpoint_help_var = nullptr; - if (ast.checkpoint && ast.checkpoint->cyk) { - /* - in checkpointing mode, the inner loop variable (e.g. t_0_i) - is either regularly set to e.g. t_0_j + 1 or to whatever value - was loaded from the checkpoint archive; - however, this loaded checkpoint value will only be the start value - for t_0_i in the first inner loop pass; - afterwards it will regularly be set to t_0_j + 1; - */ - checkpoint_help_var = new Statement::Var_Decl( - new ::Type::Size(), - "help_" + *(*it_nt)->left_indices[track]->vacc()->name(), - (*it_nt)->left_indices[track]); - stmts_checkpoint_inner->push_back(checkpoint_help_var); - //loop_quadratic_outer->statements.push_back(checkpoint_help_var); - //loop_quadratic_outer->push_back( - stmts_checkpoint_inner->push_back( - new Statement::If( - (new Expr::Vacc(new std::string("t_" + std::to_string(track) + "_i_loaded")))->plus(new Expr::Const(1)), - new Statement::Var_Assign(*checkpoint_help_var, (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1))))); - } - - Expr::Base *init_i = (*(*it_nt)->right_indices[track]).plus(new Expr::Const(1)); - if (tile_size && var_x) { - init_i = var_x; - } - if (checkpoint_help_var) { - init_i = new Expr::Vacc(checkpoint_help_var->name); - } - Statement::Var_Decl *loopvariable = new Statement::Var_Decl( - new ::Type::Size(), - (*it_nt)->left_indices[track], - init_i); - loopvariable->set_itr(true); - Expr::Base *greater = new Expr::Const(1); - if (tile_size) { - greater = z; - if (var_x) { - greater = var_x->minus(tile_size); - } - } - Expr::Greater *cond = new Expr::Greater( - (*it_nt)->left_indices[track], - greater); - loop_quadratic_inner = new Statement::For(loopvariable, cond); - loop_quadratic_inner->decrement = true; - - loop_linear = dynamic_cast(loop_quadratic_inner->copy()); - - t_i = (*loopvariable).clone(); - t_i->rhs = new Expr::Const(1); - t_i->set_itr(false); - } - } - - if (loop_omp_j == nullptr) { - Statement::Var_Decl *loopvar_j = new Statement::Var_Decl( - new ::Type::Size(), - (*it_nt)->right_indices[track], - new Expr::Vacc(maxtilen)); - loopvar_j->set_itr(true); - Expr::Less_Eq *cond = new Expr::Less_Eq( - (*it_nt)->right_indices[track], - (*it_nt)->right_most_indices[track]); - loop_omp_j = new Statement::For(loopvar_j, cond); - } - - // produce: nt_tabulate_iloop(t_0_i-1, t_0_j); - std::list *args = new std::list(); - // t_0_i - 1 - Statement::Var_Decl *idx_i = (*loop_quadratic_inner->var_decl).clone(); - idx_i->set_itr(false); - if (!(*it_nt)->tables()[track].delete_left_index()) { - args->push_back((new Expr::Vacc(*idx_i))->minus(new Expr::Const(1))); - } - // t_0_j - Statement::Var_Decl *idx_j = (*loop_quadratic_outer->var_decl).clone(); - idx_j->set_itr(false); - if (!(*it_nt)->tables()[track].delete_right_index()) { - args->push_back(new Expr::Vacc(*idx_j)); - } - Statement::Fn_Call *nt_call = new Statement::Fn_Call((*(*it_nt)->code_list().rbegin())->name, args, Loc()); - //stmts->push_back(nt_call); - - if (!(*it_nt)->tables()[track].delete_right_index() && - !(*it_nt)->tables()[track].delete_left_index()) { - stmts_quadratic->push_back(nt_call); - } - if (!(*it_nt)->tables()[track].delete_right_index() || - !(*it_nt)->tables()[track].delete_left_index()) { - stmts_linear->push_back(nt_call); - } - stmts_const->push_back(nt_call); - } - } - - if (ast.checkpoint && ast.checkpoint->cyk) { - Statement::CustomeCode *mutex = new Statement::CustomeCode("std::lock_guard lock(mutex);"); - stmts_quadratic->push_front(mutex); - stmts_linear->push_front(mutex); - stmts_const->push_front(mutex); - } - - if (loop_quadratic_outer && loop_quadratic_inner) { - res_quadratic->insert(res_quadratic->end(), stmts_checkpoint_outer->begin(), stmts_checkpoint_outer->end()); - - loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); - loop_quadratic_inner->statements = *stmts_quadratic; - std::list *loops = new std::list(); - loops->push_back(loop_quadratic_outer); - loops->push_back(loop_quadratic_inner); - nest_for_loops(loops->begin(), loops->end()); - - if (!tile_size) { - loop_quadratic_outer->statements.push_back(new Statement::CustomeCode("// B: inner quadratic loops")); - loop_quadratic_outer->statements.push_back(t_i); - loop_quadratic_outer->statements.insert(loop_quadratic_outer->statements.end(), stmts_quadratic->begin(), stmts_quadratic->end()); - } - - res_quadratic->push_back(*loops->begin()); - } - - if (loop_linear) { - loop_linear->statements = *stmts_linear; - if (!maxtilen) { - res_linear->push_back(new Statement::CustomeCode("// C: linear loops")); - res_linear->insert(res_linear->end(), stmts_checkpoint_inner->begin(), stmts_checkpoint_inner->end()); - res_linear->push_back(t_j); - res_linear->push_back(loop_linear); - } else { - loop_omp_j->statements.push_back(loop_linear); - res_linear->push_back(loop_omp_j); - } - } - - res_const->push_back(new Statement::CustomeCode("// D: constant loops")); - res_const->push_back(t_i); - res_const->insert(res_const->end(), stmts_const->begin(), stmts_const->end()); - } - - std::vector *> *res = new std::vector *>(); - res->push_back(res_quadratic); - res->push_back(res_linear); - res->push_back(res_const); - - return res; -} - -std::list *get_tile_computation(const AST &ast, size_t track, Statement::Var_Decl *tile_size, std::string *name_maxtilen) { - std::list *res = new std::list(); - - - if (!(ast.checkpoint && ast.checkpoint->cyk)) { - res->push_back(tile_size); - res->push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); - res->push_back(new Statement::Var_Assign(*tile_size, new Expr::Const("TILE_SIZE"))); - res->push_back(new Statement::CustomeCode("#endif")); - } - res->push_back(new Statement::Fn_Call(Statement::Fn_Call::ASSERT, *tile_size)); - Statement::Var_Decl *max_tiles = new Statement::Var_Decl( - new Type::Size(), - "max_tiles", - new Expr::Div(ast.grammar()->axiom->right_indices[track]->vacc(), new Expr::Vacc(*tile_size))); - res->push_back(max_tiles); - Statement::Var_Decl *max_tiles_n = new Statement::Var_Decl( - new Type::Int(), - *name_maxtilen, - new Expr::Times(new Expr::Vacc(*max_tiles), new Expr::Vacc(*tile_size))); - res->push_back(max_tiles_n); - - return res; -} - -Fn_Def *print_CYK(const AST &ast) { - Fn_Def *fn_cyk = new Fn_Def(new Type::RealVoid(), new std::string("cyk")); - - if (ast.checkpoint && ast.checkpoint->cyk) { - /* - define a boolean marker (as an int) for every loop idx - to allow for the loading of the checkpointed loop indices; - if the user wants to load a checkpoint (load_checkpoint == true) - and the loaded idx value doesn't equal the default value 0 - (meaning that the checkpointed program made enough progress - to get to the loop where the current idx lives), - the markers will be set to "false" (== 0), which indicates - that the respective loop idx hasn't been loaded yet and - should be loaded when it is first requested; - if the user does not want to load a checkpoint - (load_checkpoint == false) or the load idx values are still 0, - the respective markers will be set to "true" (== 1); - this means that all idx values are already assumed to be - loaded and won't be loaded when they are first requested; - this ensures that the idx values start at whatever value - they would normally start with - */ - for (size_t track_i = 0; track_i < ast.grammar()->axiom->tracks(); ++track_i) { - fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_i_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_i;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int t_" + std::to_string(track_i) + "_j_loaded = !load_checkpoint || !t_" + std::to_string(track_i) + "_j;")); - } - fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef _OPENMP")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("unsigned int tile_size = 32;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifdef TILE_SIZE")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("tile_size = TILE_SIZE;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_loaded = !load_checkpoint || !outer_loop_1_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_loaded = !load_checkpoint || !outer_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_loaded = !load_checkpoint || !inner_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_1_idx_start = (outer_loop_1_idx_loaded++) ? 0 : outer_loop_1_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int outer_loop_2_idx_start = (outer_loop_2_idx_loaded++) ? tile_size : outer_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("int inner_loop_2_idx_start = inner_loop_2_idx;")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); - } - - fn_cyk->stmts.push_back(new Statement::CustomeCode("#ifndef _OPENMP")); - - std::vector *> *body = CYK_body(ast, nullptr, nullptr, nullptr, nullptr); - for (std::vector *>::const_iterator it_s = body->begin(); it_s != body->end(); ++it_s) { - fn_cyk->stmts.insert(fn_cyk->stmts.end(), (*it_s)->begin(), (*it_s)->end()); - } - - fn_cyk->stmts.push_back(new Statement::CustomeCode("#else")); - // FIXME abstract from unsigned int, int -> perhaps wait for OpenMP 3 - // since OpenMP < 3 doesn't allow unsigned int in workshared fors - fn_cyk->stmts.push_back(new Statement::CustomeCode("#pragma omp parallel")); - Statement::Block *blk_omp = new Statement::Block(); - // FIXME adjust for multi-track (> 1 track) - unsigned int track = 0; - Statement::Var_Decl *tile_size = new Statement::Var_Decl( - new Type::Size(), - "tile_size", - new Expr::Const(32)); - std::string *maxtilen = new std::string("max_tiles_n"); - std::list *stmts_tile = get_tile_computation(ast, track, tile_size, maxtilen); - blk_omp->statements.insert(blk_omp->statements.end(), stmts_tile->begin(), stmts_tile->end()); - if (ast.checkpoint && ast.checkpoint->cyk) { - blk_omp->push_back(new Statement::CustomeCode("#pragma omp for ordered schedule(dynamic)")); - } else { - blk_omp->push_back(new Statement::CustomeCode("#pragma omp for")); - } - blk_omp->push_back(new Statement::CustomeCode("// OPENMP < 3 requires signed int here ...")); - - // for loops - Expr::Vacc *var_z = new Expr::Vacc(new std::string("z")); - body = CYK_body(ast, new Expr::Vacc(*tile_size), var_z, nullptr, nullptr); - - // this loop was too complicated to be realized via proper Statements - if (ast.checkpoint && ast.checkpoint->cyk) { - blk_omp->push_back(new Statement::CustomeCode("for (int z = outer_loop_1_idx_start; z < max_tiles_n; z+=tile_size)")); - } else { - blk_omp->push_back(new Statement::CustomeCode("for (int z = 0; z < max_tiles_n; z+=tile_size)")); - } - Statement::Block *blk_loop_tile = new Statement::Block(); - if (ast.checkpoint && ast.checkpoint->cyk) { - blk_loop_tile->statements.push_back(new Statement::CustomeCode("mutex.lock_shared()")); - } - blk_loop_tile->statements.insert(blk_loop_tile->statements.end(), body->at(0)->begin(), body->at(0)->end()); - blk_omp->push_back(blk_loop_tile); - - blk_omp->push_back(new Statement::CustomeCode("for (int z = tile_size; z < max_tiles_n; z+=tile_size)")); - Statement::Block *blk_loop_tile2_outer = new Statement::Block(); - blk_loop_tile2_outer->statements.push_back(new Statement::CustomeCode("#pragma omp for")); - blk_loop_tile2_outer->statements.push_back(new Statement::CustomeCode("for (int y = z; y < max_tiles_n; y+=tile_size)")); - Statement::Block *blk_loop_tile2_inner = new Statement::Block(); - Expr::Vacc *var_y = new Expr::Vacc(new std::string("y")); - Statement::Var_Decl *var_x = new Statement::Var_Decl( - new Type::Size(), - "x", - var_y->minus(var_z)->plus(new Expr::Vacc(*tile_size))); - blk_loop_tile2_inner->statements.push_back(var_x); - body = CYK_body(ast, new Expr::Vacc(*tile_size), var_y, new Expr::Vacc(*var_x), nullptr); - blk_loop_tile2_inner->statements.insert(blk_loop_tile2_inner->statements.end(), body->at(0)->begin(), body->at(0)->end()); - blk_loop_tile2_outer->statements.push_back(blk_loop_tile2_inner); - blk_omp->push_back(blk_loop_tile2_outer); - - blk_omp->push_back(new Statement::CustomeCode("// end parallel")); - - blk_omp->statements.insert(blk_omp->statements.end(), stmts_tile->begin(), stmts_tile->end()); - body = CYK_body(ast, nullptr, nullptr, nullptr, maxtilen); - - blk_omp->statements.insert(blk_omp->statements.end(), body->at(1)->begin(), body->at(1)->end()); - - - fn_cyk->stmts.push_back(blk_omp); - //fn_cyk->stmts.push_back(new Statement::CustomeCode("} // end parallel")); - fn_cyk->stmts.push_back(new Statement::CustomeCode("#endif")); - - return fn_cyk; -} diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh index 68621d26a..a497fb348 100644 --- a/src/outside/codegen.hh +++ b/src/outside/codegen.hh @@ -38,6 +38,5 @@ #include "grammar_transformation.hh" void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast); -Fn_Def *print_CYK(const AST &ast); #endif // SRC_OUTSIDE_CODEGEN_HH_ From 8e045dca9bf1ec22dc2bca86a76a48a707eee33f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 17 May 2023 14:47:15 +0200 Subject: [PATCH 122/189] merge --- src/cpp.cc | 7 - src/cyk.cc | 103 +++-- src/outside/codegen.cc | 4 +- src/outside/codegen.hh | 1 + src/statement.hh | 2 +- src/statement/base.hh | 6 +- testdata/grammar2/alignments_cyk.gap | 2 +- testdata/regresstest/config | 552 --------------------------- 8 files changed, 82 insertions(+), 595 deletions(-) diff --git a/src/cpp.cc b/src/cpp.cc index f38d0e669..2852036ba 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -555,13 +555,6 @@ void Printer::Cpp::print(const Statement::Block &stmt) { stream << indent() << "}" << endl; } -void Printer::Cpp::print(const Statement::CustomeCode &stmt) { - if (stmt.line_of_code.at(0) != '#') { - stream << indent(); - } - stream << stmt.line_of_code; -} - void Printer::Cpp::print(const Statement::CustomCode &stmt) { if (stmt.line_of_code.at(0) != '#') { stream << indent(); diff --git a/src/cyk.cc b/src/cyk.cc index 90225f0fd..1c3a8f47e 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -106,10 +106,10 @@ class CYKloop { } }; -enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL}; +enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL, SINGLETHREAD_OUTSIDE}; CYKloop get_for_column(Expr::Vacc *running_boundary, - Statement::Var_Decl *input_seq, Expr::Base *start, Expr::Base *end, + Expr::Base *start, Expr::Base *end, bool with_checkpoint, CYKmode mode) { // create loop variable addressing the DP column (=2nd index) // e.g.: for (unsigned int t_0_j = 0; t_0_j < t_0_seq.size(); ++t_0_j) { @@ -128,13 +128,6 @@ CYKloop get_for_column(Expr::Vacc *running_boundary, running_boundary, start); - // create end point for loop variable - if (mode != CYKmode::OPENMP_PARALLEL) { - end = new Expr::Fn_Call(new std::string("size")); - dynamic_cast(end)->add_arg(input_seq->name); - dynamic_cast(end)->is_obj = Bool(true); - } - // create condition of For loop Expr::Less *cond_col = new Expr::Less( new Expr::Vacc(*var_col), end); @@ -169,13 +162,20 @@ CYKloop get_for_row(Expr::Vacc *running_boundary, Expr::Base *start, start); // create condition of For loop - Expr::Greater *cond_row = new Expr::Greater(new Expr::Vacc(*var_row), end); + Expr::Two *cond_row = new Expr::Greater(new Expr::Vacc(*var_row), end); + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + cond_row = new Expr::Less(new Expr::Vacc(*var_row), end); + } Statement::For *loop = new Statement::For(var_row, cond_row); - Statement::Var_Assign *x = new Statement::Var_Assign( - *var_row, new Expr::Const(new Const::Int(-1))); - x->set_op(::Expr::Type::PLUS); - loop->inc = x; + // except for outside, we need to decrement the loop variable, i.e. t_x_i-- + // In outside, it must be ++t_x_i + if (mode != CYKmode::SINGLETHREAD_OUTSIDE) { + Statement::Var_Assign *x = new Statement::Var_Assign( + *var_row, new Expr::Const(new Const::Int(-1))); + x->set_op(::Expr::Type::PLUS); + loop->inc = x; + } Statement::Var_Decl *var_nonloop = var_row->clone(); var_nonloop->rhs = new Expr::Const(1); @@ -239,6 +239,10 @@ std::list *cyk_traversal_singlethread_singletrack( Expr::Base *row_start = ast.grammar()->right_running_indices.at( track)->plus(new Expr::Const(1)); + // create t_X_seq.size() call + Expr::Fn_Call *seqend = new Expr::Fn_Call(new std::string("size")); + dynamic_cast(seqend)->add_arg(seq->name); + dynamic_cast(seqend)->is_obj = Bool(true); // A: major cells in triangle below first row, left of last columns // A: t_x_i = row index @@ -254,7 +258,7 @@ std::list *cyk_traversal_singlethread_singletrack( alt_start = new Expr::Vacc(new std::string("max_tiles_n")); } CYKloop col = get_for_column(ast.grammar()->right_running_indices[track], - seq, alt_start, new Expr::Const(9999), with_checkpoint, mode); + alt_start, seqend, with_checkpoint, mode); col.loop->statements.push_back(row.loop); col.loop->statements.push_back(row.end_state); @@ -281,6 +285,40 @@ std::list *cyk_traversal_singlethread_singletrack( return stmts; } +/* + * for (unsigned int t_0_i = 0; t_0_i <= t_0_seq.size(); ++t_0_i) { + for (unsigned int t_0_j = t_0_seq.size() - t_0_i; t_0_j <= t_0_seq.size(); ++t_0_j) { + * + */ +std::list *cyk_traversal_singlethread_singletrack_outside( + size_t track, const AST &ast, Statement::Var_Decl *seq, + std::list *nested_stmts, bool with_checkpoint, + CYKmode mode) { + std::list *stmts = new std::list(); + + // create t_X_seq.size() call + Expr::Fn_Call *seqend = new Expr::Fn_Call(new std::string("size")); + dynamic_cast(seqend)->add_arg(seq->name); + dynamic_cast(seqend)->is_obj = Bool(true); + + CYKloop col = get_for_column( + ast.grammar()->right_running_indices[track], + seqend->minus(ast.grammar()->left_running_indices[track]), seqend->plus(new Expr::Const(1)), + with_checkpoint, mode); + std::list *co = copy_statements(nested_stmts); + col.loop->statements.insert( + col.loop->statements.end(), co->begin(), co->end()); + + CYKloop row = get_for_row(ast.grammar()->left_running_indices[track], + new Expr::Const(0), seqend->plus(new Expr::Const(1)), + with_checkpoint, mode); + row.loop->statements.push_back(col.loop); + + stmts->push_back(row.loop); + + return stmts; +} + // recursively reverse iterate through tracks and create nested for loop // structures std::list *cyk_traversal_singlethread(const AST &ast, @@ -292,9 +330,15 @@ std::list *cyk_traversal_singlethread(const AST &ast, ast.seq_decls.rbegin(); for (int track = ast.grammar()->axiom->tracks() - 1; track >= 0; track--, ++it_stmt_seq) { - stmts = cyk_traversal_singlethread_singletrack( - track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, - mode); + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + stmts = cyk_traversal_singlethread_singletrack_outside( + track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, + mode); + } else { + stmts = cyk_traversal_singlethread_singletrack( + track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, + mode); + } } return stmts; @@ -302,6 +346,7 @@ std::list *cyk_traversal_singlethread(const AST &ast, + /* Construct the loop traversal structure for CYK parsing of one track in * multi-threaded mode. Before we can start operating in parallel, we need to * compute all predecessor cells (part A). Thus, tiles of the DP matrix on the @@ -382,7 +427,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, CYKloop row = get_for_row(ast.grammar()->left_running_indices[track], row_start, z, with_checkpoint, CYKmode::OPENMP_PARALLEL); CYKloop col = get_for_column(ast.grammar()->right_running_indices[track], - seq, z, z->plus(new Expr::Vacc(*tile_size)), with_checkpoint, + z, z->plus(new Expr::Vacc(*tile_size)), with_checkpoint, CYKmode::OPENMP_PARALLEL); col.loop->statements.push_back(row.loop); Expr::Base *start_z = new Expr::Const(0); @@ -418,7 +463,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, (new Expr::Vacc(*x))->minus(new Expr::Vacc(*tile_size)), with_checkpoint, CYKmode::OPENMP_PARALLEL); CYKloop colB = get_for_column(ast.grammar()->right_running_indices[track], - seq, y, y->plus(new Expr::Vacc(*tile_size)), with_checkpoint, + y, y->plus(new Expr::Vacc(*tile_size)), with_checkpoint, CYKmode::OPENMP_PARALLEL); colB.loop->statements.push_back(rowB.loop); @@ -665,13 +710,13 @@ Fn_Def *print_CYK(const AST &ast) { // recursively reverse iterate through tracks and create nested for loop // structures std::list *stmts = cyk_traversal_singlethread( - ast, CYKmode::SINGLETHREAD); - // add NT calls to traversal structure - std::list *new_stmts = add_nt_calls(*stmts, - new std::list(), ast.grammar()->topological_ord(), - ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD); - stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); - // finally add traversal structure with NT calls to function body + ast, ast.outside_generation() ? CYKmode::SINGLETHREAD_OUTSIDE : CYKmode::SINGLETHREAD); +// // add NT calls to traversal structure +// std::list *new_stmts = add_nt_calls(*stmts, +// new std::list(), ast.grammar()->topological_ord(), +// ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD); +// stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); +// // finally add traversal structure with NT calls to function body fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); // ==== multi thread version (only single-track possible for now) @@ -767,3 +812,7 @@ Fn_Def *print_CYK(const AST &ast) { return fn_cyk; } + + + + diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 7c96c6d88..ab6265bd2 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -182,7 +182,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { stmts = &((*loops->rbegin())->statements); } - stmts->push_back(new Statement::CustomeCode( + stmts->push_back(new Statement::CustomCode( "out << \"start answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); @@ -198,7 +198,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { // produce: out << "//end answers outside_iloop(" << t_0_i << "," // << t_0_j << ")\n"; - stmts->push_back(new Statement::CustomeCode( + stmts->push_back(new Statement::CustomCode( "out << \"//end answers " + *nt->name + "(\"" + idx_param + "\")\\n\";")); diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh index a497fb348..5cfbeaa0f 100644 --- a/src/outside/codegen.hh +++ b/src/outside/codegen.hh @@ -37,6 +37,7 @@ #include "../statement/fn_call.hh" #include "grammar_transformation.hh" + void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast); #endif // SRC_OUTSIDE_CODEGEN_HH_ diff --git a/src/statement.hh b/src/statement.hh index a7a32887d..e20a432da 100644 --- a/src/statement.hh +++ b/src/statement.hh @@ -372,7 +372,7 @@ class CustomCode : public Base { std::string line_of_code; explicit CustomCode(std::string line_of_code) : - Base(CUSTOMECODE), line_of_code(line_of_code) { + Base(CUSTOMCODE), line_of_code(line_of_code) { } void print(Printer::Base &p) const; diff --git a/src/statement/base.hh b/src/statement/base.hh index 63ff5a541..70b7c76f6 100644 --- a/src/statement/base.hh +++ b/src/statement/base.hh @@ -50,11 +50,7 @@ namespace Statement { enum Type { RETURN, IF, VAR_DECL, BLOCK, FOR, FOREACH, VAR_ASSIGN, FN_CALL, BACKTRACE_DECL, BACKTRACE_NT_DECL, HASH_DECL, BREAK, MARKER_DECL, TABLE_DECL, CONTINUE, WHILE, -<<<<<<< HEAD - DECREASE, INCREASE, SORTER, SWITCH, CUSTOMECODE, -======= - DECREASE, INCREASE, SORTER, SWITCH, CUSTOMECODE ->>>>>>> 4b954d4b31cb7234c77b263fea5fac671076fa00 + DECREASE, INCREASE, SORTER, SWITCH, CUSTOMCODE }; diff --git a/testdata/grammar2/alignments_cyk.gap b/testdata/grammar2/alignments_cyk.gap index a31ceea83..cbbd7d7fd 100644 --- a/testdata/grammar2/alignments_cyk.gap +++ b/testdata/grammar2/alignments_cyk.gap @@ -48,7 +48,7 @@ algebra alg_maxMatch implements sig_alignments(alphabet = char, answer = int) { // pair-wise global alignment grammar gra_NWcyk uses sig_alignments(axiom=nt_const) { - nt_const = nt_left # h; + nt_const = nt_left | Sto() # h; nt_left = split(, nt_right) # h; nt_right = splitR(A, ) # h; diff --git a/testdata/regresstest/config b/testdata/regresstest/config index f92010f83..d2665d24a 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -3,484 +3,6 @@ DEFAULT_LDLIBS_EXTRA=$LDLIBS_EXTRA DEFAULT_CPPFLAGS_EXTRA=$CPPFLAGS_EXTRA DEFAULT_GAPC=$GAPC -check_new_old_eq elm.gap unused enum 1+2*3*4+5 foo - -check_new_old_eq loco3stem.gap unused count caucguacgucagucguagucaguugcagugcaucgacua foo - -check_new_old_eq loco3stem.gap unused count gggcguucucauagguccgcguggguuagacauucaagguuauuuuuuauccggaguuaccucaucuaauugauagauuaagaaauucuuuuguucgaauaaggcgcaguuauuuacccuuuugauuccuaaaaacuuuccgccgccgucaagaugacaaauaacaaacuugccaaggcggcauccguuuuuagauaauu bar - -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq rnashapes2wip.gap unused mfepp gcgcggugcgucacgcaucacauacucaucaacgaugagaagc foo - -check_new_old_eq rnashapespf.gap unused pf GGAGAGAUGGCUGAGUGGUUGAUAGCUCCGGUCUUGAAAACCGGUAUAGUUCUAGGAACUAUCGAGGGUUCGAAUCCCUCUCUCUCCUGGAGAGAUGGCUGAGUGGUUGAUAGCUCCGGUCUUGAAAACCGGUAUAGUUCUAGGAACUAUCGAGGGUUCGAAUCCCUCUCUCUCCU pf - -RUN_CPP_FLAGS="" - -check_new_old_eq cmsmallint.gap unused enum a foo - -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq adpf.gap unused shapemfepp acgugucagucagucauggucaucauacugccgua foo - -CPPFLAGS_EXTRA+="-DSTATS" - -# FIXME, with optimized classify, the stat-ing of one hash-table is of no use -# ugucgcccgaccuguaaucgauuguuauuuccaggcucgagggcaagucuugaaaggacuaccuugucgaaguggacagugcagcgauugacggauucagucggggcauauugugcauaaugucagc -#check_feature adpf.gap shape5 ugucgcccgaccuguaaucgauuguuauuuccaggcucgagggcaagucuugaaaggacuaccuugucgaaguggacagug foo err grep "Hi water use: 428785\>" - -CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA - -GAPC="../../../gapc -t --window-mode" - -RUN_CPP_FLAGS="-w 20 -i 5" - -check_new_old_eq adpf.gap unused bpmaxpp auagacguguaauuauugaggaacaggcaucgaucauaauaggguaucagggauacaugaauaggcuuagcgucaguuguuggcuauuccaucaucggguacaauuccauacuucgcaugggaucaaccaagcucuaguggccgccuaug foo - -RUN_CPP_FLAGS="-w 23 -i 8" - -check_new_old_eq adpf.gap unused bpmaxpp auagacguguaauuauugaggaacaggcaucgaucauaauaggguaucagggauacaugaauaggcuuagcgucaguuguuggcuauuccaucaucggguacaauuccauacuucgcaugggaucaaccaagcucuaguggccgccuaug bar - -RUN_CPP_FLAGS="-w 100 -i 50 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq adpf.gap unused mfepp cuccccucuucggacgcaacuuaugccuaggaccuauuuugcacagaaugagggcuagggaagagccgucccucagugagcagaguuaaguuguuguuugaguaacucccggcgggcuaagccauugcacccaaccgcuugccugucauucuggaccgggauggaaccguaccucugcacuuaagacagacuaucaaaagcguauggcggguuguggucucaagugggaggacaaucaccguauauuugaucaacgauucagggaugcucacccguuucuuauuugaaacuuggcacccggaauauucugaagccaauacaguuugugacacaaccccgucaguugagacucuuuuaacgccgugugccgacgaaucuccccacgguaugcgcuggucggucccacgagggcguauaucgccaaggcagcuuaugguaacgucgcauaccagcucaagccgguugaaauaacagguccaguuuguaggucucuucugugacguaggccugcagcaagaacugcgcaugcuugucguagaggccaauagagcugaucuggcaaucguaaagguaguguuuagguagcuucauguauucaucuuucgucaucgcaagcuaaacuugcgcucaucacuauggcgucaucugaggucguugcgagaaagaugcuagguugcgcgcauaacgacuuuaagcguuagauuccgccucucaucgggccagcgaaagacccauacgcaaacgcgcuaucgcaguaauggaauaauuggcaguacucaucgccggcgucgcuauguucuaugcucacgcucucuccaggcggcggauggucccugccagcgcucgagaggcauccaaguuggaacuauauccuaugaaucacaaugccggucacuucgcgggcuaauaaguuccucaggggaccaggacgugauuuuccgugcagggggggccggucacacgcaggagguuugggcuagcacaagcccaacaaccacau foo - -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-f" - -check_new_old_eq adpf.gap unused shape5 "../../input/rna127" bar - -RUN_CPP_FLAGS="" -CPPFLAGS_EXTRA+=" -DUSE_GMP_INT" -# under Linux -lgmpxx pulls automatically -lgmp, Solaris does not -LDLIBS_EXTRA+=" -lgmp -lgmpxx" - -check_new_old_eq elm.gap unused acount '1+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+1' foo - -CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA -LDLIBS_EXTRA=$DEFAULT_LDLIBS_EXTRA - -# Jens subopt old adpc bug report 1 - -GAPC="../../../gapc -t --subopt" - -# 30 % -RUN_CPP_FLAGS="-d 552 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq rnashapesmfe.gap unused mfepp ugcuagucagcuaucgacucgugcagcaguacgaucagcauagcuagcacuacgcua subopt30 - -# 31 % -GAPC="../../../gapc -t --cyk --subopt" -RUN_CPP_FLAGS="-d 570 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq rnashapesmfe.gap unused mfepp ugcuagucagcuaucgacucgugcagcaguacgaucagcauagcuagcacuacgcua subopt31 - -# Jens subopt old adpc bug report 2 (prob sum > 1.0) - -GAPC="../../../gapc -t --subopt" -RUN_CPP_FLAGS="-d 1090 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq adpf_nonamb.gap unused mfepppf CCacaccaacacacCuGuCACGGGAGAGAAuGuGGGuuCAAAuCCCAuCGGuCGCGCCA subopt - -check_feature adpf_nonamb.gap mfepppf CCacaccaacacacCuGuCACGGGAGAGAAuGuGGGuuCAAAuCCCAuCGGuCGCGCCA suboptpfsum out $KSH ../check_prob_sum 9.33773 - -# - -# another Jens subopt RNAshapes -r -s Probability sum > 1.0 bug -# mail from Date: Fri, 13 Feb 2009 11:16:32 - -RUN_CPP_FLAGS="-d 224 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_feature adpf_nonamb.gap mfepppf UCACCGUCGGAAAGUGUGCGCUUUCCCUGAUGAGCCCAAAAGGGCGAAACGGUAC suboptpfsum2 out $KSH ../check_prob_sum 5.06405e+08 - -# - -GAPC="../../../gapc -t" - -check_new_old_eq adpf_nonamb.gap unused shape5pf CCacaccaacacacCuGuCACGGGAGAGAAuGuGGGuuCAAAuCCCAuCGGuCGCGCCA shapesubopt - -GAPC="../../../gapc --tab-all" -RUN_CPP_FLAGS="-f" - -# FIXME remove - obsoleted by external test case, which is more robust -#check_new_old_eq adpf_nonamb.gap unused shape5pfx ../../input/rna150 shapefpffilter - - -#GSL_RNG_SEED=`../rand 1` -#export GSL_RNG_SEED - -RUN_CPP_FLAGS="-r 1000 -P ../../../librna/paramfiles/rna_turner1999.par -f" -GAPC="../../../gapc -t --sample" - -check_feature adpf.gap pfsampleshape ../../input/rna100 sample out $KSH ../check_samples ../adpf.rna100shapepf 0.000349275 0.00005 - - -# Sequence from Jens RNAshapes sampling mode bug report - -RUN_CPP_FLAGS="-r 1000 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_feature adpf_nonamb.gap pfsampleshape AGAGAACAUGAGAGAGAUUCCCAACAGAGGCCUGCACGCACUUGGACUCU sample out $KSH ../check_samples ../nonamb_shape_pf.log 6.33459e-05 0.00005 - -# Sequence from Jens RNAshapes sampling mode bug report, distribution test - -RUN_CPP_FLAGS="-r 1000 -P ../../../librna/paramfiles/rna_turner1999.par" - -check_feature_repeat_mean_var adpf_nonamb.gap pfsampleshape AGAGAACAUGAGAGAGAUUCCCAACAGAGGCCUGCACGCACUUGGACUCU sample2 - -# Too much sample output bug ( see a9fed4287fda and 980a3871b4a7 ) -GAPC="../../../gapc -t --sample --cyk" -RUN_CPP_FLAGS="-r 1 -P ../../../librna/paramfiles/rna_turner1999.par -f" -check_feature adpf_nonamb.gap pfsampleshapeall ../../input/rna400 samplecount out $KSH ../check_sample_count - -RUN_CPP_FLAGS="-f" -GAPC="../../../gapc -t" - -check_new_old_eq nussinov.gap unused bpmax1pp ../../input/rna150 takeone - -CPPFLAGS_EXTRA+=" -DUSE_GMP_INT" -LDLIBS_EXTRA+=" -lgmp -lgmpxx" - -check_new_old_eq adpf.gap unused cart ../../input/rna150 cartesian - -GAPC="../../../gapc -t --backtrack" - -check_new_old_eq adpf.gap unused cartpp2 ../../input/rna20 cartesian2 - -CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA -LDLIBS_EXTRA=$DEFAULT_LDLIBS_EXTRA - -RUN_CPP_FLAGS="-f" -GAPC="../../../gapc -t --backtrack" - -check_new_old_eq nussinov.gap unused bpmax1pp ../../input/rna150 takeonebt - -GAPC="../../../gapc -t --kbacktrack" -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq adpf_nonamb.gap unused shapemfepf acgccucuucgaaguucaggauuugaccgccgcaugcgaacucggauuacgaaacauuuc kbt - -# FIXME remove - obsoleted by external test case, which is more robust -#check_new_old_eq adpf_nonamb.gap unused shapemfepfx acgccucuucgaaguucaggauuugaccgccgcaugcgaacucggauuacgaaacauuuc kbtpfx - -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par -f" -GAPC="../../../gapc -t --cyk --kbacktrack" - -check_new_old_eq helene.gap unused mfepp ../../input/rna100 rope - - -check_external extpfx ../check_shape_filter_old_new "../../test/shapemfepfx/main -w 2 -i 1 -P ../../../librna/paramfiles/rna_turner1999.par" $REF/shapemfepfx.150.log 0.000001 0.000001 2 `cat ../../input/rna150` - -check_external extsample ../check_shape_filter "../../test/shrepmfesample/main -r 2000 -P ../../../librna/paramfiles/rna_turner1999.par" $REF/shrepmfesample.2000.150.log 0.0002 0.0002 1 `cat ../../input/rna150` - - -check_external extpfxwindow ../../test/shapemfepfx/test.pl ../../test/shapemfepfx/main ../../test/shapemfepfx/nowindow `cat ../../input/rna100` - - -#RUN_CPP_FLAGS="-x -300 -f" -# thresh of 0 -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par -f" -GAPC="../../../gapc -t --kbacktrack --cyk" - -check_new_old_eq adpf_hl.gap unused mfepp ../../input/rna200 suchthat - - -GAPC="../../../gapc -t --cyk --subopt-classify --kbacktrack" -RUN_CPP_FLAGS="-d 0 -P ../../../librna/paramfiles/rna_turner1999.par -f" - -check_new_old_eq adpf.gap unused shapemfepp ../../input/rna80 subshape - -RUN_CPP_FLAGS="-d 50 -P ../../../librna/paramfiles/rna_turner1999.par -f" -check_new_old_eq adpf.gap unused shapemfepp ../../input/rna80 subshape2 - -RUN_CPP_FLAGS="-d 100 -P ../../../librna/paramfiles/rna_turner1999.par -f" -check_new_old_eq adpf.gap unused shapemfepp ../../input/rna80 subshape3 - -RUN_CPP_FLAGS="-d 429 -P ../../../librna/paramfiles/rna_turner1999.par -f" -check_new_old_eq adpf.gap unused shapemfepp ../../input/rna20 subshape4 - -RUN_CPP_FLAGS="-d 430 -P ../../../librna/paramfiles/rna_turner1999.par -f" -check_new_old_eq adpf.gap unused shapemfepp ../../input/rna20 subshape5 - -RUN_CPP_FLAGS="-d 100 -P ../../../librna/paramfiles/rna_turner1999.par -f" -check_new_old_eq adpf_nonamb.gap unused shapemfepp ../../input/rna80 subshape8 - -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par -f" -GAPC="../../../gapc -t --cyk --kbacktrack" -check_new_old_eq adpf.gap unused shapemfeppcl ../../input/rna20 subshape6 - -check_new_old_eq adpf.gap unused shapemfeppshcl ../../input/rna20 subshape7 - -RUN_CPP_FLAGS="" - - -# FIXME tab heuristic (-t) is not optimal for this grammar -GAPC="../../../gapc --tab-all" -check_new_old_eq structure2shape.gap unused shape5 '..(((...((......))...(((.....)))....)))..' structure - - -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-f" -check_new_old_eq flowgram.gap unused foo ../../input/flow flow - -RUN_CPP_FLAGS="-w 20 -i 5 -P ../../../librna/paramfiles/rna_turner1999.par -f" -GAPC="../../../gapc -t --backtrack --window-mode" -check_new_old_eq adpf.gap unused mfepp ../../input/rna80 windowbacktrack - -RUN_CPP_FLAGS="-w 20 -i 1 -P ../../../librna/paramfiles/rna_turner1999.par -f" -GAPC="../../../gapc -t --kbacktrack --no-coopt --window-mode" -check_new_old_eq adpf.gap unused mfepp ../../input/rna80 windowkbacktrack - -RUN_CPP_FLAGS="" -GAPC="../../../gapc -t" -check_new_old_eq g3pl.gap unused shapeprobls acgucguagucagucaacguacgucagu classlogspace - -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-f" -check_new_old_eq flowgram2b.gap unused score ../../input/flow.2 multitrack.flow - -GAPC="../../../gapc -t --cyk --kbacktrack" -check_new_old_eq flowgram2b.gap unused foo ../../input/flow.2 multitrack.flow - - -# multiple singleton {} blocks in grammar (see nt_stem) - -RUN_CPP_FLAGS="" -GAPC="../../../gapc -t" - -check_new_old_eq single_block.gap unused count CCAAAGG block - -check_new_old_eq elm.gap unused enumenum '1+2*3' prodcopy - -check_new_old_eq optimalMCM.gap unused minmemminmult '[3x4]*[4x3]' extends - - -# test case for multiple classifying choice fns -> classify optimization -# minimal example for part of the pknotsRG multi choice fns classify bug -check_new_old_eq mchoice.gap unused shape 'gattaca' multiplechoiceclass - -# FIXME add pknotsRG shape5 - -GAPC="../../../gapc -t --cyk --kbacktrack" -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq pknotsRG.gap unused mfepp 'acgucgaaauaaaugccuugucugcuauauucgacgcgagcuuaauauuuggggcc' index - - -GAPC="../../../gapc -t " - -check_new_old_eq tdm2hp.gap unused pretty aaacccggggaauuccuu tabledim -check_new_old_eq tdm2hporig.gap unused pf gaauacccacggaugguagauuucgcuuuugggugaacuugccacgcccccgacggucgcgagcuuaucugcuauaccccaauugagaauacagggaacuu tabledim - - -GAPC="../../../gapc -t --kbacktrace --no-coopt" -RUN_CPP_FLAGS="" - -check_new_old_eq nussinov2.gap unused bpmaxpp caguagucagcu nocooptkbt - -GAPC="../../../gapc -t --kbacktrace " -RUN_CPP_FLAGS=" gggaaaaccc " - -check_new_old_eq multfilter.gap unused bpmaxpp aggaaaacca multitrack.filter - -GAPC="../../../gapc -t " -RUN_CPP_FLAGS=" cagu " - -check_new_old_eq aliglob2.gap unused enum cag multitrack.enum - - -RUN_CPP_FLAGS="" - -check_compiler_output ../../grammar2 elmnoterm.gap buyer compile grep "Function char is not defined" - -GAPC="../../../gapc -t " -RUN_CPP_FLAGS="" -GRAMMAR=../../grammar2 - -check_new_old_eq multigrammar.gap unused seller '1+2*3*4+5' multigrammar - -check_new_old_eq ochoice.gap unused buyer '1+2*3*4+5' optchoice - - -GAPC="../../../gapc --tab-all " -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" -GRAMMAR=../../grammar2 - -check_new_old_eq p7.gap unused mfe 'gagacugcagucc' tablegen -check_new_old_eq p72.gap unused mfe 'gagacugcagucc' tablegen - -GAPC="../../../gapc --tab-all --cyk --kbacktrace" -GRAMMAR=../../grammar2 -RUN_CPP_FLAGS="" - -check_new_old_eq rf01380.gap unused cykpp 'AGUCA' tablegen.rightlin - -GAPC="../../../gapc -t --kbest" -RUN_CPP_FLAGS="-k 5 -P ../../../librna/paramfiles/rna_turner1999.par -f" -GRAMMAR=../../grammar - -check_new_old_eq adpf.gap unused shapemfe ../../input/rna200 kbest - - -GAPC="../../../gapc --tab-all" -RUN_CPP_FLAGS="AA " -GRAMMAR=../../grammar2 -check_new_old_eq menum.gap unused enumi "AA" multi.enum - - -RUN_CPP_FLAGS="" -GAPC="../../../gapc -t " -GRAMMAR=../../grammar2 - -check_compiler_output ../../grammar2 ttcounterr.gap test compile.multi grep "does not match" - -GRAMMAR=../../grammar -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" - -check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG mfe1.t1999 -check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG mfe2.t1999 -check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC mfe3.t1999 - -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner2004.par" - -check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG mfe1.t2004 -check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG mfe2.t2004 -check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC mfe3.t2004 - - -RUN_CPP_FLAGS="-t 50.742 -P ../../../librna/paramfiles/rna_turner1999.par" - -GAPC="../../../gapc -t" - -check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG temp50.mfe1.t1999 -check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG temp50.mfe2.t1999 -check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC temp50.mfe3.t1999 - -GAPC="../../../gapc -t" -RUN_CPP_FLAGS="-t 50.742 -P ../../../librna/paramfiles/rna_turner2004.par" - -check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG temp50.mfe1.t2004 -check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG temp50.mfe2.t2004 -check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC temp50.mfe3.t2004 - -RUN_CPP_FLAGS="-f" -GRAMMAR=../../grammar2 -GAPC="../../../gapc -t" - -check_new_old_eq escape.gap unused acount ../../input/esc esc - -RUN_CPP_FLAGS="c" -GRAMMAR=../../grammar2 -GAPC="../../../gapc -t --kbacktrace" - -# from mmoehl -check_new_old_eq interaction.gap unused bpmaxpp g multitrack.kbt - -GAPC="../../../gapc -t " -GRAMMAR=../../grammar2 -RUN_CPP_FLAGS="abc" - -check_new_old_eq mcount.gap unused cnt abc multitrack.count - -RUN_CPP_FLAGS="ac" - -check_new_old_eq trackpos.gap unused cnt dc multitrack.trackpos - -GRAMMAR=../../grammar2 -RUN_CPP_FLAGS="" - -check_new_old_eq overlay.gap unused count '1+2*3*4*5' overlay - -GAPC="../../../gapc -t --kbacktrace" -RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" -check_new_old_eq backtraceminys.gap unused mfepre a kbt - -GAPC="../../../gapc -t --cyk" -RUN_CPP_FLAGS="" - -GRAMMAR=../../grammar2 - -check_new_old_eq adpfiupac.gap unused mfepp agcugucaugcagucguagucaguca iupac - -GRAMMAR=../../grammar2 -check_new_old_eq locomotif.gap unused pretty acugacugaacuguacguugaugac foo - -#test for new functions to rope: "front", "back" and "tail". For MacOSx the shape datatype has problems with hashing, thus we need a rope version for the shape algebras, but that rope first has to implement the aforementioned functions. -GRAMMAR=../../grammar -GAPC="../../../gapc" -check_new_old_eq macrostate.gap unused shape1count acuguagucugagucacguuaucuggucguaucgaucgaucgaucacuguaguc shape_t -check_new_old_eq macrostate.gap unused shape1ropecount acuguagucugagucacguuaucuggucguaucgaucgaucgaucacuguaguc rope - -# we are here testing of seg fault due to wrongly increased Iterator in hashmap (subopt.cc) passes -# See issue #38 @ github.com/jlab/gapc -GAPC="../../../gapc --subopt" -check_new_old_eq rnashapesmfe.gap unused mfeppshape "A" foo - -#test new FLOAT terminal parser -GAPC="../../../gapc" -RUN_CPP_FLAGS="" -check_new_old_eq testfloat.gap unused enum "23" floatint -check_new_old_eq testfloat.gap unused enum "23.4" justfloat -check_new_old_eq testfloat.gap unused enum "23.45" largerfloat -check_new_old_eq testfloat.gap unused enum "23.45678" largerfloat2 -check_new_old_eq testfloat.gap unused enum "23.00000009" smallpostradix -check_new_old_eq testfloat.gap unused enum "2.345e+06" failscientific - -# test yield size analysis of const (i.e. string) terminal arguments, like ROPE("stefan") -check_compiler_output ../../grammar2 testtermarg.gap testme termarg grep "6), \"stefan" testtermarg.cc - -# fixing missing includes when changing gapc flag --float-accuracy -GRAMMAR=../../grammar -GAPC="../../../gapc --float-accuracy 2" -check_new_old_eq elm.gap unused pareto "1+2*3+4*5" floatacc - -GAPC="../../../gapc --checkpoint" -# int -check_checkpoint_eq adpf.gap unused mfe "GCUUCACAUCUCGGGCAUUUUCCUGCAAAACCAUACCCUUACGAAAAGUACGGCAUUGAUAAUCAUUUUCAAUAUCAUUUAAUUAACUAUAAUGAACCAACUGCUUACGCGGCAUUAACAAUCGGCCGCCCGACAAUACUGGAGAUGAAUAUGAGCUAUACCCUGCCAUCCCUGCCGUAUGCUUACGAUGCCCUGGAACCGCACUUCGAUAAGCAGACCAUGGAAAUCCACCACACCAAACACCAUCAGACCUACGUAAACAACGCCAACGCGGCGCUGGAAAGCCUGCCAGAAUUUGCCAACCUGCCGGUUGAAGAGCUGAUCACCAAACUGGACCAGCUGCCAGCAGACAAGAAAACCGUACUGCGCAACAACGCUGGCGGUCACGCUAACCACAGCCUGUUCUGGAAAGGUCUGAAAAAAGGCACCACCCUGCAGGGUGACCUGAAAGCGGCUAUCGAACGUGACUUCGGCUCCGUUGAUAACUUCAAAGCAGAAUUUGAAAAAGCGGCAGCUUCCCGCUUUGGUUCCGGCUGGGCAUGGCUGGUGCUGAAAGGCGAUAAACUGGCGGUGGUUUCUACUGCUAACCAGGAUUCUCCGCUGAUGGGUGAAGCUAUUUCUGGCGCUUCCGGCUUCCCGAUUAUGGGCCUGGAUGUGUGGGAACAUGCUUACUACCUGAAAUUCCAGAACCGCCGUCCGGACUACAUUAAAGAGUUCUGGAACGUGGUGAACUGGGACGAAGCAGCGGCACGUUUUGCGGCGAAAAAAUAA" checkpoint1 1 -# int -check_checkpoint_eq adpf.gap unused mfe "GUAAAAUAAACAACGCUGAUAUUAGCCGUAAACAUCGGGUUUUUUACCUCGGUAUGCCUUGUGACUGGCUUGACAAGCUUUUCCUCAGCUCCGUAAACUCCUUUCAGUGGGAAAUUGUGGGGCAAAGUGGGAAUAAGGGGUGAGGCUGGCAUGUUCCGGGGAGCAACGUUAGUCAAUCUCGACAGCAAAGGGCGCUUAUCAGUGCCUACCCGUUAUCGGGAACAGCUGCUUGAGAACGCUGCCGGUCAAAUGGUUUGCACCAUUGACAUUUAUCACCCGUGCCUGCUGCUUUACCCCCUGCCUGAAUGGGAAAUUAUCGAGCAAAAAUUAUCGCGUCUGUCGAGCAUGAACCCGGUUGAGCGCCGUGUGCAGCGCCUACUGUUAGGUCAUGCCAGCGAAUGUCAGAUGGAUGGCGCAGGUCGAUUGUUAAUCGCGCCAGUACUGCGGCAACAUGCCGGGCUGACAAAAGAAGUGAUGCUGGUUGGACAGUUCAACAAGUUUGAGCUGUGGGAUGAAACAACCUGGCAUCAACAGGUCAAGGAAGAUAUCGACGCAGAGCAGUUGGCUACCGGAGACUUAUCGGAGCGACUGCAGGACUUGUCUCUAUAAACGAUCUGACGAGCGAUCUAGCGAGCAUCGAUCUGAUCAUCUACUAUCUAUUCUAUCUAUCGGGGUGUCGACGAUCU" checkpoint2 1 -# int -check_checkpoint_eq adpf.gap unused mfe "GUUGUAGACUUUACAUCGCCAGGGGUGCUCGGCAUAAGCCGAAGAUAUCGGUAGAGUUAAUAUUGAGCAGAUCCCCCGGUGAAGGAUUUAACCGUGUUAUCUCGUUGGAGAUAUUCAUGGCGUAUUUUGGAUGAUAACGAGGCGCAAAAAAUGAAAAAGACAGCUAUCGCGAUUGCAGUGGCACUGGCUGGUUUCGCUACCGUAGCGCAGGCCGCUCCGAAAGAUAACACCUGGUACACUGGUGCUAAACUGGGCUGGUCCCAGUACCAUGACACUGGUUUCAUCAACAACAAUGGCCCGACCCAUGAAAACCAACUGGGCGCUGGUGCUUUUGGUGGUUACCAGGUUAACCCGUAUGUUGGCUUUGAAAUGGGUUACGACUGGUUAGGUCGUAUGCCGUACAAAGGCAGCGUUGAAAACGGUGCAUACAAAGCUCAGGGCGUUCAACUGACCGCUAAACUGGGUUACCCAAUCACUGACGACCUGGACAUCUACACUCGUCUGGGUGGCAUGGUAUGGCGUGCAGACACUAAAUCCAACGUUUAUGGUAAAAACCACGACACCGGCGUUUCUCCGGUCUUCGCUGGCGGUGUUGAGUACGCGAUCACUCCUGAAAUCGCUACCCGUCUGGAAUACCAGUGGACCAACAACAUCGGUGACGCACACACCAUCGGCACUCGUCCGGACAACGGCAUGCUGAGCCUGGGUGUUUCCUACCGUUUCGGUCAGGGCG" checkpoint3 1 -# List_Ref -check_checkpoint_eq adpf.gap unused mfepp "CGUAGUCGUAGUUCUGAGUCGUAGUCGUAGUCGUGUACUGAGUGCUGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCUGUGAGUCGUAGUCGUAGUCGUAGUCGUAcGUCAGCGAGUCGUAGUCGUAGUCGUAGUCGAGUAGUCAGUCUGAGCAGUCUAGUGCUGUAGUCGUAGUCGUAGUCUGCUGACGUCGUAUGCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUAGUCGUAGUCAGUCGUAGUCGUAGUCGUAGUGUC" checkpoint4 1 -# std::pair -check_checkpoint_eq adpf.gap unused mfeen "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUA" checkpoint5 1 -# Hash::Ref> -check_checkpoint_eq adpf.gap unused shape5pfx "CGAGCGUAGUCGUAGCguCGUAGCGUAGUCGUAGUCGUGCUGAGUCguaCAGUCGGAGCUAGUCGUAGUCGUAGUCGUAGCUAGUCGUCGUAGUCGUAGUCGAGUCGUACGUCGUAGCGUAGUCGUAGCUAGUGUAGCUCGUAGUCGUGUCACACCGUAUA" checkpoint6 1 -GAPC="../../../gapc --checkpoint --sample" -# double + Backtrace -check_checkpoint_eq adpf.gap unused pfsampleshape "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUACGUACGUAGUCGUAGUCGUAGUCGUAGUCGAGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUGUACGUACGUGUACGGUCGUAGUCGUAGCUguCGUAGCGUAGUCGUAGUCGUAGUCGUAGUCAGUCGUAGUGUAGUGUCGUCGUCGUAGUCGUAGUCGUAGUCAGUCGUAGUCGUAGUCGUAGUCGAUGUAGUGUCGUAGUCAGUCUGAGUCGUAGCGUAGUCGAUGUCAGUCGUAGUCGUAGUCGUAGUCGAUGCUAGUCCUGAGUCGUAGUCGUAGUCGAUCGUAGCUGAUCGUCGUAGUCGUAGUCGAGUCGACGUAGUCGUACGUAGUCGUACGUAGUCGUAGUACGUAGUGUACguCGUA" checkpoint7 1 -GAPC="../../../gapc --checkpoint --cyk" -# std::pair + cyk -check_checkpoint_eq adpf.gap unused mfepf "CGUAGCUGAUGCUGAGCGUCGUAUCUGAGUCGUGUAGUCGAUGUCGAUCGUAGUCGUGUCGAGUCGUAUGCGUAGCGUAGUCGUAGCUAGUCCGUAGCGUAGUCAGUGCUAGUGCUGCAGUGCUGAUCGUGUACGUCGAGUCGAGUCGUAGUCGUACGUAGUGCUAGUGCUAGUCGUAGUCGUGUCGUAGUCGUGAUGUCAGUGUCGUGUAGUCGUAGUCGUACGUGUACGUAGUCGUAGUCGUAUCGAGUCGCGUAGGCUAGUCGUAGUCGUAGUCGUGCGUAGCGUUGAGUCGUAGUCGAUGUCAGUCGUGUAGUCUGAGCUGAUCUGUUCGUAGCGUGUACGAGUCGUGUCGUGUAGCUGUAGUCGUAGUCAGUCAUGUAGUCGAUGCGUAGUCGUGUACGUGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUGUCGUAGCUGUAGUCGUGUAGUCGUAGUCUGAGUGUCGUAGUCGUCGUGUAGUCGUGUACGUGUAGUCGUGUAGUCGUAGUCGUAGUCGUUAUCGGAUGUCGUAGCUGUACGUGAUCGUCCGUC" checkpoint8 1 -# std::pair + cyk -check_checkpoint_eq adpf.gap unused mfeen "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUA" checkpoint9 1 -# std::pair + cyk -check_checkpoint_eq adpf.gap unused mfepp "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUAGUCGAUCGUGAUGUCGUAGUCGUGUAGCUGAUGCUGUAGUCGUAUGCGUAGUCGUGUACGUGUAGCU" checkpoint10 1 -# std::pair + cyk + two track -check_checkpoint_eq affinelocsim2.gap unused affinecnt "CUGAAACGUAGUCUGAAAAGCCCGCGUAGUCGUAGUCGUAGUCGUACGUUAGCGUUGAGUCGUAGUCGUAGUUGAGUUCGGUAGUCGUAGUCGUGUACCACACAUGUGCGUAGUCGUCAGUCGUAGUCGUACGUCGUCUAGCGUGUCGUAUGCGUACGUAGUCGAGUCUGACGAGUGCGUGGGUCUGAGUCGUCGUUAGGCCAGUCGUAGUCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUU" checkpoint11 1 "CGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUCGUAGUCGUAGUCGUAGUCGUACGUCGUAUGCUGAGCAAAAAAUCGUAGUCCUGAGUCGUAGCAUGCGUACGACGUGUCCGUAGCGUACGUGUAGUACGUAGUCGAUCGUCUGAGUGUCGUAGUCGUAGUCCGUAGUCUGUAGUGUCGUACGUCGUGUAGUCGUAGCUGUAGUCGUAGUCGUAGUCGUUGCGUAGUCGUAGCGUACGUAGUGUAGUCGUCGUGUAGCGUACGUGU" -# std::pair + cyk + two track -check_checkpoint_eq affinelocsim2.gap unused affinepp "CUGUCAGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUU" checkpoint12 1 "CGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUGUACGU" -GAPC="../../../gapc" -RUN_CPP_FLAGS="" -check_new_old_eq empty_ys_issue.gap unused count "A" Ashouldbe0 -check_new_old_eq empty_ys_issue.gap unused count "AA" AAshouldbe1 -check_new_old_eq empty_ys_issue.gap unused count "AAA" AAAshouldbe0 -RUN_CPP_FLAGS=" -f emptyinput " -echo "" > emptyinput # create an input file with empty word, since '' as parameter is not correctly propagated through bash scripts -check_new_old_eq empty_ys_issue.gap unused count dummyinput shouldbe1 -check_new_old_eq empty_ys_issue_larger.gap unused count dummyinput shouldbe1 - -# ensure that previously composed answers are not erased by later application of filters for completely different alternatives, see PR https://github.com/jlab/gapc/pull/123 -GRAMMAR=../../grammar2 -GAPC="../../../gapc" -RUN_CPP_FLAGS="" -check_new_old_eq eraseanswers.gap unused ins_count_failing "AC" eraseanswer -check_new_old_eq eraseanswers.gap unused ins_count_working "AC" eraseanswer -check_new_old_eq eraseanswers_product.gap unused ins "CaaG" eraseanswer_one -check_new_old_eq eraseanswers_product.gap unused ins "CaaaG" eraseanswer_four # ======= following are test of the new CYK code generation of file src/cyk.cc ======= GRAMMAR=../../grammar2 @@ -527,77 +49,3 @@ check_new_old_eq adpf.gap unused count "uacgugacguugacguguaucgguacuacgugacguugac GAPC="../../../gapc --cyk --checkpoint" check_checkpoint_eq adpf.gap unused pf "uacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguac" cyk_openmp_checkpoint 1 - -# results have been verified against "RNAfold -p -d0 --bppmThreshold=0" v2.4.17 and Stefan's manual python outside version of nodangle -GRAMMAR=../../grammar_outside -GAPC="../../../gapc --outside_grammar weak --outside_grammar struct" -check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside -check_new_old_eq nodangle.gap unused mfe "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside -check_new_old_eq nodangle.gap unused count "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside - -# check that fn_arg (with alt) instead of only alt gets initialized -check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside_overlay - - -# same as above, but with CYK code generation -GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" -check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside - - - - - - - - - - -GAPC="../../../gapc --outside_grammar ALL" -CPPFLAGS_EXTRA="" -LDLIBS_EXTRA="" -check_new_old_eq hmm_sonneregen.gap unused count "SS" outside -check_new_old_eq hmm_sonneregen.gap unused fwd "SS" outside -check_new_old_eq hmm_sonneregen.gap unused fwd "SSRR" outside_ssrr - -# example in which inside and outside NTs have different dimensions, don't use tmhmm_debug.gap as new semantic checks will prevent producing code -check_new_old_eq tmhmm_debug_nil.gap unused count "AA" outside_report - -# example with multiple tracks for outside report function -check_new_old_eq_twotrack alignments.gap unused count "AAAA" outside_2track "BBB" -check_new_old_eq_twotrack alignments.gap unused sim_enum "AA" outside_undefvar "B" - -# example with parameterized terminals e.g. ROPE("manfred") -check_new_old_eq elmamun.gap unused count "1+2*3" outside_elm - -# check correct indices for multiple CONST_FLOAT args for outside generation; caused by incorrectly set yield size when replacing NTs -check_new_old_eq nonzero_constsize.gap unused count "G" outside_constissue - -# test if outside to inside transitions works also for constant non-terminal tables, i.e. those missing t_0_i t_0_j parameters which should be replaced via dummies in this one and only situation -check_new_old_eq constAxiom.gap unused enum "G" outside_out2in - -# check TMHMM outside with real sequence which previously revealed < 1.0 prob sums -# to not exceed file size of truth, just report 5 random NTs -CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA -GAPC="../../../gapc --outside_grammar state_in21 --outside_grammar state_ihelixi7 --outside_grammar state_ihelix5 --outside_grammar state_in13 --outside_grammar state_outglob14 " -check_new_old_eq tmhmm.gap unused fwd_scaled "MENLNMDLLYMAAAVMMGLAAIGAAIGIGILGGKFLEGAARQPDLIPLLRTQFFIVMGLVDAIPMIAVGLGLYVMFAVA" outside_tmhmm -GAPC="../../../gapc --outside_grammar ALL" - -check_new_old_eq RFmini.gap unused enum "G" outside_cm -check_new_old_eq RFmini.gap unused count "G" outside_cm - -# Results can be converted into probabilities via nt_inside(i,j) + nt_outside(i,j) - axiom(0,n) - axiom(0,0) -# where axiom(0,0) is the pfunc value of the empty word. This words because we are in log2-space. -# Converted to probabilities: 2^nt_inside(i,j) * 2^nt_outside(i,j) / 2^axiom(0,n) / 2^axiom(0,0) -# The important aspect is that we have to also normalize by axiom(0,0) since the inside result of -# the empty word "" != 0 <-- log2-space but will be integrated in each and every outside candidate -check_new_old_eq RFmini.gap unused inside "G" outside_cm - -# more extensive example as before, also checked against cm_OutsideAlign of Infernal -GAPC="../../../gapc --outside_grammar state_MR_3 --outside_grammar state_MP_6 --outside_grammar state_S_0 --outside_grammar state_E_120" -check_new_old_eq RF00005.gap unused inside "GACGGUAU" outside_cm5 - -GAPC="../../../gapc --outside_grammar a_1 --outside_grammar a_47 --outside_grammar a_82" -# not yet explored -check_new_old_eq acmsearch_RF00005.gap unused inside "GACGGUAU" outside_acm - -CPPFLAGS_EXTRA="" From 18c30084c96c6a22b41b819594d6f51279718683 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 18 May 2023 18:34:14 +0200 Subject: [PATCH 123/189] intermedite state --- src/cyk.cc | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index 1c3a8f47e..192f31c97 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -561,7 +561,7 @@ size_t count_nt_calls_and_loops(Statement::For *loop) { */ std::list *add_nt_calls(std::list &stmts, std::list *loop_vars, std::list orderedNTs, - bool with_checkpoint, CYKmode mode) { + bool with_checkpoint, CYKmode mode, const AST &ast) { bool contains_nested_for = false; for (std::list::iterator s = stmts.begin(); s != stmts.end(); ++s) { @@ -581,7 +581,7 @@ std::list *add_nt_calls(std::list &stmts, } std::list *new_stmts = add_nt_calls( fl->statements, next_loop_vars, orderedNTs, with_checkpoint, - mode); + mode, ast); fl->statements.insert( fl->statements.end(), new_stmts->begin(), new_stmts->end()); } @@ -597,7 +597,7 @@ std::list *add_nt_calls(std::list &stmts, } } - if ((mode == CYKmode::OPENMP_PARALLEL) && contains_nested_for) { + if (((mode == CYKmode::OPENMP_PARALLEL) || (mode == CYKmode::SINGLETHREAD_OUTSIDE)) && contains_nested_for) { // don't add NT calls in for loops that is not the innermost loop, if in // multi threaded mode. return new std::list(); @@ -620,10 +620,14 @@ std::list *add_nt_calls(std::list &stmts, if (!(*i)->is_tabulated()) { continue; } + if ((*i)->is_partof_outside() == (mode != CYKmode::SINGLETHREAD_OUTSIDE)) { + continue; + } std::list *args = new std::list(); size_t used_indices = 0; size_t nt_has_indices = 0; - for (size_t t = 0; t < (*i)->tracks(); ++t) { + std::vector::const_iterator it_stmt_seq = ast.seq_decls.begin(); + for (size_t t = 0; t < (*i)->tracks(); ++t, ++it_stmt_seq) { if (!(*i)->tables()[t].delete_left_index()) { Expr::Vacc *idx = (*i)->left_indices.at(t)->vacc(); if (std::find(loop_vars->begin(), loop_vars->end(), @@ -631,7 +635,15 @@ std::list *add_nt_calls(std::list &stmts, used_indices++; } nt_has_indices++; - args->push_back(idx->minus(new Expr::Const(1))); + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + // create t_X_seq.size() call + Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); + dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); + dynamic_cast(seqsize)->is_obj = Bool(true); + args->push_back(idx->minus(seqsize)->plus((*i)->right_indices.at(t)->vacc())); + } else { + args->push_back(idx->minus(new Expr::Const(1))); + } } if (!(*i)->tables()[t].delete_right_index()) { Expr::Vacc *idx = (*i)->right_indices.at(t)->vacc(); @@ -709,15 +721,23 @@ Fn_Def *print_CYK(const AST &ast) { fn_cyk->stmts.push_back(new Statement::CustomCode("#ifndef _OPENMP")); // recursively reverse iterate through tracks and create nested for loop // structures + // add NT calls to traversal structure std::list *stmts = cyk_traversal_singlethread( - ast, ast.outside_generation() ? CYKmode::SINGLETHREAD_OUTSIDE : CYKmode::SINGLETHREAD); -// // add NT calls to traversal structure -// std::list *new_stmts = add_nt_calls(*stmts, -// new std::list(), ast.grammar()->topological_ord(), -// ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD); -// stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); -// // finally add traversal structure with NT calls to function body + ast, CYKmode::SINGLETHREAD); + std::list *new_stmts = add_nt_calls(*stmts, + new std::list(), ast.grammar()->topological_ord(), + ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD, ast); + stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); + // finally add traversal structure with NT calls to function body fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); + if (ast.outside_generation()) { + stmts = cyk_traversal_singlethread(ast, CYKmode::SINGLETHREAD_OUTSIDE); + std::list *new_stmts = add_nt_calls(*stmts, + new std::list(), ast.grammar()->topological_ord(), + ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD_OUTSIDE, ast); + stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); + fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); + } // ==== multi thread version (only single-track possible for now) fn_cyk->stmts.push_back(new Statement::CustomCode("#else")); @@ -785,7 +805,7 @@ Fn_Def *print_CYK(const AST &ast) { // inject NT calls std::list *new_stmts = add_nt_calls(*stmts, new std::list(), ast.grammar()->topological_ord(), - ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_PARALLEL); + ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_PARALLEL, ast); stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); blk_parallel->statements.insert(blk_parallel->statements.end(), @@ -802,7 +822,7 @@ Fn_Def *print_CYK(const AST &ast) { // inject NT calls std::list *new_serial_stmts = add_nt_calls( *stmts, new std::list(), ast.grammar()->topological_ord(), - ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_SERIAL); + ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_SERIAL, ast); stmts->insert(stmts->end(), new_serial_stmts->begin(), new_serial_stmts->end()); fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); From afb1d3b1838e3c103bf31b4dfc32473897303eb7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Thu, 18 May 2023 21:26:31 +0200 Subject: [PATCH 124/189] clean up old Custom*e*Code use --- src/cpp.cc | 6 ------ src/outside/codegen.cc | 4 ++-- src/statement.hh | 13 ------------- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/cpp.cc b/src/cpp.cc index 24e0ebcb3..cc6e3dda2 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -555,12 +555,6 @@ void Printer::Cpp::print(const Statement::Block &stmt) { stream << indent() << "}" << endl; } -void Printer::Cpp::print(const Statement::CustomeCode &stmt) { - if (stmt.line_of_code.at(0) != '#') { - stream << indent(); - } - stream << stmt.line_of_code; -} void Printer::Cpp::print(const Statement::CustomCode &stmt) { if (stmt.line_of_code.at(0) != '#') { diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 7c96c6d88..ab6265bd2 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -182,7 +182,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { stmts = &((*loops->rbegin())->statements); } - stmts->push_back(new Statement::CustomeCode( + stmts->push_back(new Statement::CustomCode( "out << \"start answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); @@ -198,7 +198,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { // produce: out << "//end answers outside_iloop(" << t_0_i << "," // << t_0_j << ")\n"; - stmts->push_back(new Statement::CustomeCode( + stmts->push_back(new Statement::CustomCode( "out << \"//end answers " + *nt->name + "(\"" + idx_param + "\")\\n\";")); diff --git a/src/statement.hh b/src/statement.hh index 8d7b748e9..e20a432da 100644 --- a/src/statement.hh +++ b/src/statement.hh @@ -363,19 +363,6 @@ class Block : public Block_Base { Base *copy() const; }; -class CustomeCode : public Base { - /* A "CustomeCode" statement is an arbitrary line of string that get's - * injected. Handy to leave comments in the generated code or inject - * constructs otherwise impossible. Use with care! */ - public: - std::string line_of_code; - - explicit CustomeCode(std::string line_of_code) : - Base(CUSTOMECODE), line_of_code(line_of_code) { - } - - void print(Printer::Base &p) const; -}; class CustomCode : public Base { /* A "CustomCode" statement is an arbitrary line of string that get's From 20244915373919d1861f2958124f7784cae0f3e4 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 21 May 2023 17:44:59 +0200 Subject: [PATCH 125/189] do not add loops onto inself, but replace to prevent infinit loops --- src/outside/middle_end.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index ce4186c7a..6c4f307d3 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -375,9 +375,7 @@ void outside_init_indices( } if (alt->is(Alt::SIMPLE)) { - dynamic_cast(alt)->loops.insert( - dynamic_cast(alt)->loops.begin(), - loops.begin(), loops.end()); + dynamic_cast(alt)->loops = loops; } } From ebede34e8728a474c82b9919c35b78e67cbdf096 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 21 May 2023 22:26:18 +0200 Subject: [PATCH 126/189] add grammar that can parse the empty word to not fail semantic test --- testdata/grammar2/alignments_cyk.gap | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/testdata/grammar2/alignments_cyk.gap b/testdata/grammar2/alignments_cyk.gap index a31ceea83..382c09cb3 100644 --- a/testdata/grammar2/alignments_cyk.gap +++ b/testdata/grammar2/alignments_cyk.gap @@ -60,6 +60,19 @@ grammar gra_NWcyk uses sig_alignments(axiom=nt_const) { # h; } +grammar gra_NWcyk_infinitloop uses sig_alignments(axiom=nt_const) { + nt_const = nt_left | Sto() # h; + + nt_left = split(, nt_right) # h; + nt_right = splitR(A, ) # h; + + A = Ins(, , A) + | Del(, , A) + | Ers(, , A) + | Sto() + # h; +} instance count = gra_NWcyk(alg_count); instance maxM = gra_NWcyk(alg_maxMatch); +instance infloop = gra_NWcyk_infinitloop(alg_count); From 0f571f28868db353682fabca774268536eaa36fe Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 21 May 2023 22:30:12 +0200 Subject: [PATCH 127/189] 1) only add for loops, if not already in list 2) consequently pass loops as reference 3) reset table_dim_ready flag for next track --- src/alt.cc | 6 +++--- src/alt.hh | 2 +- src/grammar.cc | 10 +++++++++- src/outside/middle_end.cc | 15 +++++++++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index d2b8604a3..cd90b87d0 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1073,7 +1073,7 @@ void Alt::Simple::reset() { Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, - std::list *loops, + std::list &loops, bool for_outside_generation, bool outmost, bool is_left_not_right) { #ifdef LOOPDEBUG std::cerr << " next_index_var next_var="; @@ -1170,7 +1170,7 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Statement::Var_Decl *loopvariable = new Statement::Var_Decl( new ::Type::Size(), ivar, index.first); Statement::For *f = new Statement::For (loopvariable, cond); - loops->push_back(f); + loops.push_back(f); #ifdef LOOPDEBUG std::cerr << " --> " << *ivar << "\n"; @@ -1216,7 +1216,7 @@ void Alt::Simple::init_indices( next_var = next_index_var( k, track, next_var, last_var, right, ys, lhs, rhs, - &this->loops, false, false, false); + this->loops, false, false, false); std::pair res(0, 0); if (lhs.low() == lhs.high()) { diff --git a/src/alt.hh b/src/alt.hh index 56c2d8cb6..6fd1ead6d 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -72,7 +72,7 @@ Expr::Base *next_index_var( unsigned &k, size_t track, Expr::Base *next_var, Expr::Base *last_var, Expr::Base *right, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, - std::list *loops, + std::list &loops, bool for_outside_generation, bool outmost, bool is_left_not_right); class Base { diff --git a/src/grammar.cc b/src/grammar.cc index 389e68433..56536bf4b 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -371,8 +371,13 @@ void Grammar::init_table_dims() { std::vector temp_rs(nt_list.size()); axiom->init_table_dim(l, r, temp_ls, temp_rs, track); - } + // clear table dim ready flag for next track + for (std::list::iterator nt = this->nt_list.begin(); + nt != this->nt_list.end(); ++nt) { + (*nt)->reset_table_dim(); + } + } #ifndef NDEBUG for (std::list::iterator i = nt_list.begin(); @@ -878,6 +883,9 @@ struct Clear_Loops : public Visitor { void Grammar::init_indices() { Clear_Loops cl; traverse(cl); + + assert(this->left_running_indices.size() == 0); + assert(this->right_running_indices.size() == 0); for (size_t track = 0; track < axiom->tracks(); ++track) { // variable access for all possible boundaries std::ostringstream i, j, lm, rm; diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 6c4f307d3..01d45c7c3 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -213,7 +213,7 @@ void iterate_indices(bool is_left_not_right, #endif next_var = Alt::next_index_var( k, track, next_var, last_var, upstream_index, - ys, lhs, rhs, &((*i)->simple_loops), true, false, is_left_not_right); + ys, lhs, rhs, (*i)->simple_loops, true, false, is_left_not_right); // copy and paste from Alt::Simple::init_indices std::pair res(0, 0); @@ -328,7 +328,7 @@ void outside_init_indices( ys.set(0, 0); Expr::Base *next_var = Alt::next_index_var(k, track, left, left_most, left, ys, ys_lhs, ys_all, - &loops, true, true, true); + loops, true, true, true); Expr::Base *last_var = next_var; iterate_indices(true, &left_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, left, ys_all); @@ -343,7 +343,7 @@ void outside_init_indices( right_parser.begin(), track); last_var = Alt::next_index_var(k, track, right, right_most, right, ys, ys_all, ys_rhs, - &loops, true, true, false); + loops, true, true, false); iterate_indices(false, &right_parser, k, track, alt->multi_ys().tracks(), next_var, last_var, right, ys_all); } @@ -375,7 +375,14 @@ void outside_init_indices( } if (alt->is(Alt::SIMPLE)) { - dynamic_cast(alt)->loops = loops; + Alt::Simple *asimple = dynamic_cast(alt); + for (std::list::iterator i = asimple->loops.begin(); i != asimple->loops.end(); ++i) { + // only add those loops, not already on the list + if (std::find(loops.begin(), loops.end(), *i) == loops.end()) { + loops.push_back(*i); + } + } + asimple->loops = loops; } } From c34f2c098b01ef29793b95429b009baaec790dec Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 21 May 2023 22:33:00 +0200 Subject: [PATCH 128/189] add test for which gapc was stuck in an infinit loop, because loop variables where added multiple times and nesting led to infinetly nested loops --- testdata/regresstest/config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index f92010f83..ae421d516 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -541,7 +541,7 @@ check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaC # same as above, but with CYK code generation GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" -check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +#check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside @@ -600,4 +600,8 @@ GAPC="../../../gapc --outside_grammar a_1 --outside_grammar a_47 --outside_gramm # not yet explored check_new_old_eq acmsearch_RF00005.gap unused inside "GACGGUAU" outside_acm +GRAMMAR=../../grammar2 +GAPC="../../../gapc --outside_grammar ALL " +check_new_old_eq_twotrack alignments_cyk.gap unused infloop "ff" outside_infloop "z" + CPPFLAGS_EXTRA="" From eaf58e17b3aad448790f1802cd456bc99e8a473f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 21 May 2023 22:42:14 +0200 Subject: [PATCH 129/189] use different branch of gapc-test-suite --- .github/workflows/c-cpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 87735400c..e2cdef5cf 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -31,7 +31,7 @@ jobs: run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip - name: Checkout truth - run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch outside_fix_infloop https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure @@ -79,7 +79,7 @@ jobs: - name: add random Haskell lib run: cabal install --lib random - name: Checkout truth - run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch outside_fix_infloop https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure From eab1eab946fedb7d0c870ed8b1d0f1e583767e15 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 22 May 2023 08:38:00 +0200 Subject: [PATCH 130/189] fix pointer access --- src/cyk.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index cb4333630..b7823f30b 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -429,7 +429,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, CYKloop row = get_for_row(ast.grammar()->left_running_indices[track], row_start, z, with_checkpoint, CYKmode::OPENMP_PARALLEL); CYKloop col = get_for_column(ast.grammar()->right_running_indices[track], - z, z->plus(new Expr::Vacc(*tile_size)), with_checkpoint, + z, z->plus(new Expr::Vacc(tile_size)), with_checkpoint, CYKmode::OPENMP_PARALLEL); col.loop->statements.push_back(row.loop); Expr::Base *start_z = new Expr::Const(0); @@ -465,7 +465,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, (new Expr::Vacc(*x))->minus(new Expr::Vacc(tile_size)), with_checkpoint, CYKmode::OPENMP_PARALLEL); CYKloop colB = get_for_column(ast.grammar()->right_running_indices[track], - y, y->plus(new Expr::Vacc(*tile_size)), with_checkpoint, + y, y->plus(new Expr::Vacc(tile_size)), with_checkpoint, CYKmode::OPENMP_PARALLEL); colB.loop->statements.push_back(rowB.loop); From 10b8480b75edaf7cbb51b591a9c251900bfcfc97 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 22 May 2023 08:38:47 +0200 Subject: [PATCH 131/189] no CYK available yet --- testdata/regresstest/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index f92010f83..aee3aa6ac 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -541,7 +541,7 @@ check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaC # same as above, but with CYK code generation GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" -check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +#check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside From d1ed712ab5db5a91ccd8686dd6e04385e49d48ed Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 22 May 2023 08:40:07 +0200 Subject: [PATCH 132/189] Update c-cpp.yml --- .github/workflows/c-cpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 87735400c..c69b46932 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -4,7 +4,7 @@ on: push: branches: [ master ] pull_request: - branches: [ master ] + branches: [ master, outside ] workflow_dispatch: inputs: logLevel: From 448099b28b6a607196d47f6c20a37e4b27498bd5 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 22 May 2023 08:46:23 +0200 Subject: [PATCH 133/189] linting --- src/outside/middle_end.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 01d45c7c3..c7a12acab 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -376,7 +376,8 @@ void outside_init_indices( if (alt->is(Alt::SIMPLE)) { Alt::Simple *asimple = dynamic_cast(alt); - for (std::list::iterator i = asimple->loops.begin(); i != asimple->loops.end(); ++i) { + for (std::list::iterator i = asimple->loops.begin(); + i != asimple->loops.end(); ++i) { // only add those loops, not already on the list if (std::find(loops.begin(), loops.end(), *i) == loops.end()) { loops.push_back(*i); From aa181804483ffa7fc54bf095f8253d9e5eefcd09 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 12:14:31 +0200 Subject: [PATCH 134/189] passing iterators to sum_ys() led to wrong results only on OSx (ubuntu worked fine). I changed the logic such we now only pass the start element position, i.e. size_t instead of iterators --- src/outside/middle_end.cc | 45 ++++++++++++++++++++++----------------- src/outside/middle_end.hh | 3 +-- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index ce4186c7a..45063d7cf 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -120,16 +120,25 @@ void Fn_Arg::Alt::outside_collect_parsers( } Yield::Size sum_ys(std::vector parser, - std::vector::iterator itr_start, - std::vector::iterator itr_end, + size_t pos_start, size_t track) { Yield::Size ys; // don't risk undefined yield sizes! ys.set(0, 0); - for (std::vector::iterator i = itr_start; - (i != parser.end()) && (i != itr_end); ++i) { - ys += (*i)->yield_size; + if (parser.size() <= 0) { + return ys; + } + + std::vector::iterator x = parser.begin(); + size_t pos = 0; + // skip first pos_start elements=parser + for (; (x != parser.end()) && (pos < pos_start); ++x, ++pos) { + } + + // start adding yield size of elements=parser + for (; x != parser.end(); ++x) { + ys += (*x)->yield_size; } return ys; @@ -201,10 +210,11 @@ void iterate_indices(bool is_left_not_right, Yield::Size ys_all) { Yield::Size lhs; lhs.set(0, 0); + size_t pos = 0; for (std::vector::iterator i = parser->begin(); - i != parser->end(); ++i) { + i != parser->end(); ++i, ++pos) { Yield::Size ys = (*i)->yield_size; - Yield::Size rhs = sum_ys(*parser, std::next(i), parser->end(), track); + Yield::Size rhs = sum_ys(*parser, pos+1, track); Yield::Size rhs_ys(rhs); rhs_ys += ys; @@ -317,13 +327,12 @@ void outside_init_indices( // phase 2: based on the collected Parsers, assign left and right indices // to Parsers for grammar components LEFT of outside NT - Yield::Size ys_all = sum_ys(left_parser, left_parser.begin(), - left_parser.end(), track); + Yield::Size ys_all = sum_ys(left_parser, 0, track); #ifdef LOOPDEBUG std::cerr << "1) "; #endif - Yield::Size ys_lhs = sum_ys(left_parser, left_parser.begin(), - left_parser.begin(), track); + // +99 to ensure that we skip ALL elements of the left_parser list + Yield::Size ys_lhs = sum_ys(left_parser, left_parser.size()+99, track); Yield::Size ys; ys.set(0, 0); Expr::Base *next_var = Alt::next_index_var(k, track, left, left_most, left, @@ -334,13 +343,13 @@ void outside_init_indices( next_var, last_var, left, ys_all); // for grammar components RIGHT of outside NT if (right_parser.size() > 0) { - ys_all = sum_ys(right_parser, right_parser.begin(), right_parser.end(), - track); + ys_all = sum_ys(right_parser, 0, track); #ifdef LOOPDEBUG std::cerr << "3) "; #endif - Yield::Size ys_rhs = sum_ys(right_parser, right_parser.begin(), - right_parser.begin(), track); + // +99 to ensure that we skip ALL elements of the right_parser list + Yield::Size ys_rhs = sum_ys(right_parser, right_parser.size() + 99, track); + last_var = Alt::next_index_var(k, track, right, right_most, right, ys, ys_all, ys_rhs, &loops, true, true, false); @@ -420,8 +429,7 @@ void Alt::Simple::init_outside_guards() { new Expr::Greater_Eq( v.outside_link->nt->left_indices[track], v.outside_link->nt->left_most_indices[track]->plus( - sum_ys(left_parser, left_parser.begin(), - left_parser.end(), track).low()))); + sum_ys(left_parser, 0, track).low()))); } } if (!this->outside_lhsNT->tables()[track].delete_right_index()) { @@ -431,8 +439,7 @@ void Alt::Simple::init_outside_guards() { l.push_back( new Expr::Less_Eq( v.outside_link->nt->right_indices[track]->plus( - sum_ys(right_parser, right_parser.begin(), - right_parser.end(), track).low()), + sum_ys(right_parser, 0, track).low()), v.outside_link->nt->right_most_indices[track])); } } diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 7fe60bc3a..23732ed40 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -60,8 +60,7 @@ void outside_init_indices( Expr::Vacc *left_most, Expr::Vacc *right_most); Yield::Size sum_ys(std::vector parser, - std::vector::iterator itr_start, - std::vector::iterator itr_end, + size_t pos_start, size_t track); struct GetOutsideLink : public Visitor { From 55689dd36275825b1b7f69a4c7acc9b4ade4e56b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 12:31:15 +0200 Subject: [PATCH 135/189] there was no use of the passed track argument -> removed --- src/outside/middle_end.cc | 18 ++++++++---------- src/outside/middle_end.hh | 3 +-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 45063d7cf..5903efe43 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -119,9 +119,7 @@ void Fn_Arg::Alt::outside_collect_parsers( track, simple_loops); } -Yield::Size sum_ys(std::vector parser, - size_t pos_start, - size_t track) { +Yield::Size sum_ys(std::vector parser, size_t pos_start) { Yield::Size ys; // don't risk undefined yield sizes! ys.set(0, 0); @@ -214,7 +212,7 @@ void iterate_indices(bool is_left_not_right, for (std::vector::iterator i = parser->begin(); i != parser->end(); ++i, ++pos) { Yield::Size ys = (*i)->yield_size; - Yield::Size rhs = sum_ys(*parser, pos+1, track); + Yield::Size rhs = sum_ys(*parser, pos+1); Yield::Size rhs_ys(rhs); rhs_ys += ys; @@ -327,12 +325,12 @@ void outside_init_indices( // phase 2: based on the collected Parsers, assign left and right indices // to Parsers for grammar components LEFT of outside NT - Yield::Size ys_all = sum_ys(left_parser, 0, track); + Yield::Size ys_all = sum_ys(left_parser, 0); #ifdef LOOPDEBUG std::cerr << "1) "; #endif // +99 to ensure that we skip ALL elements of the left_parser list - Yield::Size ys_lhs = sum_ys(left_parser, left_parser.size()+99, track); + Yield::Size ys_lhs = sum_ys(left_parser, left_parser.size()+99); Yield::Size ys; ys.set(0, 0); Expr::Base *next_var = Alt::next_index_var(k, track, left, left_most, left, @@ -343,12 +341,12 @@ void outside_init_indices( next_var, last_var, left, ys_all); // for grammar components RIGHT of outside NT if (right_parser.size() > 0) { - ys_all = sum_ys(right_parser, 0, track); + ys_all = sum_ys(right_parser, 0); #ifdef LOOPDEBUG std::cerr << "3) "; #endif // +99 to ensure that we skip ALL elements of the right_parser list - Yield::Size ys_rhs = sum_ys(right_parser, right_parser.size() + 99, track); + Yield::Size ys_rhs = sum_ys(right_parser, right_parser.size() + 99); last_var = Alt::next_index_var(k, track, right, right_most, right, ys, ys_all, ys_rhs, @@ -429,7 +427,7 @@ void Alt::Simple::init_outside_guards() { new Expr::Greater_Eq( v.outside_link->nt->left_indices[track], v.outside_link->nt->left_most_indices[track]->plus( - sum_ys(left_parser, 0, track).low()))); + sum_ys(left_parser, 0).low()))); } } if (!this->outside_lhsNT->tables()[track].delete_right_index()) { @@ -439,7 +437,7 @@ void Alt::Simple::init_outside_guards() { l.push_back( new Expr::Less_Eq( v.outside_link->nt->right_indices[track]->plus( - sum_ys(right_parser, 0, track).low()), + sum_ys(right_parser, 0).low()), v.outside_link->nt->right_most_indices[track])); } } diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh index 23732ed40..938751a6e 100644 --- a/src/outside/middle_end.hh +++ b/src/outside/middle_end.hh @@ -60,8 +60,7 @@ void outside_init_indices( Expr::Vacc *left_most, Expr::Vacc *right_most); Yield::Size sum_ys(std::vector parser, - size_t pos_start, - size_t track); + size_t pos_start); struct GetOutsideLink : public Visitor { Alt::Link *outside_link = nullptr; From 90e96a1ee7ecc1c6bac43975b00c83aed5b58b58 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 13:21:45 +0200 Subject: [PATCH 136/189] get old tests back in --- testdata/regresstest/config | 472 ++++++++++++++++++++++++++++++++++++ 1 file changed, 472 insertions(+) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index 2f26d3f40..ae421d516 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -3,7 +3,479 @@ DEFAULT_LDLIBS_EXTRA=$LDLIBS_EXTRA DEFAULT_CPPFLAGS_EXTRA=$CPPFLAGS_EXTRA DEFAULT_GAPC=$GAPC +check_new_old_eq elm.gap unused enum 1+2*3*4+5 foo +check_new_old_eq loco3stem.gap unused count caucguacgucagucguagucaguugcagugcaucgacua foo + +check_new_old_eq loco3stem.gap unused count gggcguucucauagguccgcguggguuagacauucaagguuauuuuuuauccggaguuaccucaucuaauugauagauuaagaaauucuuuuguucgaauaaggcgcaguuauuuacccuuuugauuccuaaaaacuuuccgccgccgucaagaugacaaauaacaaacuugccaaggcggcauccguuuuuagauaauu bar + +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq rnashapes2wip.gap unused mfepp gcgcggugcgucacgcaucacauacucaucaacgaugagaagc foo + +check_new_old_eq rnashapespf.gap unused pf GGAGAGAUGGCUGAGUGGUUGAUAGCUCCGGUCUUGAAAACCGGUAUAGUUCUAGGAACUAUCGAGGGUUCGAAUCCCUCUCUCUCCUGGAGAGAUGGCUGAGUGGUUGAUAGCUCCGGUCUUGAAAACCGGUAUAGUUCUAGGAACUAUCGAGGGUUCGAAUCCCUCUCUCUCCU pf + +RUN_CPP_FLAGS="" + +check_new_old_eq cmsmallint.gap unused enum a foo + +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq adpf.gap unused shapemfepp acgugucagucagucauggucaucauacugccgua foo + +CPPFLAGS_EXTRA+="-DSTATS" + +# FIXME, with optimized classify, the stat-ing of one hash-table is of no use +# ugucgcccgaccuguaaucgauuguuauuuccaggcucgagggcaagucuugaaaggacuaccuugucgaaguggacagugcagcgauugacggauucagucggggcauauugugcauaaugucagc +#check_feature adpf.gap shape5 ugucgcccgaccuguaaucgauuguuauuuccaggcucgagggcaagucuugaaaggacuaccuugucgaaguggacagug foo err grep "Hi water use: 428785\>" + +CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA + +GAPC="../../../gapc -t --window-mode" + +RUN_CPP_FLAGS="-w 20 -i 5" + +check_new_old_eq adpf.gap unused bpmaxpp auagacguguaauuauugaggaacaggcaucgaucauaauaggguaucagggauacaugaauaggcuuagcgucaguuguuggcuauuccaucaucggguacaauuccauacuucgcaugggaucaaccaagcucuaguggccgccuaug foo + +RUN_CPP_FLAGS="-w 23 -i 8" + +check_new_old_eq adpf.gap unused bpmaxpp auagacguguaauuauugaggaacaggcaucgaucauaauaggguaucagggauacaugaauaggcuuagcgucaguuguuggcuauuccaucaucggguacaauuccauacuucgcaugggaucaaccaagcucuaguggccgccuaug bar + +RUN_CPP_FLAGS="-w 100 -i 50 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq adpf.gap unused mfepp cuccccucuucggacgcaacuuaugccuaggaccuauuuugcacagaaugagggcuagggaagagccgucccucagugagcagaguuaaguuguuguuugaguaacucccggcgggcuaagccauugcacccaaccgcuugccugucauucuggaccgggauggaaccguaccucugcacuuaagacagacuaucaaaagcguauggcggguuguggucucaagugggaggacaaucaccguauauuugaucaacgauucagggaugcucacccguuucuuauuugaaacuuggcacccggaauauucugaagccaauacaguuugugacacaaccccgucaguugagacucuuuuaacgccgugugccgacgaaucuccccacgguaugcgcuggucggucccacgagggcguauaucgccaaggcagcuuaugguaacgucgcauaccagcucaagccgguugaaauaacagguccaguuuguaggucucuucugugacguaggccugcagcaagaacugcgcaugcuugucguagaggccaauagagcugaucuggcaaucguaaagguaguguuuagguagcuucauguauucaucuuucgucaucgcaagcuaaacuugcgcucaucacuauggcgucaucugaggucguugcgagaaagaugcuagguugcgcgcauaacgacuuuaagcguuagauuccgccucucaucgggccagcgaaagacccauacgcaaacgcgcuaucgcaguaauggaauaauuggcaguacucaucgccggcgucgcuauguucuaugcucacgcucucuccaggcggcggauggucccugccagcgcucgagaggcauccaaguuggaacuauauccuaugaaucacaaugccggucacuucgcgggcuaauaaguuccucaggggaccaggacgugauuuuccgugcagggggggccggucacacgcaggagguuugggcuagcacaagcccaacaaccacau foo + +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-f" + +check_new_old_eq adpf.gap unused shape5 "../../input/rna127" bar + +RUN_CPP_FLAGS="" +CPPFLAGS_EXTRA+=" -DUSE_GMP_INT" +# under Linux -lgmpxx pulls automatically -lgmp, Solaris does not +LDLIBS_EXTRA+=" -lgmp -lgmpxx" + +check_new_old_eq elm.gap unused acount '1+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+11+2*3*4+5*3*2*2*3*1+1+3+1' foo + +CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA +LDLIBS_EXTRA=$DEFAULT_LDLIBS_EXTRA + +# Jens subopt old adpc bug report 1 + +GAPC="../../../gapc -t --subopt" + +# 30 % +RUN_CPP_FLAGS="-d 552 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq rnashapesmfe.gap unused mfepp ugcuagucagcuaucgacucgugcagcaguacgaucagcauagcuagcacuacgcua subopt30 + +# 31 % +GAPC="../../../gapc -t --cyk --subopt" +RUN_CPP_FLAGS="-d 570 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq rnashapesmfe.gap unused mfepp ugcuagucagcuaucgacucgugcagcaguacgaucagcauagcuagcacuacgcua subopt31 + +# Jens subopt old adpc bug report 2 (prob sum > 1.0) + +GAPC="../../../gapc -t --subopt" +RUN_CPP_FLAGS="-d 1090 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq adpf_nonamb.gap unused mfepppf CCacaccaacacacCuGuCACGGGAGAGAAuGuGGGuuCAAAuCCCAuCGGuCGCGCCA subopt + +check_feature adpf_nonamb.gap mfepppf CCacaccaacacacCuGuCACGGGAGAGAAuGuGGGuuCAAAuCCCAuCGGuCGCGCCA suboptpfsum out $KSH ../check_prob_sum 9.33773 + +# + +# another Jens subopt RNAshapes -r -s Probability sum > 1.0 bug +# mail from Date: Fri, 13 Feb 2009 11:16:32 + +RUN_CPP_FLAGS="-d 224 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_feature adpf_nonamb.gap mfepppf UCACCGUCGGAAAGUGUGCGCUUUCCCUGAUGAGCCCAAAAGGGCGAAACGGUAC suboptpfsum2 out $KSH ../check_prob_sum 5.06405e+08 + +# + +GAPC="../../../gapc -t" + +check_new_old_eq adpf_nonamb.gap unused shape5pf CCacaccaacacacCuGuCACGGGAGAGAAuGuGGGuuCAAAuCCCAuCGGuCGCGCCA shapesubopt + +GAPC="../../../gapc --tab-all" +RUN_CPP_FLAGS="-f" + +# FIXME remove - obsoleted by external test case, which is more robust +#check_new_old_eq adpf_nonamb.gap unused shape5pfx ../../input/rna150 shapefpffilter + + +#GSL_RNG_SEED=`../rand 1` +#export GSL_RNG_SEED + +RUN_CPP_FLAGS="-r 1000 -P ../../../librna/paramfiles/rna_turner1999.par -f" +GAPC="../../../gapc -t --sample" + +check_feature adpf.gap pfsampleshape ../../input/rna100 sample out $KSH ../check_samples ../adpf.rna100shapepf 0.000349275 0.00005 + + +# Sequence from Jens RNAshapes sampling mode bug report + +RUN_CPP_FLAGS="-r 1000 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_feature adpf_nonamb.gap pfsampleshape AGAGAACAUGAGAGAGAUUCCCAACAGAGGCCUGCACGCACUUGGACUCU sample out $KSH ../check_samples ../nonamb_shape_pf.log 6.33459e-05 0.00005 + +# Sequence from Jens RNAshapes sampling mode bug report, distribution test + +RUN_CPP_FLAGS="-r 1000 -P ../../../librna/paramfiles/rna_turner1999.par" + +check_feature_repeat_mean_var adpf_nonamb.gap pfsampleshape AGAGAACAUGAGAGAGAUUCCCAACAGAGGCCUGCACGCACUUGGACUCU sample2 + +# Too much sample output bug ( see a9fed4287fda and 980a3871b4a7 ) +GAPC="../../../gapc -t --sample --cyk" +RUN_CPP_FLAGS="-r 1 -P ../../../librna/paramfiles/rna_turner1999.par -f" +check_feature adpf_nonamb.gap pfsampleshapeall ../../input/rna400 samplecount out $KSH ../check_sample_count + +RUN_CPP_FLAGS="-f" +GAPC="../../../gapc -t" + +check_new_old_eq nussinov.gap unused bpmax1pp ../../input/rna150 takeone + +CPPFLAGS_EXTRA+=" -DUSE_GMP_INT" +LDLIBS_EXTRA+=" -lgmp -lgmpxx" + +check_new_old_eq adpf.gap unused cart ../../input/rna150 cartesian + +GAPC="../../../gapc -t --backtrack" + +check_new_old_eq adpf.gap unused cartpp2 ../../input/rna20 cartesian2 + +CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA +LDLIBS_EXTRA=$DEFAULT_LDLIBS_EXTRA + +RUN_CPP_FLAGS="-f" +GAPC="../../../gapc -t --backtrack" + +check_new_old_eq nussinov.gap unused bpmax1pp ../../input/rna150 takeonebt + +GAPC="../../../gapc -t --kbacktrack" +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq adpf_nonamb.gap unused shapemfepf acgccucuucgaaguucaggauuugaccgccgcaugcgaacucggauuacgaaacauuuc kbt + +# FIXME remove - obsoleted by external test case, which is more robust +#check_new_old_eq adpf_nonamb.gap unused shapemfepfx acgccucuucgaaguucaggauuugaccgccgcaugcgaacucggauuacgaaacauuuc kbtpfx + +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par -f" +GAPC="../../../gapc -t --cyk --kbacktrack" + +check_new_old_eq helene.gap unused mfepp ../../input/rna100 rope + + +check_external extpfx ../check_shape_filter_old_new "../../test/shapemfepfx/main -w 2 -i 1 -P ../../../librna/paramfiles/rna_turner1999.par" $REF/shapemfepfx.150.log 0.000001 0.000001 2 `cat ../../input/rna150` + +check_external extsample ../check_shape_filter "../../test/shrepmfesample/main -r 2000 -P ../../../librna/paramfiles/rna_turner1999.par" $REF/shrepmfesample.2000.150.log 0.0002 0.0002 1 `cat ../../input/rna150` + + +check_external extpfxwindow ../../test/shapemfepfx/test.pl ../../test/shapemfepfx/main ../../test/shapemfepfx/nowindow `cat ../../input/rna100` + + +#RUN_CPP_FLAGS="-x -300 -f" +# thresh of 0 +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par -f" +GAPC="../../../gapc -t --kbacktrack --cyk" + +check_new_old_eq adpf_hl.gap unused mfepp ../../input/rna200 suchthat + + +GAPC="../../../gapc -t --cyk --subopt-classify --kbacktrack" +RUN_CPP_FLAGS="-d 0 -P ../../../librna/paramfiles/rna_turner1999.par -f" + +check_new_old_eq adpf.gap unused shapemfepp ../../input/rna80 subshape + +RUN_CPP_FLAGS="-d 50 -P ../../../librna/paramfiles/rna_turner1999.par -f" +check_new_old_eq adpf.gap unused shapemfepp ../../input/rna80 subshape2 + +RUN_CPP_FLAGS="-d 100 -P ../../../librna/paramfiles/rna_turner1999.par -f" +check_new_old_eq adpf.gap unused shapemfepp ../../input/rna80 subshape3 + +RUN_CPP_FLAGS="-d 429 -P ../../../librna/paramfiles/rna_turner1999.par -f" +check_new_old_eq adpf.gap unused shapemfepp ../../input/rna20 subshape4 + +RUN_CPP_FLAGS="-d 430 -P ../../../librna/paramfiles/rna_turner1999.par -f" +check_new_old_eq adpf.gap unused shapemfepp ../../input/rna20 subshape5 + +RUN_CPP_FLAGS="-d 100 -P ../../../librna/paramfiles/rna_turner1999.par -f" +check_new_old_eq adpf_nonamb.gap unused shapemfepp ../../input/rna80 subshape8 + +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par -f" +GAPC="../../../gapc -t --cyk --kbacktrack" +check_new_old_eq adpf.gap unused shapemfeppcl ../../input/rna20 subshape6 + +check_new_old_eq adpf.gap unused shapemfeppshcl ../../input/rna20 subshape7 + +RUN_CPP_FLAGS="" + + +# FIXME tab heuristic (-t) is not optimal for this grammar +GAPC="../../../gapc --tab-all" +check_new_old_eq structure2shape.gap unused shape5 '..(((...((......))...(((.....)))....)))..' structure + + +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-f" +check_new_old_eq flowgram.gap unused foo ../../input/flow flow + +RUN_CPP_FLAGS="-w 20 -i 5 -P ../../../librna/paramfiles/rna_turner1999.par -f" +GAPC="../../../gapc -t --backtrack --window-mode" +check_new_old_eq adpf.gap unused mfepp ../../input/rna80 windowbacktrack + +RUN_CPP_FLAGS="-w 20 -i 1 -P ../../../librna/paramfiles/rna_turner1999.par -f" +GAPC="../../../gapc -t --kbacktrack --no-coopt --window-mode" +check_new_old_eq adpf.gap unused mfepp ../../input/rna80 windowkbacktrack + +RUN_CPP_FLAGS="" +GAPC="../../../gapc -t" +check_new_old_eq g3pl.gap unused shapeprobls acgucguagucagucaacguacgucagu classlogspace + +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-f" +check_new_old_eq flowgram2b.gap unused score ../../input/flow.2 multitrack.flow + +GAPC="../../../gapc -t --cyk --kbacktrack" +check_new_old_eq flowgram2b.gap unused foo ../../input/flow.2 multitrack.flow + + +# multiple singleton {} blocks in grammar (see nt_stem) + +RUN_CPP_FLAGS="" +GAPC="../../../gapc -t" + +check_new_old_eq single_block.gap unused count CCAAAGG block + +check_new_old_eq elm.gap unused enumenum '1+2*3' prodcopy + +check_new_old_eq optimalMCM.gap unused minmemminmult '[3x4]*[4x3]' extends + + +# test case for multiple classifying choice fns -> classify optimization +# minimal example for part of the pknotsRG multi choice fns classify bug +check_new_old_eq mchoice.gap unused shape 'gattaca' multiplechoiceclass + +# FIXME add pknotsRG shape5 + +GAPC="../../../gapc -t --cyk --kbacktrack" +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq pknotsRG.gap unused mfepp 'acgucgaaauaaaugccuugucugcuauauucgacgcgagcuuaauauuuggggcc' index + + +GAPC="../../../gapc -t " + +check_new_old_eq tdm2hp.gap unused pretty aaacccggggaauuccuu tabledim +check_new_old_eq tdm2hporig.gap unused pf gaauacccacggaugguagauuucgcuuuugggugaacuugccacgcccccgacggucgcgagcuuaucugcuauaccccaauugagaauacagggaacuu tabledim + + +GAPC="../../../gapc -t --kbacktrace --no-coopt" +RUN_CPP_FLAGS="" + +check_new_old_eq nussinov2.gap unused bpmaxpp caguagucagcu nocooptkbt + +GAPC="../../../gapc -t --kbacktrace " +RUN_CPP_FLAGS=" gggaaaaccc " + +check_new_old_eq multfilter.gap unused bpmaxpp aggaaaacca multitrack.filter + +GAPC="../../../gapc -t " +RUN_CPP_FLAGS=" cagu " + +check_new_old_eq aliglob2.gap unused enum cag multitrack.enum + + +RUN_CPP_FLAGS="" + +check_compiler_output ../../grammar2 elmnoterm.gap buyer compile grep "Function char is not defined" + +GAPC="../../../gapc -t " +RUN_CPP_FLAGS="" +GRAMMAR=../../grammar2 + +check_new_old_eq multigrammar.gap unused seller '1+2*3*4+5' multigrammar + +check_new_old_eq ochoice.gap unused buyer '1+2*3*4+5' optchoice + + +GAPC="../../../gapc --tab-all " +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" +GRAMMAR=../../grammar2 + +check_new_old_eq p7.gap unused mfe 'gagacugcagucc' tablegen +check_new_old_eq p72.gap unused mfe 'gagacugcagucc' tablegen + +GAPC="../../../gapc --tab-all --cyk --kbacktrace" +GRAMMAR=../../grammar2 +RUN_CPP_FLAGS="" + +check_new_old_eq rf01380.gap unused cykpp 'AGUCA' tablegen.rightlin + +GAPC="../../../gapc -t --kbest" +RUN_CPP_FLAGS="-k 5 -P ../../../librna/paramfiles/rna_turner1999.par -f" +GRAMMAR=../../grammar + +check_new_old_eq adpf.gap unused shapemfe ../../input/rna200 kbest + + +GAPC="../../../gapc --tab-all" +RUN_CPP_FLAGS="AA " +GRAMMAR=../../grammar2 +check_new_old_eq menum.gap unused enumi "AA" multi.enum + + +RUN_CPP_FLAGS="" +GAPC="../../../gapc -t " +GRAMMAR=../../grammar2 + +check_compiler_output ../../grammar2 ttcounterr.gap test compile.multi grep "does not match" + +GRAMMAR=../../grammar +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" + +check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG mfe1.t1999 +check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG mfe2.t1999 +check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC mfe3.t1999 + +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner2004.par" + +check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG mfe1.t2004 +check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG mfe2.t2004 +check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC mfe3.t2004 + + +RUN_CPP_FLAGS="-t 50.742 -P ../../../librna/paramfiles/rna_turner1999.par" + +GAPC="../../../gapc -t" + +check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG temp50.mfe1.t1999 +check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG temp50.mfe2.t1999 +check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC temp50.mfe3.t1999 + +GAPC="../../../gapc -t" +RUN_CPP_FLAGS="-t 50.742 -P ../../../librna/paramfiles/rna_turner2004.par" + +check_new_old_eq adpf.gap unused mfepp UUGCGCCGAUGGUUUGAGCAGCAACGCGAUCUACUUUCCAUCAGGAUAAACGUUGACUUUUAGUAAGAAACACAGCCUCAGCUAGGCUGCCCUUAUAGUUCAACG temp50.mfe1.t2004 +check_new_old_eq adpf.gap unused mfepp CCCUGAUACCCUCAUGCCUCGUGG temp50.mfe2.t2004 +check_new_old_eq adpf.gap unused mfepp GGCGAGCGAGCCCCGGGCGGACGCGCGCCCGAAACGGGCGCGCGCCGCCCGGAAAGGCACGCCGCC temp50.mfe3.t2004 + +RUN_CPP_FLAGS="-f" +GRAMMAR=../../grammar2 +GAPC="../../../gapc -t" + +check_new_old_eq escape.gap unused acount ../../input/esc esc + +RUN_CPP_FLAGS="c" +GRAMMAR=../../grammar2 +GAPC="../../../gapc -t --kbacktrace" + +# from mmoehl +check_new_old_eq interaction.gap unused bpmaxpp g multitrack.kbt + +GAPC="../../../gapc -t " +GRAMMAR=../../grammar2 +RUN_CPP_FLAGS="abc" + +check_new_old_eq mcount.gap unused cnt abc multitrack.count + +RUN_CPP_FLAGS="ac" + +check_new_old_eq trackpos.gap unused cnt dc multitrack.trackpos + +GRAMMAR=../../grammar2 +RUN_CPP_FLAGS="" + +check_new_old_eq overlay.gap unused count '1+2*3*4*5' overlay + +GAPC="../../../gapc -t --kbacktrace" +RUN_CPP_FLAGS="-P ../../../librna/paramfiles/rna_turner1999.par" +check_new_old_eq backtraceminys.gap unused mfepre a kbt + +GAPC="../../../gapc -t --cyk" +RUN_CPP_FLAGS="" + +GRAMMAR=../../grammar2 + +check_new_old_eq adpfiupac.gap unused mfepp agcugucaugcagucguagucaguca iupac + +GRAMMAR=../../grammar2 +check_new_old_eq locomotif.gap unused pretty acugacugaacuguacguugaugac foo + +#test for new functions to rope: "front", "back" and "tail". For MacOSx the shape datatype has problems with hashing, thus we need a rope version for the shape algebras, but that rope first has to implement the aforementioned functions. +GRAMMAR=../../grammar +GAPC="../../../gapc" +check_new_old_eq macrostate.gap unused shape1count acuguagucugagucacguuaucuggucguaucgaucgaucgaucacuguaguc shape_t +check_new_old_eq macrostate.gap unused shape1ropecount acuguagucugagucacguuaucuggucguaucgaucgaucgaucacuguaguc rope + +# we are here testing of seg fault due to wrongly increased Iterator in hashmap (subopt.cc) passes +# See issue #38 @ github.com/jlab/gapc +GAPC="../../../gapc --subopt" +check_new_old_eq rnashapesmfe.gap unused mfeppshape "A" foo + +#test new FLOAT terminal parser +GAPC="../../../gapc" +RUN_CPP_FLAGS="" +check_new_old_eq testfloat.gap unused enum "23" floatint +check_new_old_eq testfloat.gap unused enum "23.4" justfloat +check_new_old_eq testfloat.gap unused enum "23.45" largerfloat +check_new_old_eq testfloat.gap unused enum "23.45678" largerfloat2 +check_new_old_eq testfloat.gap unused enum "23.00000009" smallpostradix +check_new_old_eq testfloat.gap unused enum "2.345e+06" failscientific + +# test yield size analysis of const (i.e. string) terminal arguments, like ROPE("stefan") +check_compiler_output ../../grammar2 testtermarg.gap testme termarg grep "6), \"stefan" testtermarg.cc + +# fixing missing includes when changing gapc flag --float-accuracy +GRAMMAR=../../grammar +GAPC="../../../gapc --float-accuracy 2" +check_new_old_eq elm.gap unused pareto "1+2*3+4*5" floatacc + +GAPC="../../../gapc --checkpoint" +# int +check_checkpoint_eq adpf.gap unused mfe "GCUUCACAUCUCGGGCAUUUUCCUGCAAAACCAUACCCUUACGAAAAGUACGGCAUUGAUAAUCAUUUUCAAUAUCAUUUAAUUAACUAUAAUGAACCAACUGCUUACGCGGCAUUAACAAUCGGCCGCCCGACAAUACUGGAGAUGAAUAUGAGCUAUACCCUGCCAUCCCUGCCGUAUGCUUACGAUGCCCUGGAACCGCACUUCGAUAAGCAGACCAUGGAAAUCCACCACACCAAACACCAUCAGACCUACGUAAACAACGCCAACGCGGCGCUGGAAAGCCUGCCAGAAUUUGCCAACCUGCCGGUUGAAGAGCUGAUCACCAAACUGGACCAGCUGCCAGCAGACAAGAAAACCGUACUGCGCAACAACGCUGGCGGUCACGCUAACCACAGCCUGUUCUGGAAAGGUCUGAAAAAAGGCACCACCCUGCAGGGUGACCUGAAAGCGGCUAUCGAACGUGACUUCGGCUCCGUUGAUAACUUCAAAGCAGAAUUUGAAAAAGCGGCAGCUUCCCGCUUUGGUUCCGGCUGGGCAUGGCUGGUGCUGAAAGGCGAUAAACUGGCGGUGGUUUCUACUGCUAACCAGGAUUCUCCGCUGAUGGGUGAAGCUAUUUCUGGCGCUUCCGGCUUCCCGAUUAUGGGCCUGGAUGUGUGGGAACAUGCUUACUACCUGAAAUUCCAGAACCGCCGUCCGGACUACAUUAAAGAGUUCUGGAACGUGGUGAACUGGGACGAAGCAGCGGCACGUUUUGCGGCGAAAAAAUAA" checkpoint1 1 +# int +check_checkpoint_eq adpf.gap unused mfe "GUAAAAUAAACAACGCUGAUAUUAGCCGUAAACAUCGGGUUUUUUACCUCGGUAUGCCUUGUGACUGGCUUGACAAGCUUUUCCUCAGCUCCGUAAACUCCUUUCAGUGGGAAAUUGUGGGGCAAAGUGGGAAUAAGGGGUGAGGCUGGCAUGUUCCGGGGAGCAACGUUAGUCAAUCUCGACAGCAAAGGGCGCUUAUCAGUGCCUACCCGUUAUCGGGAACAGCUGCUUGAGAACGCUGCCGGUCAAAUGGUUUGCACCAUUGACAUUUAUCACCCGUGCCUGCUGCUUUACCCCCUGCCUGAAUGGGAAAUUAUCGAGCAAAAAUUAUCGCGUCUGUCGAGCAUGAACCCGGUUGAGCGCCGUGUGCAGCGCCUACUGUUAGGUCAUGCCAGCGAAUGUCAGAUGGAUGGCGCAGGUCGAUUGUUAAUCGCGCCAGUACUGCGGCAACAUGCCGGGCUGACAAAAGAAGUGAUGCUGGUUGGACAGUUCAACAAGUUUGAGCUGUGGGAUGAAACAACCUGGCAUCAACAGGUCAAGGAAGAUAUCGACGCAGAGCAGUUGGCUACCGGAGACUUAUCGGAGCGACUGCAGGACUUGUCUCUAUAAACGAUCUGACGAGCGAUCUAGCGAGCAUCGAUCUGAUCAUCUACUAUCUAUUCUAUCUAUCGGGGUGUCGACGAUCU" checkpoint2 1 +# int +check_checkpoint_eq adpf.gap unused mfe "GUUGUAGACUUUACAUCGCCAGGGGUGCUCGGCAUAAGCCGAAGAUAUCGGUAGAGUUAAUAUUGAGCAGAUCCCCCGGUGAAGGAUUUAACCGUGUUAUCUCGUUGGAGAUAUUCAUGGCGUAUUUUGGAUGAUAACGAGGCGCAAAAAAUGAAAAAGACAGCUAUCGCGAUUGCAGUGGCACUGGCUGGUUUCGCUACCGUAGCGCAGGCCGCUCCGAAAGAUAACACCUGGUACACUGGUGCUAAACUGGGCUGGUCCCAGUACCAUGACACUGGUUUCAUCAACAACAAUGGCCCGACCCAUGAAAACCAACUGGGCGCUGGUGCUUUUGGUGGUUACCAGGUUAACCCGUAUGUUGGCUUUGAAAUGGGUUACGACUGGUUAGGUCGUAUGCCGUACAAAGGCAGCGUUGAAAACGGUGCAUACAAAGCUCAGGGCGUUCAACUGACCGCUAAACUGGGUUACCCAAUCACUGACGACCUGGACAUCUACACUCGUCUGGGUGGCAUGGUAUGGCGUGCAGACACUAAAUCCAACGUUUAUGGUAAAAACCACGACACCGGCGUUUCUCCGGUCUUCGCUGGCGGUGUUGAGUACGCGAUCACUCCUGAAAUCGCUACCCGUCUGGAAUACCAGUGGACCAACAACAUCGGUGACGCACACACCAUCGGCACUCGUCCGGACAACGGCAUGCUGAGCCUGGGUGUUUCCUACCGUUUCGGUCAGGGCG" checkpoint3 1 +# List_Ref +check_checkpoint_eq adpf.gap unused mfepp "CGUAGUCGUAGUUCUGAGUCGUAGUCGUAGUCGUGUACUGAGUGCUGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCUGUGAGUCGUAGUCGUAGUCGUAGUCGUAcGUCAGCGAGUCGUAGUCGUAGUCGUAGUCGAGUAGUCAGUCUGAGCAGUCUAGUGCUGUAGUCGUAGUCGUAGUCUGCUGACGUCGUAUGCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUAGUCGUAGUCAGUCGUAGUCGUAGUCGUAGUGUC" checkpoint4 1 +# std::pair +check_checkpoint_eq adpf.gap unused mfeen "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUA" checkpoint5 1 +# Hash::Ref> +check_checkpoint_eq adpf.gap unused shape5pfx "CGAGCGUAGUCGUAGCguCGUAGCGUAGUCGUAGUCGUGCUGAGUCguaCAGUCGGAGCUAGUCGUAGUCGUAGUCGUAGCUAGUCGUCGUAGUCGUAGUCGAGUCGUACGUCGUAGCGUAGUCGUAGCUAGUGUAGCUCGUAGUCGUGUCACACCGUAUA" checkpoint6 1 +GAPC="../../../gapc --checkpoint --sample" +# double + Backtrace +check_checkpoint_eq adpf.gap unused pfsampleshape "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUACGUACGUAGUCGUAGUCGUAGUCGUAGUCGAGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUGUACGUACGUGUACGGUCGUAGUCGUAGCUguCGUAGCGUAGUCGUAGUCGUAGUCGUAGUCAGUCGUAGUGUAGUGUCGUCGUCGUAGUCGUAGUCGUAGUCAGUCGUAGUCGUAGUCGUAGUCGAUGUAGUGUCGUAGUCAGUCUGAGUCGUAGCGUAGUCGAUGUCAGUCGUAGUCGUAGUCGUAGUCGAUGCUAGUCCUGAGUCGUAGUCGUAGUCGAUCGUAGCUGAUCGUCGUAGUCGUAGUCGAGUCGACGUAGUCGUACGUAGUCGUACGUAGUCGUAGUACGUAGUGUACguCGUA" checkpoint7 1 +GAPC="../../../gapc --checkpoint --cyk" +# std::pair + cyk +check_checkpoint_eq adpf.gap unused mfepf "CGUAGCUGAUGCUGAGCGUCGUAUCUGAGUCGUGUAGUCGAUGUCGAUCGUAGUCGUGUCGAGUCGUAUGCGUAGCGUAGUCGUAGCUAGUCCGUAGCGUAGUCAGUGCUAGUGCUGCAGUGCUGAUCGUGUACGUCGAGUCGAGUCGUAGUCGUACGUAGUGCUAGUGCUAGUCGUAGUCGUGUCGUAGUCGUGAUGUCAGUGUCGUGUAGUCGUAGUCGUACGUGUACGUAGUCGUAGUCGUAUCGAGUCGCGUAGGCUAGUCGUAGUCGUAGUCGUGCGUAGCGUUGAGUCGUAGUCGAUGUCAGUCGUGUAGUCUGAGCUGAUCUGUUCGUAGCGUGUACGAGUCGUGUCGUGUAGCUGUAGUCGUAGUCAGUCAUGUAGUCGAUGCGUAGUCGUGUACGUGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUGUCGUAGCUGUAGUCGUGUAGUCGUAGUCUGAGUGUCGUAGUCGUCGUGUAGUCGUGUACGUGUAGUCGUGUAGUCGUAGUCGUAGUCGUUAUCGGAUGUCGUAGCUGUACGUGAUCGUCCGUC" checkpoint8 1 +# std::pair + cyk +check_checkpoint_eq adpf.gap unused mfeen "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUA" checkpoint9 1 +# std::pair + cyk +check_checkpoint_eq adpf.gap unused mfepp "CGAGCGGUACUGAGUCGUAGUGUAGUGCUCGUAGUCGUAGUCGUAGUCGUAGCUGAUCGUAGUAGUCGUCGUAGUCGUAGUCGUCGUAGCGUAGUCGUAGUCGUAGUCAGUCGUGUCGUGUACGUAGUCGUCAGUGCGAUCGUGUCGUAGUCGUCGUAGUCGUAGUCGAGUCAGUCGUAGUAGUGCUGAUCGUgauCGUAGCGUAGUCGAUCGUGAUGUCGUAGUCGUGUAGCUGAUGCUGUAGUCGUAUGCGUAGUCGUGUACGUGUAGCU" checkpoint10 1 +# std::pair + cyk + two track +check_checkpoint_eq affinelocsim2.gap unused affinecnt "CUGAAACGUAGUCUGAAAAGCCCGCGUAGUCGUAGUCGUAGUCGUACGUUAGCGUUGAGUCGUAGUCGUAGUUGAGUUCGGUAGUCGUAGUCGUGUACCACACAUGUGCGUAGUCGUCAGUCGUAGUCGUACGUCGUCUAGCGUGUCGUAUGCGUACGUAGUCGAGUCUGACGAGUGCGUGGGUCUGAGUCGUCGUUAGGCCAGUCGUAGUCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUU" checkpoint11 1 "CGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUCGUAGUCGUAGUCGUAGUCGUACGUCGUAUGCUGAGCAAAAAAUCGUAGUCCUGAGUCGUAGCAUGCGUACGACGUGUCCGUAGCGUACGUGUAGUACGUAGUCGAUCGUCUGAGUGUCGUAGUCGUAGUCCGUAGUCUGUAGUGUCGUACGUCGUGUAGUCGUAGCUGUAGUCGUAGUCGUAGUCGUUGCGUAGUCGUAGCGUACGUAGUGUAGUCGUCGUGUAGCGUACGUGU" +# std::pair + cyk + two track +check_checkpoint_eq affinelocsim2.gap unused affinepp "CUGUCAGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUU" checkpoint12 1 "CGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUGUACGU" +GAPC="../../../gapc" +RUN_CPP_FLAGS="" +check_new_old_eq empty_ys_issue.gap unused count "A" Ashouldbe0 +check_new_old_eq empty_ys_issue.gap unused count "AA" AAshouldbe1 +check_new_old_eq empty_ys_issue.gap unused count "AAA" AAAshouldbe0 +RUN_CPP_FLAGS=" -f emptyinput " +echo "" > emptyinput # create an input file with empty word, since '' as parameter is not correctly propagated through bash scripts +check_new_old_eq empty_ys_issue.gap unused count dummyinput shouldbe1 +check_new_old_eq empty_ys_issue_larger.gap unused count dummyinput shouldbe1 + +# ensure that previously composed answers are not erased by later application of filters for completely different alternatives, see PR https://github.com/jlab/gapc/pull/123 +GRAMMAR=../../grammar2 +GAPC="../../../gapc" RUN_CPP_FLAGS="" check_new_old_eq eraseanswers.gap unused ins_count_failing "AC" eraseanswer check_new_old_eq eraseanswers.gap unused ins_count_working "AC" eraseanswer From 67bc1c0f35a8e6730950a8fc22d0d25e5aab68e6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 17:46:21 +0200 Subject: [PATCH 137/189] extend CYK for outside by a checkpointing mechanism. We need additional _outside indices that need to be dumped and loaded. --- src/checkpoint.hh | 35 ++++++++++++++---- src/cpp.cc | 32 +++++++++++++---- src/cyk.cc | 90 ++++++++++++++++++++++++++++++++++------------- src/cyk.hh | 2 ++ 4 files changed, 121 insertions(+), 38 deletions(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 4bfaea98f..351f4dd14 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -983,7 +983,8 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", dec_indent(); dec_indent(); } - void archive_cyk_indices(Printer::Base &stream, size_t n_tracks) { + void archive_cyk_indices(Printer::Base &stream, size_t n_tracks, + bool outside) { inc_indent(); stream << indent() << "void archive_cyk_indices() {" << endl; inc_indent(); @@ -1000,9 +1001,19 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", for (size_t i = 0; i < n_tracks; i++) { // archive the indices of the prior iteration to ensure // that the whole iteration has been completed - stream << indent() << "array_out << t_" << i << "_i + 1;" << endl; - stream << indent() << "array_out << " - << "(t_" << i << "_j == 0 ? 0 : t_" << i << "_j - 1);" << endl; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << "array_out << t_" << i << "_i" << suffix + << " + 1;" << endl; + stream << indent() << "array_out << " + << "(t_" << i << "_j" << suffix << " == 0 ? 0 : t_" << i << "_j" + << suffix << " - 1);" << endl; + if (!outside) { + break; + } else { + suffix = "_outside"; + } + } } stream << indent() << "#ifdef _OPENMP" << endl; inc_indent(); @@ -1045,7 +1056,7 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", dec_indent(); } - void load_cyk_indices(Printer::Base &stream, size_t n_tracks) { + void load_cyk_indices(Printer::Base &stream, size_t n_tracks, bool outside) { inc_indent(); stream << indent() << "void load_cyk_indices() {" << endl; inc_indent(); @@ -1060,8 +1071,18 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", stream << indent() << "boost::archive::text_iarchive " "array_in(array_fin);" << endl; for (size_t i = 0; i < n_tracks; i++) { - stream << indent() << "array_in >> t_" << i << "_i;" << endl; - stream << indent() << "array_in >> t_" << i << "_j;" << endl; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { + stream << indent() << "array_in >> t_" << i << "_i" << suffix + << ";" << endl; + stream << indent() << "array_in >> t_" << i << "_j" << suffix + << ";" << endl; + if (!outside) { + break; + } else { + suffix = "_outside"; + } + } } stream << indent() << "#ifdef _OPENMP" << endl; stream << indent() << " array_in >> outer_loop_1_idx;" << endl; diff --git a/src/cpp.cc b/src/cpp.cc index 6536832d4..b544e0d7f 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -1634,8 +1634,16 @@ void Printer::Cpp::print_seq_init(const AST &ast) { stream << indent() << "#else" << endl; inc_indent(); for (size_t i = 0; i < ast.grammar()->axiom->tracks(); i++) { - stream << indent() << "t_" << i << "_i = 0;" << endl; - stream << indent() << "t_" << i << "_j = 0;" << endl; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << "t_" << i << "_i" << suffix << " = 0;" << endl; + stream << indent() << "t_" << i << "_j" << suffix << " = 0;" << endl; + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX; + } + } } dec_indent(); stream << indent() << "#endif" << endl << endl; @@ -1979,8 +1987,18 @@ void Printer::Cpp::header(const AST &ast) { // store indices for cyk loops here so they can be archived/loaded stream << indent() << "// indices for cyk loops" << endl; for (size_t t = 0; t < ast.grammar()->axiom->tracks(); t++) { - stream << indent() << *type << " t_" << t << "_i;" << endl; - stream << indent() << *type << " t_" << t << "_j;" << endl; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << *type << " t_" << t << "_i" << suffix + << ";" << endl; + stream << indent() << *type << " t_" << t << "_j" << suffix + << ";" << endl; + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX; + } + } } stream << "#ifdef _OPENMP" << endl; stream << indent() << "int outer_loop_1_idx, outer_loop_2_idx, " @@ -2076,9 +2094,11 @@ void Printer::Cpp::header_footer(const AST &ast) { nt_tables &tabulated = ast.grammar()->tabulated; if (ast.checkpoint->cyk) { ast.checkpoint->archive_cyk_indices(stream, - ast.grammar()->axiom->tracks()); + ast.grammar()->axiom->tracks(), + ast.grammar()->is_partof_outside()); ast.checkpoint->load_cyk_indices(stream, - ast.grammar()->axiom->tracks()); + ast.grammar()->axiom->tracks(), + ast.grammar()->is_partof_outside()); ast.checkpoint->parse_checkpoint_log(stream, true); } ast.checkpoint->archive_periodically(stream, tabulated); diff --git a/src/cyk.cc b/src/cyk.cc index b7823f30b..abc81e0fb 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -303,15 +303,20 @@ std::list *cyk_traversal_singlethread_singletrack_outside( dynamic_cast(seqend)->add_arg(seq->name); dynamic_cast(seqend)->is_obj = Bool(true); + Expr::Vacc *idx_col = new Expr::Vacc(new std::string( + *ast.grammar()->right_running_indices[track]->name() + OUTSIDE_IDX_SUFFIX)); + Expr::Vacc *idx_row = new Expr::Vacc(new std::string( + *ast.grammar()->left_running_indices[track]->name() + OUTSIDE_IDX_SUFFIX)); + CYKloop col = get_for_column( - ast.grammar()->right_running_indices[track], - seqend->minus(ast.grammar()->left_running_indices[track]), seqend->plus(new Expr::Const(1)), + idx_col, + seqend->minus(idx_row), seqend->plus(new Expr::Const(1)), with_checkpoint, mode); std::list *co = copy_statements(nested_stmts); col.loop->statements.insert( col.loop->statements.end(), co->begin(), co->end()); - CYKloop row = get_for_row(ast.grammar()->left_running_indices[track], + CYKloop row = get_for_row(idx_row, new Expr::Const(0), seqend->plus(new Expr::Const(1)), with_checkpoint, mode); row.loop->statements.push_back(col.loop); @@ -607,9 +612,12 @@ std::list *add_nt_calls(std::list &stmts, // add NTs std::list *nt_stmts = new std::list(); if (with_checkpoint) { - if (mode == CYKmode::SINGLETHREAD) { - nt_stmts->push_back(new Statement::CustomCode( + if ((mode == CYKmode::SINGLETHREAD) || (mode == CYKmode::SINGLETHREAD_OUTSIDE)) { + // don't add mutex on top level, as it's context would never end + if (loop_vars->size() > 0) { + nt_stmts->push_back(new Statement::CustomCode( "std::lock_guard lock(mutex);")); + } } else { if (mode == CYKmode::OPENMP_SERIAL) { nt_stmts->push_back(mutex_lock()); @@ -631,9 +639,14 @@ std::list *add_nt_calls(std::list &stmts, for (size_t t = 0; t < (*i)->tracks(); ++t, ++it_stmt_seq) { if (!(*i)->tables()[t].delete_left_index()) { Expr::Vacc *idx = (*i)->left_indices.at(t)->vacc(); - if (std::find(loop_vars->begin(), loop_vars->end(), - idx->name()) != loop_vars->end()) { - used_indices++; + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + idx = new Expr::Vacc(new std::string(*idx->name() + OUTSIDE_IDX_SUFFIX)); + } + for (std::list::const_iterator lv = loop_vars->begin(); lv != loop_vars->end(); ++lv) { + if (**lv == *idx->name()) { + used_indices++; + break; + } } nt_has_indices++; if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { @@ -641,16 +654,21 @@ std::list *add_nt_calls(std::list &stmts, Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); dynamic_cast(seqsize)->is_obj = Bool(true); - args->push_back(idx->minus(seqsize)->plus((*i)->right_indices.at(t)->vacc())); + args->push_back(idx->minus(seqsize)->plus((new Expr::Vacc(new std::string(*(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX))))); } else { args->push_back(idx->minus(new Expr::Const(1))); } } if (!(*i)->tables()[t].delete_right_index()) { Expr::Vacc *idx = (*i)->right_indices.at(t)->vacc(); - if (std::find(loop_vars->begin(), loop_vars->end(), - idx->name()) != loop_vars->end()) { - used_indices++; + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + idx = new Expr::Vacc(new std::string(*idx->name() + OUTSIDE_IDX_SUFFIX)); + } + for (std::list::const_iterator lv = loop_vars->begin(); lv != loop_vars->end(); ++lv) { + if (**lv == *idx->name()) { + used_indices++; + break; + } } nt_has_indices++; args->push_back(idx); @@ -702,19 +720,31 @@ Fn_Def *print_CYK(const AST &ast) { they would normally start with */ for (size_t track = 0; track < ast.grammar()->axiom->tracks(); ++track) { - fn_cyk->stmts.push_back(new Statement::Var_Decl( - new Type::Int(), - *(ast.grammar()->left_running_indices.at(track)->name()) + - std::string("_loaded"), new Expr::Or( - new Expr::Not(new Expr::Vacc(new std::string("load_checkpoint"))), - new Expr::Not(ast.grammar()->left_running_indices.at(track))))); - - fn_cyk->stmts.push_back(new Statement::Var_Decl( - new Type::Int(), - *(ast.grammar()->right_running_indices.at(track)->name()) + - std::string("_loaded"), new Expr::Or( - new Expr::Not(new Expr::Vacc(new std::string("load_checkpoint"))), - new Expr::Not(ast.grammar()->right_running_indices.at(track))))); + Expr::Vacc *idx_i = ast.grammar()->left_running_indices.at(track); + Expr::Vacc *idx_j = ast.grammar()->right_running_indices.at(track); + std::string suffix = std::string("_loaded"); + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + fn_cyk->stmts.push_back(new Statement::Var_Decl( + new Type::Int(), + *(ast.grammar()->left_running_indices.at(track)->name()) + + suffix, new Expr::Or( + new Expr::Not(new Expr::Vacc(new std::string("load_checkpoint"))), + new Expr::Not(idx_i)))); + + fn_cyk->stmts.push_back(new Statement::Var_Decl( + new Type::Int(), + *(ast.grammar()->right_running_indices.at(track)->name()) + + suffix, new Expr::Or( + new Expr::Not(new Expr::Vacc(new std::string("load_checkpoint"))), + new Expr::Not(idx_j)))); + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX + suffix; + idx_i = new Expr::Vacc(new std::string(*idx_i->name() + OUTSIDE_IDX_SUFFIX)); + idx_j = new Expr::Vacc(new std::string(*idx_j->name() + OUTSIDE_IDX_SUFFIX)); + } + } } } @@ -730,8 +760,18 @@ Fn_Def *print_CYK(const AST &ast) { ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD, ast); stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); // finally add traversal structure with NT calls to function body + if (ast.outside_generation()) { + fn_cyk->stmts.push_back(new Statement::CustomCode( + "// start computing inside DP matrices only ...")); + } fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); + if (ast.outside_generation()) { + fn_cyk->stmts.push_back(new Statement::CustomCode( + "// ... now compute outside DP matrices")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "// they are by definition quadratic as every sub-word must " + "be returned")); stmts = cyk_traversal_singlethread(ast, CYKmode::SINGLETHREAD_OUTSIDE); std::list *new_stmts = add_nt_calls(*stmts, new std::list(), ast.grammar()->topological_ord(), diff --git a/src/cyk.hh b/src/cyk.hh index 2611e48b0..42d93ede2 100644 --- a/src/cyk.hh +++ b/src/cyk.hh @@ -39,6 +39,8 @@ #include "statement/fn_call.hh" #include "var_acc.hh" +static const char *OUTSIDE_IDX_SUFFIX = "_outside"; + std::tuple*, std::string*> get_tile_computation(const AST &ast, std::string *name_maxtilen, Statement::Var_Decl *input_seq, bool just_tilesize); From 28cc2557978c74ba36edd745beabdd2a97bc2b92 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 21:20:25 +0200 Subject: [PATCH 138/189] when loading dumped checkpoint, start with indices +/- 1 to make sure all DP cells are computed. Sign depends on inside/outside tables. --- src/checkpoint.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 351f4dd14..19637c41d 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -1004,10 +1004,10 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", std::string suffix = ""; for (int io = 0; io < 2; ++io) { // iterate through inside and outside stream << indent() << "array_out << t_" << i << "_i" << suffix - << " + 1;" << endl; + << " " << (io == 0 ? "+" : "-") << " 1;" << endl; stream << indent() << "array_out << " << "(t_" << i << "_j" << suffix << " == 0 ? 0 : t_" << i << "_j" - << suffix << " - 1);" << endl; + << suffix << " " << (io == 0 ? "-" : "+") << " 1);" << endl; if (!outside) { break; } else { @@ -1072,7 +1072,7 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", "array_in(array_fin);" << endl; for (size_t i = 0; i < n_tracks; i++) { std::string suffix = ""; - for (int io = 0; io < 2; ++io) { + for (int io = 0; io < 2; ++io) { // iterate through inside and outside stream << indent() << "array_in >> t_" << i << "_i" << suffix << ";" << endl; stream << indent() << "array_in >> t_" << i << "_j" << suffix From 206077c1c08103f64fde1674bc71e9911ab79bb1 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 21:21:43 +0200 Subject: [PATCH 139/189] add tests for outside + cyk + checkpointing --- testdata/regresstest/config | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index ae421d516..d627b27bd 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -528,6 +528,10 @@ check_new_old_eq adpf.gap unused count "uacgugacguugacguguaucgguacuacgugacguugac GAPC="../../../gapc --cyk --checkpoint" check_checkpoint_eq adpf.gap unused pf "uacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguac" cyk_openmp_checkpoint 1 +# deactivate openMP +CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA" +LDLIBS_EXTRA="$DEFAULT_LDLIBS_EXTRA" + # results have been verified against "RNAfold -p -d0 --bppmThreshold=0" v2.4.17 and Stefan's manual python outside version of nodangle GRAMMAR=../../grammar_outside GAPC="../../../gapc --outside_grammar weak --outside_grammar struct" @@ -541,7 +545,7 @@ check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaC # same as above, but with CYK code generation GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" -#check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside @@ -604,4 +608,14 @@ GRAMMAR=../../grammar2 GAPC="../../../gapc --outside_grammar ALL " check_new_old_eq_twotrack alignments_cyk.gap unused infloop "ff" outside_infloop "z" +GAPC="../../../gapc --outside_grammar A " +check_new_old_eq_twotrack alignments_cyk.gap unused infloop "frei" outside_multitrack_cyk "zeit" + +GAPC="../../../gapc --outside_grammar A --cyk" +check_new_old_eq_twotrack alignments_cyk.gap unused infloop "frei" outside_multitrack_cyk "zeit" + +GRAMMAR=../../grammar_outside +GAPC="../../../gapc --outside_grammar weak --cyk --checkpoint" +check_checkpoint_eq nodangle.gap unused pfunc "GUAAAAUAGGUUUUUUACCUCGGUAUGCCUUGUGACUGGCUUGACAAGCUUUUCCUCAGCUCCGUAAACUCCUUUCAGUGGGAAAUUGUGGGGCAAAGUGGGAAUAAGGGGUGAGGCUGGCAUGUUCCGGGGAGCAACGUUAGUCAAUCUCGACAGCAAAGGGCGCUUAUCAGUGCCUACCCGUUAUCGGGAACAGCUGCUUGAGAACGCUGCCGGUCAAAUGGUUUGCACCAUUGACAUUUAUCACCCGUGCCUGCUGCUUUACCCCCUGCCUGAAUGGGAAAUUAUCGAGC" cyk_cp_outside_single 1 + CPPFLAGS_EXTRA="" From c6a0984d403ee6ffbe2a44fa277b59448c400ac8 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 21:23:01 +0200 Subject: [PATCH 140/189] adding TODO --- src/checkpoint.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 19637c41d..3a90f43c7 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -1011,6 +1011,7 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", if (!outside) { break; } else { + //TODO(sjanssen) why can't I use OUTSIDE_IDX_SUFFIX from cyk.hh here? suffix = "_outside"; } } From 2dfd3d01c6a3347e754f9302386217c1c4d20e22 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 21:32:27 +0200 Subject: [PATCH 141/189] linting and adding some comments to new outside traversal construction --- src/cyk.cc | 78 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index abc81e0fb..22d0fff72 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -108,7 +108,8 @@ class CYKloop { } }; -enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL, SINGLETHREAD_OUTSIDE}; +enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL, + SINGLETHREAD_OUTSIDE}; CYKloop get_for_column(Expr::Vacc *running_boundary, Expr::Base *start, Expr::Base *end, @@ -288,8 +289,25 @@ std::list *cyk_traversal_singlethread_singletrack( } /* - * for (unsigned int t_0_i = 0; t_0_i <= t_0_seq.size(); ++t_0_i) { - for (unsigned int t_0_j = t_0_seq.size() - t_0_i; t_0_j <= t_0_seq.size(); ++t_0_j) { + * Construct the loop traversal structure for CYK parsing of one track for + * outside parts of a grammar, as below. + * Since in outside, all DP tables (except the outside_axiom) must be quadratic + * by definition, we can have a much simpler structure than for the inside case. + * Here, we don't need extra cases for tables with fewer indices that get + * optimized away in linear or constant table dimensions. + * + * However, we need to make sure that DP cells are filled in the correct order + * and this is in a triangular fashion starting top right and advancing towards + * the main anti diagonal, e.g. + * + * | 0 1 2 3 4 5 | 0 1 2 3 4 5 + * --|------------------- --|------------------ + * 0 | 18 13 9 6 1 0 0 | A A A A A A + * 1 | 19 14 10 4 2 1 | A A A A A + * 2 | 20 15 11 5 2 | A A A A + * 3 | 21 16 12 3 | A A A + * 4 | 22 17 4 | A A + * 5 | 23 5 | A * */ std::list *cyk_traversal_singlethread_singletrack_outside( @@ -304,9 +322,11 @@ std::list *cyk_traversal_singlethread_singletrack_outside( dynamic_cast(seqend)->is_obj = Bool(true); Expr::Vacc *idx_col = new Expr::Vacc(new std::string( - *ast.grammar()->right_running_indices[track]->name() + OUTSIDE_IDX_SUFFIX)); + *ast.grammar()->right_running_indices[track]->name() + + OUTSIDE_IDX_SUFFIX)); Expr::Vacc *idx_row = new Expr::Vacc(new std::string( - *ast.grammar()->left_running_indices[track]->name() + OUTSIDE_IDX_SUFFIX)); + *ast.grammar()->left_running_indices[track]->name() + + OUTSIDE_IDX_SUFFIX)); CYKloop col = get_for_column( idx_col, @@ -339,12 +359,12 @@ std::list *cyk_traversal_singlethread(const AST &ast, track--, ++it_stmt_seq) { if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { stmts = cyk_traversal_singlethread_singletrack_outside( - track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, - mode); + track, ast, *it_stmt_seq, stmts, + ast.checkpoint && ast.checkpoint->cyk, mode); } else { stmts = cyk_traversal_singlethread_singletrack( - track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, - mode); + track, ast, *it_stmt_seq, stmts, + ast.checkpoint && ast.checkpoint->cyk, mode); } } @@ -603,7 +623,8 @@ std::list *add_nt_calls(std::list &stmts, } } - if (((mode == CYKmode::OPENMP_PARALLEL) || (mode == CYKmode::SINGLETHREAD_OUTSIDE)) && contains_nested_for) { + if (((mode == CYKmode::OPENMP_PARALLEL) || + (mode == CYKmode::SINGLETHREAD_OUTSIDE)) && contains_nested_for) { // don't add NT calls in for loops that is not the innermost loop, if in // multi threaded mode. return new std::list(); @@ -612,7 +633,8 @@ std::list *add_nt_calls(std::list &stmts, // add NTs std::list *nt_stmts = new std::list(); if (with_checkpoint) { - if ((mode == CYKmode::SINGLETHREAD) || (mode == CYKmode::SINGLETHREAD_OUTSIDE)) { + if ((mode == CYKmode::SINGLETHREAD) || + (mode == CYKmode::SINGLETHREAD_OUTSIDE)) { // don't add mutex on top level, as it's context would never end if (loop_vars->size() > 0) { nt_stmts->push_back(new Statement::CustomCode( @@ -635,14 +657,17 @@ std::list *add_nt_calls(std::list &stmts, std::list *args = new std::list(); size_t used_indices = 0; size_t nt_has_indices = 0; - std::vector::const_iterator it_stmt_seq = ast.seq_decls.begin(); + std::vector::const_iterator it_stmt_seq = + ast.seq_decls.begin(); for (size_t t = 0; t < (*i)->tracks(); ++t, ++it_stmt_seq) { if (!(*i)->tables()[t].delete_left_index()) { Expr::Vacc *idx = (*i)->left_indices.at(t)->vacc(); if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { - idx = new Expr::Vacc(new std::string(*idx->name() + OUTSIDE_IDX_SUFFIX)); + idx = new Expr::Vacc(new std::string( + *idx->name() + OUTSIDE_IDX_SUFFIX)); } - for (std::list::const_iterator lv = loop_vars->begin(); lv != loop_vars->end(); ++lv) { + for (std::list::const_iterator lv = loop_vars->begin(); + lv != loop_vars->end(); ++lv) { if (**lv == *idx->name()) { used_indices++; break; @@ -654,7 +679,9 @@ std::list *add_nt_calls(std::list &stmts, Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); dynamic_cast(seqsize)->is_obj = Bool(true); - args->push_back(idx->minus(seqsize)->plus((new Expr::Vacc(new std::string(*(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX))))); + args->push_back(idx->minus(seqsize)->plus((new Expr::Vacc( + new std::string(*(*i)->right_indices.at(t)->vacc()->name() + + OUTSIDE_IDX_SUFFIX))))); } else { args->push_back(idx->minus(new Expr::Const(1))); } @@ -662,9 +689,11 @@ std::list *add_nt_calls(std::list &stmts, if (!(*i)->tables()[t].delete_right_index()) { Expr::Vacc *idx = (*i)->right_indices.at(t)->vacc(); if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { - idx = new Expr::Vacc(new std::string(*idx->name() + OUTSIDE_IDX_SUFFIX)); + idx = new Expr::Vacc(new std::string( + *idx->name() + OUTSIDE_IDX_SUFFIX)); } - for (std::list::const_iterator lv = loop_vars->begin(); lv != loop_vars->end(); ++lv) { + for (std::list::const_iterator lv = loop_vars->begin(); + lv != loop_vars->end(); ++lv) { if (**lv == *idx->name()) { used_indices++; break; @@ -728,21 +757,25 @@ Fn_Def *print_CYK(const AST &ast) { new Type::Int(), *(ast.grammar()->left_running_indices.at(track)->name()) + suffix, new Expr::Or( - new Expr::Not(new Expr::Vacc(new std::string("load_checkpoint"))), + new Expr::Not(new Expr::Vacc( + new std::string("load_checkpoint"))), new Expr::Not(idx_i)))); fn_cyk->stmts.push_back(new Statement::Var_Decl( new Type::Int(), *(ast.grammar()->right_running_indices.at(track)->name()) + suffix, new Expr::Or( - new Expr::Not(new Expr::Vacc(new std::string("load_checkpoint"))), + new Expr::Not(new Expr::Vacc(new std::string( + "load_checkpoint"))), new Expr::Not(idx_j)))); if (!ast.grammar()->is_partof_outside()) { break; } else { suffix = OUTSIDE_IDX_SUFFIX + suffix; - idx_i = new Expr::Vacc(new std::string(*idx_i->name() + OUTSIDE_IDX_SUFFIX)); - idx_j = new Expr::Vacc(new std::string(*idx_j->name() + OUTSIDE_IDX_SUFFIX)); + idx_i = new Expr::Vacc(new std::string( + *idx_i->name() + OUTSIDE_IDX_SUFFIX)); + idx_j = new Expr::Vacc(new std::string( + *idx_j->name() + OUTSIDE_IDX_SUFFIX)); } } } @@ -775,7 +808,8 @@ Fn_Def *print_CYK(const AST &ast) { stmts = cyk_traversal_singlethread(ast, CYKmode::SINGLETHREAD_OUTSIDE); std::list *new_stmts = add_nt_calls(*stmts, new std::list(), ast.grammar()->topological_ord(), - ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD_OUTSIDE, ast); + ast.checkpoint && ast.checkpoint->cyk, CYKmode::SINGLETHREAD_OUTSIDE, + ast); stmts->insert(stmts->end(), new_stmts->begin(), new_stmts->end()); fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); } From d46b86cdbfba32f7c56958bd3f87f448a935580f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 23 May 2023 21:34:54 +0200 Subject: [PATCH 142/189] linting --- src/checkpoint.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 3a90f43c7..d5e6af0a0 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -1011,7 +1011,8 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", if (!outside) { break; } else { - //TODO(sjanssen) why can't I use OUTSIDE_IDX_SUFFIX from cyk.hh here? + // TODO(sjanssen) why can't I use OUTSIDE_IDX_SUFFIX from cyk.hh + // here? suffix = "_outside"; } } From fcacc2d0e163788b450f7bc2ee20a985fd757196 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 24 May 2023 08:16:15 +0200 Subject: [PATCH 143/189] pointing to the correct branch of gapc-test-suite --- .github/workflows/c-cpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 67d5ec6ed..c69b46932 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -31,7 +31,7 @@ jobs: run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip - name: Checkout truth - run: git clone --branch outside_fix_infloop https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure @@ -79,7 +79,7 @@ jobs: - name: add random Haskell lib run: cabal install --lib random - name: Checkout truth - run: git clone --branch outside_fix_infloop https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure From b9d4ff0153445aba71f2ad7e6d2e5a0a27c59466 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 24 May 2023 11:30:49 +0200 Subject: [PATCH 144/189] adding CYK openMP code for outside --- src/cyk.cc | 226 +++++++++++++++++++++++++++++++----- testdata/regresstest/config | 29 +++-- 2 files changed, 215 insertions(+), 40 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index 22d0fff72..fe1638cfe 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -109,7 +109,8 @@ class CYKloop { }; enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL, - SINGLETHREAD_OUTSIDE}; + SINGLETHREAD_OUTSIDE, + OPENMP_PARALLEL_OUTSIDE,OPENMP_SERIAL_OUTSIDE}; CYKloop get_for_column(Expr::Vacc *running_boundary, Expr::Base *start, Expr::Base *end, @@ -132,10 +133,21 @@ CYKloop get_for_column(Expr::Vacc *running_boundary, start); // create condition of For loop - Expr::Less *cond_col = new Expr::Less( + Expr::Base *cond_col = new Expr::Less( new Expr::Vacc(*var_col), end); + if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { + cond_col = new Expr::Greater( + (new Expr::Vacc(*var_col))->plus(new Expr::Const(1)), + end); + } Statement::For *loop = new Statement::For(var_col, cond_col); + if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { + Statement::Var_Assign *x = new Statement::Var_Assign( + *var_col, new Expr::Const(new Const::Int(-1))); + x->set_op(::Expr::Type::PLUS); + loop->inc = x; + } Statement::Var_Decl *var_nonloop = var_col->clone(); var_nonloop->rhs = end; @@ -166,14 +178,16 @@ CYKloop get_for_row(Expr::Vacc *running_boundary, Expr::Base *start, // create condition of For loop Expr::Two *cond_row = new Expr::Greater(new Expr::Vacc(*var_row), end); - if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { cond_row = new Expr::Less(new Expr::Vacc(*var_row), end); } Statement::For *loop = new Statement::For(var_row, cond_row); // except for outside, we need to decrement the loop variable, i.e. t_x_i-- // In outside, it must be ++t_x_i - if (mode != CYKmode::SINGLETHREAD_OUTSIDE) { + if ((mode != CYKmode::SINGLETHREAD_OUTSIDE) && + (mode != CYKmode::OPENMP_SERIAL_OUTSIDE)) { Statement::Var_Assign *x = new Statement::Var_Assign( *var_row, new Expr::Const(new Const::Int(-1))); x->set_op(::Expr::Type::PLUS); @@ -328,16 +342,26 @@ std::list *cyk_traversal_singlethread_singletrack_outside( *ast.grammar()->left_running_indices[track]->name() + OUTSIDE_IDX_SUFFIX)); + Expr::Base *col_start = seqend->minus(idx_row); + Expr::Base *col_end = seqend->plus(new Expr::Const(1)); + if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { + col_start = seqend; + col_end = seqend->minus(idx_row); + } CYKloop col = get_for_column( idx_col, - seqend->minus(idx_row), seqend->plus(new Expr::Const(1)), + col_start, col_end, with_checkpoint, mode); std::list *co = copy_statements(nested_stmts); col.loop->statements.insert( col.loop->statements.end(), co->begin(), co->end()); + Expr::Base *row_start = new Expr::Const(0); + if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { + row_start = new Expr::Vacc(new std::string("max_tiles_n")); + } CYKloop row = get_for_row(idx_row, - new Expr::Const(0), seqend->plus(new Expr::Const(1)), + row_start, seqend->plus(new Expr::Const(1)), with_checkpoint, mode); row.loop->statements.push_back(col.loop); @@ -357,7 +381,8 @@ std::list *cyk_traversal_singlethread(const AST &ast, ast.seq_decls.rbegin(); for (int track = ast.grammar()->axiom->tracks() - 1; track >= 0; track--, ++it_stmt_seq) { - if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { stmts = cyk_traversal_singlethread_singletrack_outside( track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, mode); @@ -434,16 +459,68 @@ std::list *cyk_traversal_singlethread(const AST &ast, * 11 | 79 * 12 | 78 * + * ====================== + * + * This function also constructs traversal structure for outside openMP code, + * if mode == CYKmode::OPENMP_PARALLEL_OUTSIDE. The three phases look like + * + * A: tile_size = 4, input = aaaaccccgggg + * | 0 1 2 3 4 5 6 7 8 9 10 11 12 + * ---|---------------------------------------------------- + * 0 | 26 23 21 20 16 13 11 10 6 3 1 0 + * 1 | 27 24 22 17 14 12 7 4 2 + * 2 | 28 25 18 15 8 5 + * 3 | 29 19 9 + * 4 | + * 5 | + * 6 | + * 7 | + * 8 | + * 9 | + * 10 | + * 11 | + * 12 | + * + * B: tile_size = 4, input = aaaaccccgggg + * | 0 1 2 3 4 5 6 7 8 9 10 11 12 + * ---|---------------------------------------------------- + * 0 | + * 1 | 46 30 + * 2 | 50 47 31 31 + * 3 | 54 51 48 38 35 32 + * 4 | 58 55 52 49 42 39 36 33 + * 5 | 59 56 53 62 43 40 37 + * 6 | 60 57 66 63 44 41 + * 7 | 61 70 67 64 45 + * 8 | 74 71 68 65 + * 9 | 75 72 69 + * 10 | 76 73 + * 11 | 77 + * 12 | + * + * C: tile_size = 4, input = aaaaccccgggg + * | 0 1 2 3 4 5 6 7 8 9 10 11 12 + * ---|---------------------------------------------------- + * 0 | 78 + * 1 | 79 + * 2 | 80 + * 3 | 81 + * 4 | 82 + * 5 | 83 + * 6 | 84 + * 7 | 85 + * 8 | 86 + * 9 | 87 + * 10 | 88 + * 11 | 89 + * 12 | 90 */ std::list *cyk_traversal_multithread_parallel(const AST &ast, Statement::Var_Decl *seq, std::string *tile_size, - std::string *name_maxtilen, bool with_checkpoint) { + std::string *name_maxtilen, bool with_checkpoint, CYKmode mode) { size_t track = 0; // as openMP currently only works for single track grammars std::list *stmts = new std::list(); - Expr::Base *row_start = ast.grammar()->right_running_indices.at( - track)->plus(new Expr::Const(1)); - Expr::Vacc *z = new Expr::Vacc(new std::string("z")); Expr::Vacc *y = new Expr::Vacc(new std::string("y")); Statement::Var_Decl *x = new Statement::Var_Decl( @@ -451,11 +528,19 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, // part A: prepare for parallel tile phase, prepare predecessor DP cells for // later parallel computation - CYKloop row = get_for_row(ast.grammar()->left_running_indices[track], - row_start, z, with_checkpoint, CYKmode::OPENMP_PARALLEL); - CYKloop col = get_for_column(ast.grammar()->right_running_indices[track], - z, z->plus(new Expr::Vacc(tile_size)), with_checkpoint, - CYKmode::OPENMP_PARALLEL); + Expr::Vacc *idx_row = ast.grammar()->left_running_indices[track]; + Expr::Vacc *idx_col = ast.grammar()->right_running_indices[track]; + if (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) { + idx_row = new Expr::Vacc(new std::string( + *idx_row->name() + OUTSIDE_IDX_SUFFIX)); + idx_col = new Expr::Vacc(new std::string( + *idx_col->name() + OUTSIDE_IDX_SUFFIX)); + } + Expr::Base *row_start = idx_col->plus(new Expr::Const(1)); + + CYKloop row = get_for_row(idx_row, row_start, z, with_checkpoint, mode); + CYKloop col = get_for_column(idx_col, + z, z->plus(new Expr::Vacc(tile_size)), with_checkpoint, mode); col.loop->statements.push_back(row.loop); Expr::Base *start_z = new Expr::Const(0); if (with_checkpoint) { @@ -485,13 +570,11 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, stmts->push_back(loop_z); // part B: code for the actual parallel tile computation - CYKloop rowB = get_for_row(ast.grammar()->left_running_indices[track], - new Expr::Vacc(*x), + CYKloop rowB = get_for_row(idx_row, new Expr::Vacc(*x), (new Expr::Vacc(*x))->minus(new Expr::Vacc(tile_size)), - with_checkpoint, CYKmode::OPENMP_PARALLEL); - CYKloop colB = get_for_column(ast.grammar()->right_running_indices[track], - y, y->plus(new Expr::Vacc(tile_size)), with_checkpoint, - CYKmode::OPENMP_PARALLEL); + with_checkpoint, mode); + CYKloop colB = get_for_column(idx_col, + y, y->plus(new Expr::Vacc(tile_size)), with_checkpoint, mode); colB.loop->statements.push_back(rowB.loop); Expr::Base *start_y = z; @@ -598,7 +681,8 @@ std::list *add_nt_calls(std::list &stmts, std::list *next_loop_vars = new std::list(); next_loop_vars->insert( next_loop_vars->end(), loop_vars->begin(), loop_vars->end()); - if ((mode != CYKmode::OPENMP_PARALLEL) || + if (((mode != CYKmode::OPENMP_PARALLEL) && + (mode != CYKmode::OPENMP_PARALLEL_OUTSIDE)) || (fl->var_decl->name->find("t_", 0) == 0)) { // openMP code adds in loops that do not traverse NT indices. Only add // loop variable, if it regard to NT indices, which all start with t_ @@ -624,7 +708,9 @@ std::list *add_nt_calls(std::list &stmts, } if (((mode == CYKmode::OPENMP_PARALLEL) || - (mode == CYKmode::SINGLETHREAD_OUTSIDE)) && contains_nested_for) { + (mode == CYKmode::SINGLETHREAD_OUTSIDE) || + (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) && contains_nested_for) { // don't add NT calls in for loops that is not the innermost loop, if in // multi threaded mode. return new std::list(); @@ -651,7 +737,10 @@ std::list *add_nt_calls(std::list &stmts, if (!(*i)->is_tabulated()) { continue; } - if ((*i)->is_partof_outside() == (mode != CYKmode::SINGLETHREAD_OUTSIDE)) { + if ((*i)->is_partof_outside() == ( + (mode != CYKmode::SINGLETHREAD_OUTSIDE) && + (mode != CYKmode::OPENMP_PARALLEL_OUTSIDE) && + (mode != CYKmode::OPENMP_SERIAL_OUTSIDE))) { continue; } std::list *args = new std::list(); @@ -662,7 +751,9 @@ std::list *add_nt_calls(std::list &stmts, for (size_t t = 0; t < (*i)->tracks(); ++t, ++it_stmt_seq) { if (!(*i)->tables()[t].delete_left_index()) { Expr::Vacc *idx = (*i)->left_indices.at(t)->vacc(); - if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || + (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { idx = new Expr::Vacc(new std::string( *idx->name() + OUTSIDE_IDX_SUFFIX)); } @@ -674,21 +765,28 @@ std::list *add_nt_calls(std::list &stmts, } } nt_has_indices++; - if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { // create t_X_seq.size() call Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); dynamic_cast(seqsize)->is_obj = Bool(true); - args->push_back(idx->minus(seqsize)->plus((new Expr::Vacc( + args->push_back(idx->plus((new Expr::Vacc( new std::string(*(*i)->right_indices.at(t)->vacc()->name() + - OUTSIDE_IDX_SUFFIX))))); + OUTSIDE_IDX_SUFFIX))))->minus(seqsize)); + } else if ((mode == CYKmode::OPENMP_PARALLEL_OUTSIDE)) { + Expr::Vacc *idx_j = new Expr::Vacc(new std::string( + *(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); + args->push_back(idx_j->plus(new Expr::Const(1))->minus(idx)); } else { args->push_back(idx->minus(new Expr::Const(1))); } } if (!(*i)->tables()[t].delete_right_index()) { Expr::Vacc *idx = (*i)->right_indices.at(t)->vacc(); - if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { + if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || + (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { idx = new Expr::Vacc(new std::string( *idx->name() + OUTSIDE_IDX_SUFFIX)); } @@ -700,7 +798,19 @@ std::list *add_nt_calls(std::list &stmts, } } nt_has_indices++; - args->push_back(idx); + if ((mode == CYKmode::OPENMP_PARALLEL_OUTSIDE)) { + // create t_X_seq.size() call + Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); + dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); + dynamic_cast(seqsize)->is_obj = Bool(true); + + Expr::Vacc *idx_i = new Expr::Vacc(new std::string( + *(*i)->left_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); + + args->push_back(seqsize->minus(idx_i)->plus(new Expr::Const(1))); + } else { + args->push_back(idx); + } } } if (used_indices == loop_vars->size()) { @@ -864,7 +974,7 @@ Fn_Def *print_CYK(const AST &ast) { // parallel part std::list *stmts = cyk_traversal_multithread_parallel( ast, *it_stmt_seq, &VARNAME_tile_size, name_maxtilen, - ast.checkpoint && ast.checkpoint->cyk); + ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_PARALLEL); // inject NT calls std::list *new_stmts = add_nt_calls(*stmts, new std::list(), ast.grammar()->topological_ord(), @@ -886,6 +996,58 @@ Fn_Def *print_CYK(const AST &ast) { stmts->insert(stmts->end(), new_serial_stmts->begin(), new_serial_stmts->end()); fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); + + if (ast.outside_generation()) { + fn_cyk->stmts.push_back(new Statement::CustomCode( + "// ... now compute outside DP matrices")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "#pragma omp parallel")); + Statement::Block *blk_parallel_outside = new Statement::Block(); + if (ast.checkpoint && ast.checkpoint->cyk) { + blk_parallel_outside->statements.push_back(new Statement::CustomCode( + "#pragma omp for ordered schedule(dynamic)")); + } else { + blk_parallel_outside->statements.push_back(new Statement::CustomCode( + "#pragma omp for")); + } + blk_parallel_outside->statements.push_back(new Statement::CustomCode( + "// OPENMP < 3 requires signed int here ...")); + + // parallel part + std::list *stmts_outside = + cyk_traversal_multithread_parallel(ast, *it_stmt_seq, + &VARNAME_tile_size, name_maxtilen, + ast.checkpoint && ast.checkpoint->cyk, + CYKmode::OPENMP_PARALLEL_OUTSIDE); + // inject NT calls + std::list *new_stmts_outside = add_nt_calls( + *stmts_outside, new std::list(), + ast.grammar()->topological_ord(), + ast.checkpoint && ast.checkpoint->cyk, + CYKmode::OPENMP_PARALLEL_OUTSIDE, ast); + stmts_outside->insert(stmts_outside->end(), + new_stmts_outside->begin(), new_stmts_outside->end()); + + blk_parallel_outside->statements.insert( + blk_parallel_outside->statements.end(), + stmts_outside->begin(), stmts_outside->end()); + blk_parallel_outside->statements.push_back(new Statement::CustomCode( + "// end parallel")); + fn_cyk->stmts.push_back(blk_parallel_outside); + + // serial part + stmts = cyk_traversal_singlethread(ast, CYKmode::OPENMP_SERIAL_OUTSIDE); + // inject NT calls + std::list *new_serial_stmts = add_nt_calls( + *stmts, new std::list(), + ast.grammar()->topological_ord(), + ast.checkpoint && ast.checkpoint->cyk, + CYKmode::OPENMP_SERIAL_OUTSIDE, ast); + stmts->insert(stmts->end(), new_serial_stmts->begin(), + new_serial_stmts->end()); + fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); + + } } fn_cyk->stmts.push_back(new Statement::CustomCode("#endif")); diff --git a/testdata/regresstest/config b/testdata/regresstest/config index d627b27bd..c98fc97e1 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -532,6 +532,7 @@ check_checkpoint_eq adpf.gap unused pf "uacgugacguugacguguaucgguacuacgugacguugac CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA" LDLIBS_EXTRA="$DEFAULT_LDLIBS_EXTRA" +# ======= following are test for outside code generation ======= # results have been verified against "RNAfold -p -d0 --bppmThreshold=0" v2.4.17 and Stefan's manual python outside version of nodangle GRAMMAR=../../grammar_outside GAPC="../../../gapc --outside_grammar weak --outside_grammar struct" @@ -542,23 +543,35 @@ check_new_old_eq nodangle.gap unused count "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outsi # check that fn_arg (with alt) instead of only alt gets initialized check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside_overlay - # same as above, but with CYK code generation GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +# same as above, but with activated checkpointing +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk --checkpoint" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +# same as above, but with CYK code generation AND openMP parallelization +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" +CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA -fopenmp" +LDLIBS_EXTRA="$DEFAULT_LDLIBS_EXTRA -fopenmp" +if [ $(uname) = "Darwin" ]; then + CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA -Xpreprocessor -fopenmp -lomp " + LDLIBS_EXTRA="$DEFAULT_LDLIBS_EXTRA -Xpreprocessor -fopenmp -lomp -I\"$(brew --prefix libomp)/include\" -L\"$(brew --prefix libomp)/lib\"" +fi +OMP_NUM_THREADS=2 +export OMP_NUM_THREADS +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +# same as above, but with activated checkpointing +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk --checkpoint" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside - - - - - - -GAPC="../../../gapc --outside_grammar ALL" +# deactivate openMP CPPFLAGS_EXTRA="" LDLIBS_EXTRA="" + +GAPC="../../../gapc --outside_grammar ALL" check_new_old_eq hmm_sonneregen.gap unused count "SS" outside check_new_old_eq hmm_sonneregen.gap unused fwd "SS" outside check_new_old_eq hmm_sonneregen.gap unused fwd "SSRR" outside_ssrr From ae0eb09d397569cfd06a8d476c0dcb769bfb247b Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 24 May 2023 11:32:20 +0200 Subject: [PATCH 145/189] linting --- src/cyk.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index fe1638cfe..6b9c47430 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -110,7 +110,7 @@ class CYKloop { enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL, SINGLETHREAD_OUTSIDE, - OPENMP_PARALLEL_OUTSIDE,OPENMP_SERIAL_OUTSIDE}; + OPENMP_PARALLEL_OUTSIDE, OPENMP_SERIAL_OUTSIDE}; CYKloop get_for_column(Expr::Vacc *running_boundary, Expr::Base *start, Expr::Base *end, @@ -1046,7 +1046,6 @@ Fn_Def *print_CYK(const AST &ast) { stmts->insert(stmts->end(), new_serial_stmts->begin(), new_serial_stmts->end()); fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); - } } From a405cda2e6e4ccafd227c4da2847863fa28cfb0c Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 26 May 2023 10:52:46 +0200 Subject: [PATCH 146/189] enclose cond if used within one line --- src/expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expr.cc b/src/expr.cc index 4ad48f28b..6433eaa78 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -128,7 +128,7 @@ void Expr::Max::put(std::ostream &s) const { } void Expr::Cond::put(std::ostream &s) const { - s << '(' << *cond << ") ? (" << *then << ") : (" << *els << ')'; + s << "((" << *cond << ") ? (" << *then << ") : (" << *els << "))"; } void Expr::Not::put(std::ostream &s) const { From 6714d4c53c1b52027f5e4fbd82df9b8c6b191f9e Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 26 May 2023 10:53:38 +0200 Subject: [PATCH 147/189] fixing traversal order for openMP outside --- src/cyk.cc | 474 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 342 insertions(+), 132 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index 6b9c47430..8e73d1a93 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -34,6 +34,10 @@ static std::string VARNAME_max_tiles = "max_tiles"; // NOLINT [runtime/string] static std::string VARNAME_max_tiles_n = "max_tiles_n"; // NOLINT runtime/string +static std::string +// computes the maximal fitting number of tiles in one table dimension for +// outside computation +VARNAME_num_tiles_per_axis = "num_tiles_per_axis"; static Statement::Var_Decl tile_size_decl(new Type::Size(), VARNAME_tile_size); @@ -344,10 +348,6 @@ std::list *cyk_traversal_singlethread_singletrack_outside( Expr::Base *col_start = seqend->minus(idx_row); Expr::Base *col_end = seqend->plus(new Expr::Const(1)); - if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { - col_start = seqend; - col_end = seqend->minus(idx_row); - } CYKloop col = get_for_column( idx_col, col_start, col_end, @@ -357,9 +357,6 @@ std::list *cyk_traversal_singlethread_singletrack_outside( col.loop->statements.end(), co->begin(), co->end()); Expr::Base *row_start = new Expr::Const(0); - if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { - row_start = new Expr::Vacc(new std::string("max_tiles_n")); - } CYKloop row = get_for_row(idx_row, row_start, seqend->plus(new Expr::Const(1)), with_checkpoint, mode); @@ -381,8 +378,7 @@ std::list *cyk_traversal_singlethread(const AST &ast, ast.seq_decls.rbegin(); for (int track = ast.grammar()->axiom->tracks() - 1; track >= 0; track--, ++it_stmt_seq) { - if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || - (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { stmts = cyk_traversal_singlethread_singletrack_outside( track, ast, *it_stmt_seq, stmts, ast.checkpoint && ast.checkpoint->cyk, mode); @@ -459,65 +455,15 @@ std::list *cyk_traversal_singlethread(const AST &ast, * 11 | 79 * 12 | 78 * - * ====================== - * - * This function also constructs traversal structure for outside openMP code, - * if mode == CYKmode::OPENMP_PARALLEL_OUTSIDE. The three phases look like - * - * A: tile_size = 4, input = aaaaccccgggg - * | 0 1 2 3 4 5 6 7 8 9 10 11 12 - * ---|---------------------------------------------------- - * 0 | 26 23 21 20 16 13 11 10 6 3 1 0 - * 1 | 27 24 22 17 14 12 7 4 2 - * 2 | 28 25 18 15 8 5 - * 3 | 29 19 9 - * 4 | - * 5 | - * 6 | - * 7 | - * 8 | - * 9 | - * 10 | - * 11 | - * 12 | - * - * B: tile_size = 4, input = aaaaccccgggg - * | 0 1 2 3 4 5 6 7 8 9 10 11 12 - * ---|---------------------------------------------------- - * 0 | - * 1 | 46 30 - * 2 | 50 47 31 31 - * 3 | 54 51 48 38 35 32 - * 4 | 58 55 52 49 42 39 36 33 - * 5 | 59 56 53 62 43 40 37 - * 6 | 60 57 66 63 44 41 - * 7 | 61 70 67 64 45 - * 8 | 74 71 68 65 - * 9 | 75 72 69 - * 10 | 76 73 - * 11 | 77 - * 12 | - * - * C: tile_size = 4, input = aaaaccccgggg - * | 0 1 2 3 4 5 6 7 8 9 10 11 12 - * ---|---------------------------------------------------- - * 0 | 78 - * 1 | 79 - * 2 | 80 - * 3 | 81 - * 4 | 82 - * 5 | 83 - * 6 | 84 - * 7 | 85 - * 8 | 86 - * 9 | 87 - * 10 | 88 - * 11 | 89 - * 12 | 90 */ std::list *cyk_traversal_multithread_parallel(const AST &ast, Statement::Var_Decl *seq, std::string *tile_size, std::string *name_maxtilen, bool with_checkpoint, CYKmode mode) { + + std::string var_ol1 = VARNAME_OuterLoop1; + std::string var_ol2 = VARNAME_OuterLoop2; + std::string var_il2 = VARNAME_InnerLoop2; + size_t track = 0; // as openMP currently only works for single track grammars std::list *stmts = new std::list(); @@ -530,12 +476,6 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, // later parallel computation Expr::Vacc *idx_row = ast.grammar()->left_running_indices[track]; Expr::Vacc *idx_col = ast.grammar()->right_running_indices[track]; - if (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) { - idx_row = new Expr::Vacc(new std::string( - *idx_row->name() + OUTSIDE_IDX_SUFFIX)); - idx_col = new Expr::Vacc(new std::string( - *idx_col->name() + OUTSIDE_IDX_SUFFIX)); - } Expr::Base *row_start = idx_col->plus(new Expr::Const(1)); CYKloop row = get_for_row(idx_row, row_start, z, with_checkpoint, mode); @@ -545,7 +485,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, Expr::Base *start_z = new Expr::Const(0); if (with_checkpoint) { start_z = new Expr::Vacc(new std::string(std::string( - VARNAME_OuterLoop1) + "_start")); + var_ol1) + "_start")); } Statement::For *loop_z = get_for_openMP(z, start_z, new Expr::Vacc(name_maxtilen), &tile_size_decl); @@ -562,7 +502,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, "// force omp to wait for all threads to finish their current batch " "(of size tile_size)")); blk_omp->statements.push_back(new Statement::Var_Assign( - new Var_Acc::Plain(new std::string(VARNAME_OuterLoop1)), + new Var_Acc::Plain(new std::string(var_ol1)), start_z->plus(new Expr::Vacc(tile_size)))); blk_omp->statements.push_back(mutex_unlock()); loop_z->statements.push_back(blk_omp); @@ -581,10 +521,10 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, if (with_checkpoint) { start_y = new Expr::Cond( new Expr::Vacc(new std::string(std::string( - VARNAME_InnerLoop2) + "_loaded")), + var_il2) + "_loaded")), z, new Expr::Vacc(new std::string(std::string( - VARNAME_InnerLoop2) + "_start"))); + var_il2) + "_start"))); } Statement::For *loop_y = get_for_openMP(y, start_y, new Expr::Vacc(name_maxtilen), &tile_size_decl); @@ -601,11 +541,11 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, "#pragma omp ordered")); Statement::Block *blk_omp2 = new Statement::Block(); blk_omp2->statements.push_back(new Statement::Var_Assign( - new Var_Acc::Plain(new std::string(VARNAME_InnerLoop2)), - (new Expr::Vacc(new std::string(VARNAME_InnerLoop2)))->plus( + new Var_Acc::Plain(new std::string(var_il2)), + (new Expr::Vacc(new std::string(var_il2)))->plus( new Expr::Vacc(tile_size)))); blk_omp2->statements.push_back(new Statement::Var_Assign( - new Var_Acc::Plain(new std::string(VARNAME_OuterLoop2)), z)); + new Var_Acc::Plain(new std::string(var_ol2)), z)); blk_omp2->statements.push_back(mutex_unlock()); loop_y->statements.push_back(blk_omp2); } @@ -614,7 +554,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, Expr::Vacc *start_z2 = new Expr::Vacc(tile_size); if (with_checkpoint) { start_z2 = new Expr::Vacc(new std::string(std::string( - VARNAME_OuterLoop2) + "_start")); + var_ol2) + "_start")); } loop_z = get_for_openMP(z, start_z2, new Expr::Vacc(name_maxtilen), &tile_size_decl); @@ -627,7 +567,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, loop_z->statements.push_back(loop_y); if (with_checkpoint) { loop_z->statements.push_back(new Statement::Var_Assign(new Var_Acc::Plain( - new std::string(VARNAME_InnerLoop2)), z)); + new std::string(var_il2)), z)); } stmts->push_back(loop_z); @@ -635,6 +575,227 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, return stmts; } +/* constructs two nested for-loops which realize a traversal of a square (or + * only the upper right triangle) such that it starts in the top right corner + * and follows the anti-diagonals, e.g. + * | 0 1 2 3 + * --|-------------- + * 0 | 6 3 1 0 + * 1 | 11 7 4 2 + * 2 | 17 12 8 5 + * 3 | 24 18 13 9 + * This order is necessary for outside computation, as all cells on top and + * right of a cell are predecessors. + */ +Statement::For *get_triag_traversal( + // variable name of outer for loop that addresses the anti diagonal + std::string name_diag, + // size of the square or triangle (4 in the above example) + Expr::Base *diameter, + std::string name_col, // variable name of column index + std::string name_row, // variable name of row index + bool full_square, // traverse a square or "just" the upper right triangle + // insert the "pragma omp for" statement within outer loop + bool insert_pragma, + // statements that shall be added to the inner loop, can be empty + std::list *nested_stmts, + // first anti diagonal to start with. If != 1 we can skip first x cells, + // e.g. diag_start=5 would start at cell 11 in above example + Expr::Base *diag_start) { + Expr::Base *tl = diameter; + + // tile_diag_x + Statement::Var_Decl *lv_diag = new Statement::Var_Decl( + new Type::Size(), + name_diag, + diag_start); + // short cut for tile_diag_x for variable access + Expr::Vacc *diag = new Expr::Vacc(*lv_diag); + + // t_x_j + Statement::Var_Decl *lv_j = new Statement::Var_Decl( + new Type::Size(), + name_col, + new Expr::Cond(new Expr::Less(diag, tl), tl->minus(diag), new Expr::Const(0))); + // short cut for t_x_j for variable access + Expr::Vacc *j = new Expr::Vacc(*lv_j); + + Expr::Less *cond_j = new Expr::Less(j, + new Expr::Cond( + new Expr::Less(diag, tl), + tl, + (new Expr::Times(tl, new Expr::Const(2)))->minus(diag))); + Statement::For *fl_j = new Statement::For(lv_j, cond_j); + fl_j->push_back(new Statement::Var_Decl( + new Type::Size(), + name_row, + diag->plus(j)->minus(tl))); + if (nested_stmts) { + fl_j->statements.insert(fl_j->statements.end(), nested_stmts->begin(), nested_stmts->end()); + } + + Expr::Base *diag_end = tl->plus(new Expr::Const(1)); + if (full_square) { + diag_end = new Expr::Times(tl, new Expr::Const(2)); + } + Expr::Less *cond_diag = new Expr::Less(diag, diag_end); + Statement::For *fl_diag = new Statement::For(lv_diag, cond_diag); +// if (ast.checkpoint && ast.checkpoint->cyk) { +// blk_parallel_outside->statements.push_back(new Statement::CustomCode( +// "#pragma omp for ordered schedule(dynamic)")); +// } else { + if (insert_pragma) { + fl_diag->statements.push_back(new Statement::CustomCode( + "#pragma omp for")); + } +// } + + fl_diag->statements.push_back(fl_j); + + return fl_diag; +} + +/* This function also constructs traversal structure for outside openMP code. + * + * A: tile_size = 4, input = aaaaccccgggg + * | 0 1 2 3 4 5 6 7 8 9 10 11 12 + * ---|--------------------------------------- + * 0 | 22 19 17 16 6 3 1 0 + * 1 | 26 23 20 18 10 7 4 2 + * 2 | 29 27 24 21 13 11 8 5 + * 3 | 31 30 28 25 15 14 12 9 + * 4 | 38 35 33 32 + * 5 | 42 39 36 34 + * 6 | 45 43 40 37 + * 7 | 47 46 44 41 + * 8 | + * 9 | + * 10 | + * 11 | + * 12 | + * + * + * B: tile_size = 4, input = aaaaccccgggg + * | 0 1 2 3 4 5 6 7 8 9 10 11 12 + * ---|--------------------------------------- + * 0 | 54 51 49 48 + * 1 | 55 52 50 + * 2 | 56 53 + * 3 | 57 + * 4 | 64 61 59 58 + * 5 | 65 62 60 + * 6 | 66 63 + * 7 | 67 + * 8 | 74 71 69 68 + * 9 | 75 72 70 + * 10 | 76 73 + * 11 | 77 + * 12 | + * + * + * C: tile_size = 4, input = aaaaccccgggg + * | 0 1 2 3 4 5 6 7 8 9 10 11 12 + * ---|--------------------------------------- + * 0 | 78 + * 1 | 79 + * 2 | 80 + * 3 | 81 + * 4 | 82 + * 5 | 83 + * 6 | 84 + * 7 | 85 + * 8 | 86 + * 9 | 87 + * 10 | 88 + * 11 | 89 + * 12 | 90 + * + */ + std::list *cyk_traversal_multithread_outside(const AST &ast, + Expr::Base *seqsize, std::string *tile_size, + Statement::Var_Decl *max_tiles, bool with_checkpoint, CYKmode mode, std::string part) { + +// std::string var_ol1 = VARNAME_OuterLoop1; +// std::string var_ol2 = VARNAME_OuterLoop2; +// std::string var_il2 = VARNAME_InnerLoop2; +// if (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) { +// var_ol1 += OUTSIDE_IDX_SUFFIX; +// var_ol2 += OUTSIDE_IDX_SUFFIX; +// var_il2 += OUTSIDE_IDX_SUFFIX; +// } + + size_t track = 0; // as openMP currently only works for single track grammars + std::list *stmts = new std::list(); + + if (part == "A") { + // part A: square tiles + std::list *for_tile = new std::list(); + for_tile->push_back(get_triag_traversal( + std::string("tile_diag_" + std::to_string(track)), + new Expr::Vacc(tile_size), + std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + true, + false, + nullptr, + new Expr::Const(1) + )); + + stmts->push_back(get_triag_traversal( + std::string("matrix_diag_" + std::to_string(track)), + new Expr::Vacc(*max_tiles), + "y", + "x", + false, + true, + for_tile, + new Expr::Const(1) + )); + } + + if (part == "B") { + // part B: triangular tiles at edge + Statement::For *for_tile_b = get_triag_traversal( + std::string("tile_diag_" + std::to_string(track)), + new Expr::Vacc(tile_size), + std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + false, + false, + nullptr, + new Expr::Const(1) + ); + + stmts->push_back(new Statement::CustomCode( + "#pragma omp for")); + Statement::Var_Decl *lv_diag = new Statement::Var_Decl( + new Type::Int(), "y", (new Expr::Const(0))->minus(new Expr::Const(1))); // one left of leftmost tile + Statement::For *fl_diag = new Statement::For( + lv_diag, + new Expr::Less(new Expr::Vacc(*lv_diag), new Expr::Vacc(*max_tiles))); + fl_diag->statements.push_back(new Statement::Var_Decl(new Type::Int(), "x", (new Expr::Vacc(*lv_diag))->plus(new Expr::Const(1)))); + fl_diag->statements.push_back(for_tile_b); + stmts->push_back(fl_diag); + } + + if (part == "C") { + // part C: serial part to fill remaining gapc + Statement::For *for_tile_c = get_triag_traversal( + std::string("diag_" + std::to_string(track)), + seqsize->plus(new Expr::Const(1)), + std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + false, + false, + nullptr, + (new Expr::Times(new Expr::Vacc(tile_size), (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus(new Expr::Const(1))))->plus(new Expr::Const(1)) + ); + stmts->push_back(for_tile_c); + } + + return stmts; + } + size_t count_nt_calls_and_loops(Statement::For *loop) { size_t res = 0; @@ -682,7 +843,8 @@ std::list *add_nt_calls(std::list &stmts, next_loop_vars->insert( next_loop_vars->end(), loop_vars->begin(), loop_vars->end()); if (((mode != CYKmode::OPENMP_PARALLEL) && - (mode != CYKmode::OPENMP_PARALLEL_OUTSIDE)) || + (mode != CYKmode::OPENMP_PARALLEL_OUTSIDE) && + (mode != CYKmode::OPENMP_SERIAL_OUTSIDE)) || (fl->var_decl->name->find("t_", 0) == 0)) { // openMP code adds in loops that do not traverse NT indices. Only add // loop variable, if it regard to NT indices, which all start with t_ @@ -765,8 +927,7 @@ std::list *add_nt_calls(std::list &stmts, } } nt_has_indices++; - if ((mode == CYKmode::SINGLETHREAD_OUTSIDE) || - (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { + if (mode == CYKmode::SINGLETHREAD_OUTSIDE) { // create t_X_seq.size() call Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); @@ -775,9 +936,14 @@ std::list *add_nt_calls(std::list &stmts, new std::string(*(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX))))->minus(seqsize)); } else if ((mode == CYKmode::OPENMP_PARALLEL_OUTSIDE)) { - Expr::Vacc *idx_j = new Expr::Vacc(new std::string( - *(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); - args->push_back(idx_j->plus(new Expr::Const(1))->minus(idx)); + Expr::Vacc *idx_i = new Expr::Vacc(new std::string( + *(*i)->left_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); + // t_0_i_outside + x*tile_size + args->push_back(idx_i->plus(new Expr::Times(new Expr::Vacc(new std::string("x")), new Expr::Vacc(&VARNAME_tile_size)))); + } else if ((mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { + Expr::Vacc *idx_i = new Expr::Vacc(new std::string( + *(*i)->left_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); + args->push_back(idx_i); } else { args->push_back(idx->minus(new Expr::Const(1))); } @@ -799,15 +965,23 @@ std::list *add_nt_calls(std::list &stmts, } nt_has_indices++; if ((mode == CYKmode::OPENMP_PARALLEL_OUTSIDE)) { + // (t_0_j_outside + y*tile_size + (t_0_seq.size() - num_tiles_per_axis*tile_size + 1)) + // create t_X_seq.size() call Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); dynamic_cast(seqsize)->add_arg((*it_stmt_seq)->name); dynamic_cast(seqsize)->is_obj = Bool(true); - Expr::Vacc *idx_i = new Expr::Vacc(new std::string( - *(*i)->left_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); + Expr::Vacc *idx_j = new Expr::Vacc(new std::string( + *(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); - args->push_back(seqsize->minus(idx_i)->plus(new Expr::Const(1))); + args->push_back(idx_j->plus(new Expr::Times(new Expr::Vacc(new std::string("y")), new Expr::Vacc(&VARNAME_tile_size)))->plus( + seqsize->minus(new Expr::Times(new Expr::Vacc(&VARNAME_num_tiles_per_axis), new Expr::Vacc(&VARNAME_tile_size)))->plus(new Expr::Const(1)) + )); + } else if ((mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { + Expr::Vacc *idx_j = new Expr::Vacc(new std::string( + *(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); + args->push_back(idx_j); } else { args->push_back(idx); } @@ -937,26 +1111,38 @@ Fn_Def *print_CYK(const AST &ast) { // header if (ast.checkpoint && ast.checkpoint->cyk) { - fn_cyk->stmts.push_back(new Statement::CustomCode( - "bool " + std::string(VARNAME_OuterLoop1) + - "_loaded = !load_checkpoint || !" + VARNAME_OuterLoop1 + ";")); - fn_cyk->stmts.push_back(new Statement::CustomCode( - "bool " + std::string(VARNAME_OuterLoop2) + - "_loaded = !load_checkpoint || !" + VARNAME_OuterLoop2 + ";")); - fn_cyk->stmts.push_back(new Statement::CustomCode( - "int " + std::string(VARNAME_InnerLoop2) + - "_loaded = !load_checkpoint || !" + VARNAME_InnerLoop2 + ";")); - fn_cyk->stmts.push_back(new Statement::CustomCode( - "int " + std::string(VARNAME_OuterLoop1) + - "_start = (" + VARNAME_OuterLoop1 + "_loaded) ? 0 : " + - VARNAME_OuterLoop1 + ";")); - fn_cyk->stmts.push_back(new Statement::CustomCode( - "int " + std::string(VARNAME_OuterLoop2) + - "_start = (" + VARNAME_OuterLoop2 + "_loaded) ? tile_size : " + - VARNAME_OuterLoop2 + ";")); - fn_cyk->stmts.push_back(new Statement::CustomCode( - "int " + std::string(VARNAME_InnerLoop2) + - "_start = " + VARNAME_InnerLoop2 + ";")); + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + fn_cyk->stmts.push_back(new Statement::CustomCode( + "bool " + std::string(VARNAME_OuterLoop1) + suffix + + "_loaded = !load_checkpoint || !" + VARNAME_OuterLoop1 + suffix + + ";")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "bool " + std::string(VARNAME_OuterLoop2) + suffix + + "_loaded = !load_checkpoint || !" + VARNAME_OuterLoop2 + suffix + + ";")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "int " + std::string(VARNAME_InnerLoop2) + suffix + + "_loaded = !load_checkpoint || !" + VARNAME_InnerLoop2 + suffix + + ";")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "int " + std::string(VARNAME_OuterLoop1) + suffix + + "_start = (" + VARNAME_OuterLoop1 + suffix + "_loaded) ? 0 : " + + VARNAME_OuterLoop1 + suffix + ";")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "int " + std::string(VARNAME_OuterLoop2) + suffix + + "_start = (" + VARNAME_OuterLoop2 + suffix + + "_loaded) ? tile_size : " + + VARNAME_OuterLoop2 + suffix + ";")); + fn_cyk->stmts.push_back(new Statement::CustomCode( + "int " + std::string(VARNAME_InnerLoop2) + suffix + + "_start = " + VARNAME_InnerLoop2 + suffix + ";")); + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX; + } + } } fn_cyk->stmts.push_back(new Statement::CustomCode("#pragma omp parallel")); Statement::Block *blk_parallel = new Statement::Block(); @@ -1000,52 +1186,76 @@ Fn_Def *print_CYK(const AST &ast) { if (ast.outside_generation()) { fn_cyk->stmts.push_back(new Statement::CustomCode( "// ... now compute outside DP matrices")); + Expr::Vacc *tl = new Expr::Vacc(&VARNAME_tile_size); + /* since tiles shall always be complete squares, we cannot touch the main anti-diagonal + * and thus leave a triangular space. This triangle must be at most tile_size - 1 in size. + * We divide (without rest, since we operate on integer) the remaining sequence size by + * the tile_size and multiply with tile_size to obtain the suffix of the input sequence which + * can be tiled */ + Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); + dynamic_cast(seqsize)->add_arg((*ast.seq_decls.at(0)).name); + dynamic_cast(seqsize)->is_obj = Bool(true); + //max_tiles_n = ((t_0_seq.size() - (tile_size - 1)) / tile_size) * tile_size; + Statement::Var_Decl *max_tiles = new Statement::Var_Decl(new Type::Int, VARNAME_num_tiles_per_axis, new Expr::Div(seqsize->minus(tl->minus(new Expr::Const(1))), tl)); + fn_cyk->stmts.push_back(max_tiles); + fn_cyk->stmts.push_back(new Statement::CustomCode( "#pragma omp parallel")); Statement::Block *blk_parallel_outside = new Statement::Block(); - if (ast.checkpoint && ast.checkpoint->cyk) { - blk_parallel_outside->statements.push_back(new Statement::CustomCode( - "#pragma omp for ordered schedule(dynamic)")); - } else { - blk_parallel_outside->statements.push_back(new Statement::CustomCode( - "#pragma omp for")); - } blk_parallel_outside->statements.push_back(new Statement::CustomCode( "// OPENMP < 3 requires signed int here ...")); // parallel part - std::list *stmts_outside = - cyk_traversal_multithread_parallel(ast, *it_stmt_seq, - &VARNAME_tile_size, name_maxtilen, + // part A + std::list *stmts_outsideA = + cyk_traversal_multithread_outside(ast, seqsize, + &VARNAME_tile_size, max_tiles, ast.checkpoint && ast.checkpoint->cyk, - CYKmode::OPENMP_PARALLEL_OUTSIDE); + CYKmode::OPENMP_PARALLEL_OUTSIDE, "A"); // inject NT calls - std::list *new_stmts_outside = add_nt_calls( - *stmts_outside, new std::list(), + add_nt_calls( + *stmts_outsideA, new std::list(), ast.grammar()->topological_ord(), ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_PARALLEL_OUTSIDE, ast); - stmts_outside->insert(stmts_outside->end(), - new_stmts_outside->begin(), new_stmts_outside->end()); + blk_parallel_outside->statements.insert( + blk_parallel_outside->statements.end(), + stmts_outsideA->begin(), stmts_outsideA->end()); + // part B + std::list *stmts_outsideB = + cyk_traversal_multithread_outside(ast, seqsize, + &VARNAME_tile_size, max_tiles, + ast.checkpoint && ast.checkpoint->cyk, + CYKmode::OPENMP_PARALLEL_OUTSIDE, "B"); + add_nt_calls( + *stmts_outsideB, new std::list(), + ast.grammar()->topological_ord(), + ast.checkpoint && ast.checkpoint->cyk, + CYKmode::OPENMP_PARALLEL_OUTSIDE, ast); blk_parallel_outside->statements.insert( blk_parallel_outside->statements.end(), - stmts_outside->begin(), stmts_outside->end()); + stmts_outsideB->begin(), stmts_outsideB->end()); + blk_parallel_outside->statements.push_back(new Statement::CustomCode( "// end parallel")); fn_cyk->stmts.push_back(blk_parallel_outside); - // serial part - stmts = cyk_traversal_singlethread(ast, CYKmode::OPENMP_SERIAL_OUTSIDE); - // inject NT calls - std::list *new_serial_stmts = add_nt_calls( - *stmts, new std::list(), + // part C = serial part + std::list *stmts_outsideC = + cyk_traversal_multithread_outside(ast, seqsize, + &VARNAME_tile_size, max_tiles, + ast.checkpoint && ast.checkpoint->cyk, + CYKmode::OPENMP_SERIAL_OUTSIDE, "C"); + fn_cyk->stmts.insert( + fn_cyk->stmts.end(), + stmts_outsideC->begin(), stmts_outsideC->end()); + add_nt_calls( + *stmts_outsideC, new std::list(), ast.grammar()->topological_ord(), ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_SERIAL_OUTSIDE, ast); - stmts->insert(stmts->end(), new_serial_stmts->begin(), - new_serial_stmts->end()); - fn_cyk->stmts.insert(fn_cyk->stmts.end(), stmts->begin(), stmts->end()); + } } From a12ba1888ef2fb41a5970a55f53959a837c56486 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 26 May 2023 10:58:08 +0200 Subject: [PATCH 148/189] linting --- src/cyk.cc | 113 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 45 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index 8e73d1a93..7d1e4ec15 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -616,7 +616,8 @@ Statement::For *get_triag_traversal( Statement::Var_Decl *lv_j = new Statement::Var_Decl( new Type::Size(), name_col, - new Expr::Cond(new Expr::Less(diag, tl), tl->minus(diag), new Expr::Const(0))); + new Expr::Cond( + new Expr::Less(diag, tl), tl->minus(diag), new Expr::Const(0))); // short cut for t_x_j for variable access Expr::Vacc *j = new Expr::Vacc(*lv_j); @@ -631,7 +632,8 @@ Statement::For *get_triag_traversal( name_row, diag->plus(j)->minus(tl))); if (nested_stmts) { - fl_j->statements.insert(fl_j->statements.end(), nested_stmts->begin(), nested_stmts->end()); + fl_j->statements.insert(fl_j->statements.end(), + nested_stmts->begin(), nested_stmts->end()); } Expr::Base *diag_end = tl->plus(new Expr::Const(1)); @@ -711,10 +713,10 @@ Statement::For *get_triag_traversal( * 12 | 90 * */ - std::list *cyk_traversal_multithread_outside(const AST &ast, +std::list *cyk_traversal_multithread_outside(const AST &ast, Expr::Base *seqsize, std::string *tile_size, - Statement::Var_Decl *max_tiles, bool with_checkpoint, CYKmode mode, std::string part) { - + Statement::Var_Decl *max_tiles, bool with_checkpoint, CYKmode mode, + std::string part) { // std::string var_ol1 = VARNAME_OuterLoop1; // std::string var_ol2 = VARNAME_OuterLoop2; // std::string var_il2 = VARNAME_InnerLoop2; @@ -724,22 +726,24 @@ Statement::For *get_triag_traversal( // var_il2 += OUTSIDE_IDX_SUFFIX; // } - size_t track = 0; // as openMP currently only works for single track grammars - std::list *stmts = new std::list(); + // as openMP currently only works for single track grammars + size_t track = 0; + std::list *stmts = new std::list(); - if (part == "A") { + if (part == "A") { // part A: square tiles std::list *for_tile = new std::list(); for_tile->push_back(get_triag_traversal( std::string("tile_diag_" + std::to_string(track)), new Expr::Vacc(tile_size), - std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), - std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->right_running_indices[track])->name() + + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->left_running_indices[track])->name() + + OUTSIDE_IDX_SUFFIX), true, false, nullptr, - new Expr::Const(1) - )); + new Expr::Const(1))); stmts->push_back(get_triag_traversal( std::string("matrix_diag_" + std::to_string(track)), @@ -749,52 +753,60 @@ Statement::For *get_triag_traversal( false, true, for_tile, - new Expr::Const(1) - )); - } + new Expr::Const(1))); + } - if (part == "B") { + if (part == "B") { // part B: triangular tiles at edge Statement::For *for_tile_b = get_triag_traversal( std::string("tile_diag_" + std::to_string(track)), new Expr::Vacc(tile_size), - std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), - std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->right_running_indices[track])->name() + + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->left_running_indices[track])->name() + + OUTSIDE_IDX_SUFFIX), false, false, nullptr, - new Expr::Const(1) - ); + new Expr::Const(1)); stmts->push_back(new Statement::CustomCode( "#pragma omp for")); Statement::Var_Decl *lv_diag = new Statement::Var_Decl( - new Type::Int(), "y", (new Expr::Const(0))->minus(new Expr::Const(1))); // one left of leftmost tile + // one left of leftmost tile + new Type::Int(), "y", (new Expr::Const(0))->minus(new Expr::Const(1))); Statement::For *fl_diag = new Statement::For( lv_diag, new Expr::Less(new Expr::Vacc(*lv_diag), new Expr::Vacc(*max_tiles))); - fl_diag->statements.push_back(new Statement::Var_Decl(new Type::Int(), "x", (new Expr::Vacc(*lv_diag))->plus(new Expr::Const(1)))); + fl_diag->statements.push_back(new Statement::Var_Decl( + new Type::Int(), + "x", + (new Expr::Vacc(*lv_diag))->plus(new Expr::Const(1)))); fl_diag->statements.push_back(for_tile_b); stmts->push_back(fl_diag); - } + } - if (part == "C") { + if (part == "C") { // part C: serial part to fill remaining gapc Statement::For *for_tile_c = get_triag_traversal( std::string("diag_" + std::to_string(track)), seqsize->plus(new Expr::Const(1)), - std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), - std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->right_running_indices[track])->name() + + OUTSIDE_IDX_SUFFIX), + std::string(*(ast.grammar()->left_running_indices[track])->name() + + OUTSIDE_IDX_SUFFIX), false, false, nullptr, - (new Expr::Times(new Expr::Vacc(tile_size), (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus(new Expr::Const(1))))->plus(new Expr::Const(1)) - ); + (new Expr::Times( + new Expr::Vacc(tile_size), + (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus( + new Expr::Const(1))))->plus(new Expr::Const(1))); stmts->push_back(for_tile_c); - } + } - return stmts; - } + return stmts; +} size_t count_nt_calls_and_loops(Statement::For *loop) { @@ -939,7 +951,9 @@ std::list *add_nt_calls(std::list &stmts, Expr::Vacc *idx_i = new Expr::Vacc(new std::string( *(*i)->left_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); // t_0_i_outside + x*tile_size - args->push_back(idx_i->plus(new Expr::Times(new Expr::Vacc(new std::string("x")), new Expr::Vacc(&VARNAME_tile_size)))); + args->push_back(idx_i->plus(new Expr::Times( + new Expr::Vacc(new std::string("x")), + new Expr::Vacc(&VARNAME_tile_size)))); } else if ((mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { Expr::Vacc *idx_i = new Expr::Vacc(new std::string( *(*i)->left_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); @@ -965,7 +979,8 @@ std::list *add_nt_calls(std::list &stmts, } nt_has_indices++; if ((mode == CYKmode::OPENMP_PARALLEL_OUTSIDE)) { - // (t_0_j_outside + y*tile_size + (t_0_seq.size() - num_tiles_per_axis*tile_size + 1)) + // (t_0_j_outside + y*tile_size + (t_0_seq.size() - num_tiles_per_axis + // *tile_size + 1)) // create t_X_seq.size() call Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); @@ -975,9 +990,12 @@ std::list *add_nt_calls(std::list &stmts, Expr::Vacc *idx_j = new Expr::Vacc(new std::string( *(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); - args->push_back(idx_j->plus(new Expr::Times(new Expr::Vacc(new std::string("y")), new Expr::Vacc(&VARNAME_tile_size)))->plus( - seqsize->minus(new Expr::Times(new Expr::Vacc(&VARNAME_num_tiles_per_axis), new Expr::Vacc(&VARNAME_tile_size)))->plus(new Expr::Const(1)) - )); + args->push_back(idx_j->plus(new Expr::Times(new Expr::Vacc( + new std::string("y")), new Expr::Vacc(&VARNAME_tile_size)))->plus( + seqsize->minus(new Expr::Times( + new Expr::Vacc(&VARNAME_num_tiles_per_axis), + new Expr::Vacc(&VARNAME_tile_size)))->plus( + new Expr::Const(1)))); } else if ((mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { Expr::Vacc *idx_j = new Expr::Vacc(new std::string( *(*i)->right_indices.at(t)->vacc()->name() + OUTSIDE_IDX_SUFFIX)); @@ -1187,16 +1205,22 @@ Fn_Def *print_CYK(const AST &ast) { fn_cyk->stmts.push_back(new Statement::CustomCode( "// ... now compute outside DP matrices")); Expr::Vacc *tl = new Expr::Vacc(&VARNAME_tile_size); - /* since tiles shall always be complete squares, we cannot touch the main anti-diagonal - * and thus leave a triangular space. This triangle must be at most tile_size - 1 in size. - * We divide (without rest, since we operate on integer) the remaining sequence size by - * the tile_size and multiply with tile_size to obtain the suffix of the input sequence which - * can be tiled */ + /* since tiles shall always be complete squares, we cannot touch the main + * anti-diagonal and thus leave a triangular space. This triangle must be + * at most tile_size - 1 in size. + * We divide (without rest, since we operate on integer) the remaining + * sequence size by the tile_size and multiply with tile_size to obtain + * the suffix of the input sequence which can be tiled */ Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); - dynamic_cast(seqsize)->add_arg((*ast.seq_decls.at(0)).name); + dynamic_cast(seqsize)->add_arg( + (*ast.seq_decls.at(0)).name); dynamic_cast(seqsize)->is_obj = Bool(true); - //max_tiles_n = ((t_0_seq.size() - (tile_size - 1)) / tile_size) * tile_size; - Statement::Var_Decl *max_tiles = new Statement::Var_Decl(new Type::Int, VARNAME_num_tiles_per_axis, new Expr::Div(seqsize->minus(tl->minus(new Expr::Const(1))), tl)); + // max_tiles_n = ((t_0_seq.size() - (tile_size - 1)) / tile_size) * + // tile_size; + Statement::Var_Decl *max_tiles = new Statement::Var_Decl( + new Type::Int, + VARNAME_num_tiles_per_axis, + new Expr::Div(seqsize->minus(tl->minus(new Expr::Const(1))), tl)); fn_cyk->stmts.push_back(max_tiles); fn_cyk->stmts.push_back(new Statement::CustomCode( @@ -1255,7 +1279,6 @@ Fn_Def *print_CYK(const AST &ast) { ast.grammar()->topological_ord(), ast.checkpoint && ast.checkpoint->cyk, CYKmode::OPENMP_SERIAL_OUTSIDE, ast); - } } From 66008f30843ff08752c9961d23a5342d71683369 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Fri, 26 May 2023 21:56:10 +0200 Subject: [PATCH 149/189] handling for base case where input sequence is smaller than tile size --- src/cyk.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index 7d1e4ec15..ffc2c7a2f 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -798,10 +798,14 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, false, false, nullptr, - (new Expr::Times( - new Expr::Vacc(tile_size), - (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus( - new Expr::Const(1))))->plus(new Expr::Const(1))); + new Expr::Cond( + // test the case that input is smaller than a single tile + new Expr::Greater(seqsize, new Expr::Vacc(tile_size)), + (new Expr::Times( + new Expr::Vacc(tile_size), + (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus( + new Expr::Const(1))))->plus(new Expr::Const(1)), + new Expr::Const(1))); stmts->push_back(for_tile_c); } @@ -1220,10 +1224,15 @@ Fn_Def *print_CYK(const AST &ast) { Statement::Var_Decl *max_tiles = new Statement::Var_Decl( new Type::Int, VARNAME_num_tiles_per_axis, - new Expr::Div(seqsize->minus(tl->minus(new Expr::Const(1))), tl)); + new Expr::Cond( + new Expr::Less(tl, seqsize->minus(new Expr::Const(1))), + new Expr::Div(seqsize->minus(tl->minus(new Expr::Const(1))), tl), + new Expr::Const(0))); fn_cyk->stmts.push_back(max_tiles); - fn_cyk->stmts.push_back(new Statement::CustomCode( + Statement::If *input_large_enough = new Statement::If( + new Expr::Greater(seqsize, tl)); + input_large_enough->then.push_back(new Statement::CustomCode( "#pragma omp parallel")); Statement::Block *blk_parallel_outside = new Statement::Block(); blk_parallel_outside->statements.push_back(new Statement::CustomCode( @@ -1263,7 +1272,8 @@ Fn_Def *print_CYK(const AST &ast) { blk_parallel_outside->statements.push_back(new Statement::CustomCode( "// end parallel")); - fn_cyk->stmts.push_back(blk_parallel_outside); + input_large_enough->then.push_back(blk_parallel_outside); + fn_cyk->stmts.push_back(input_large_enough); // part C = serial part std::list *stmts_outsideC = From c191d95331b49cded291673245d788bb88a30db3 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 31 May 2023 08:37:37 +0200 Subject: [PATCH 150/189] handle another set of CYK openMP indices for outside programs --- src/checkpoint.hh | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index d5e6af0a0..1b0bffb2d 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -1002,9 +1002,10 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", // archive the indices of the prior iteration to ensure // that the whole iteration has been completed std::string suffix = ""; + std::string first_index = "i"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << "array_out << t_" << i << "_i" << suffix - << " " << (io == 0 ? "+" : "-") << " 1;" << endl; + stream << indent() << "array_out << t_" << i << "_" << first_index + << suffix << " " << (io == 0 ? "+" : "-") << " 1;" << endl; stream << indent() << "array_out << " << "(t_" << i << "_j" << suffix << " == 0 ? 0 : t_" << i << "_j" << suffix << " " << (io == 0 ? "-" : "+") << " 1);" << endl; @@ -1014,14 +1015,23 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", // TODO(sjanssen) why can't I use OUTSIDE_IDX_SUFFIX from cyk.hh // here? suffix = "_outside"; + first_index = "diag"; } } } stream << indent() << "#ifdef _OPENMP" << endl; inc_indent(); - stream << indent() << "array_out << outer_loop_1_idx;" << endl; - stream << indent() << "array_out << outer_loop_2_idx;" << endl; - stream << indent() << "array_out << inner_loop_2_idx;" << endl; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << "array_out << outer_loop_1_idx" << suffix << ";" << endl; + stream << indent() << "array_out << outer_loop_2_idx" << suffix << ";" << endl; + stream << indent() << "array_out << inner_loop_2_idx" << suffix << ";" << endl; + if (!outside) { + break; + } else { + suffix = "_outside"; + } + } dec_indent(); stream << indent() << "#endif" << endl; @@ -1074,23 +1084,33 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", "array_in(array_fin);" << endl; for (size_t i = 0; i < n_tracks; i++) { std::string suffix = ""; + std::string first_index = "i"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << "array_in >> t_" << i << "_i" << suffix - << ";" << endl; + stream << indent() << "array_in >> t_" << i << "_" << first_index + << suffix << ";" << endl; stream << indent() << "array_in >> t_" << i << "_j" << suffix << ";" << endl; if (!outside) { break; } else { suffix = "_outside"; + first_index = "diag"; } } } stream << indent() << "#ifdef _OPENMP" << endl; - stream << indent() << " array_in >> outer_loop_1_idx;" << endl; - stream << indent() << " array_in >> outer_loop_2_idx;" << endl; - stream << indent() << " array_in >> inner_loop_2_idx;" << endl; - stream << indent() << "#endif" << endl; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << " array_in >> outer_loop_1_idx" << suffix << ";" << endl; + stream << indent() << " array_in >> outer_loop_2_idx" << suffix << ";" << endl; + stream << indent() << " array_in >> inner_loop_2_idx" << suffix << ";" << endl; + if (!outside) { + break; + } else { + suffix = "_outside"; + } + } + stream << indent() << "#endif" << endl; stream << indent() << "array_fin.close();" << endl << endl; stream << indent() << "std::cerr << \"Info: Successfully loaded " << "cyk loop indices. \"" << endl; From af20cfded9dcc4d7c286bd2248c308a877289fba Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 31 May 2023 08:38:18 +0200 Subject: [PATCH 151/189] handle another set of CYK openMP indices for outside programs --- src/cpp.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/cpp.cc b/src/cpp.cc index b544e0d7f..a43974bcd 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -1611,6 +1611,7 @@ void Printer::Cpp::print_seq_init(const AST &ast) { for (Statement::Base *stmt : *std::get<0>(tile_stmts)) { stream << *stmt << endl; } + stream << *get_tile_computation_outside(ast.seq_decls.front()) << endl; delete max_tiles_n_var; } @@ -1623,25 +1624,57 @@ void Printer::Cpp::print_seq_init(const AST &ast) { << "(cyk_archive + \"_new\");" << endl << endl; stream << indent() << "#ifdef _OPENMP" << endl; inc_indent(); - stream << indent() << "outer_loop_1_idx = 0;" << endl; - stream << indent() << "outer_loop_2_idx = 0;" << endl; - stream << indent() << "inner_loop_2_idx = 0;" << endl; + std::string suffix = ""; + int start_ol1 = 0; + int start_ol2 = 0; + int start_il2 = 0; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << "outer_loop_1_idx" << suffix << " = " + << start_ol1 << ";" << endl; + stream << indent() << "outer_loop_2_idx" << suffix << " = " + << start_ol2 << ";" << endl; + stream << indent() << "inner_loop_2_idx" << suffix << " = " + << start_il2 << ";" << endl; + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX; + start_ol1 = -1; + start_ol2 = 1; + start_il2 = 0; + } + } for (size_t i = 0; i < ast.grammar()->axiom->tracks(); i++) { - stream << indent() << "t_" << i << "_i = 0;" << endl; - stream << indent() << "t_" << i << "_j = max_tiles_n;" << endl; + std::string suffix = ""; + std::string first_index = "i"; + std::string start_j = "max_tiles_n"; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << indent() << "t_" << i << "_" << first_index << suffix << " = 0;" << endl; + stream << indent() << "t_" << i << "_j" << suffix << " = " << start_j << ";" << endl; + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX; + first_index = "diag"; + start_j = "0"; + } + } } dec_indent(); stream << indent() << "#else" << endl; inc_indent(); for (size_t i = 0; i < ast.grammar()->axiom->tracks(); i++) { std::string suffix = ""; + std::string first_index = "i"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << "t_" << i << "_i" << suffix << " = 0;" << endl; + stream << indent() << "t_" << i << "_" << first_index << suffix + << " = 0;" << endl; stream << indent() << "t_" << i << "_j" << suffix << " = 0;" << endl; if (!ast.grammar()->is_partof_outside()) { break; } else { suffix = OUTSIDE_IDX_SUFFIX; + first_index = "diag"; } } } @@ -1980,6 +2013,7 @@ void Printer::Cpp::header(const AST &ast) { if (ast.cyk()) { stream << indent() << "unsigned int tile_size, max_tiles;" << endl; stream << indent() << "int max_tiles_n;" << endl; + stream << indent() << "int num_tiles_per_axis;" << endl; } if (ast.checkpoint && ast.checkpoint->cyk) { @@ -1988,21 +2022,37 @@ void Printer::Cpp::header(const AST &ast) { stream << indent() << "// indices for cyk loops" << endl; for (size_t t = 0; t < ast.grammar()->axiom->tracks(); t++) { std::string suffix = ""; + std::string first_index = "i"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << *type << " t_" << t << "_i" << suffix - << ";" << endl; + stream << indent() << *type << " t_" << t << "_" << first_index + << suffix << ";" << endl; stream << indent() << *type << " t_" << t << "_j" << suffix << ";" << endl; if (!ast.grammar()->is_partof_outside()) { break; } else { suffix = OUTSIDE_IDX_SUFFIX; + first_index = "diag"; } } } stream << "#ifdef _OPENMP" << endl; - stream << indent() << "int outer_loop_1_idx, outer_loop_2_idx, " - << "inner_loop_2_idx;" << endl; + stream << indent() << "int "; + std::string suffix = ""; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + stream << "outer_loop_1_idx" << suffix << ", " + << "outer_loop_2_idx" << suffix << ", " + << "inner_loop_2_idx" << suffix; + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + if (io == 0) { + stream << ", "; + } + suffix = OUTSIDE_IDX_SUFFIX; + } + } + stream << ";" << endl; stream << "#endif" << endl; delete type; } From 19587cad9946544a725ce75b6bb655497c561600 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 31 May 2023 08:38:46 +0200 Subject: [PATCH 152/189] unsuccessful attempt to add checkpointing to CYK openMP code generation --- src/cyk.cc | 213 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 159 insertions(+), 54 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index ffc2c7a2f..411dff22c 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -86,6 +86,30 @@ get_tile_computation(const AST &ast, std::string *name_maxtilen, return std::make_tuple(res, &VARNAME_tile_size); } +/* since tiles shall always be complete squares, we cannot touch the main + * anti-diagonal and thus leave a triangular space. This triangle must be + * at most tile_size - 1 in size. + * We divide (without rest, since we operate on integer) the remaining + * sequence size by the tile_size and multiply with tile_size to obtain + * the suffix of the input sequence which can be tiled */ +Statement::Var_Decl *get_tile_computation_outside( + Statement::Var_Decl *input_seq) { + Expr::Fn_Call *seqsize = new Expr::Fn_Call(new std::string("size")); + seqsize->add_arg(input_seq->name); + seqsize->is_obj = Bool(true); + + Expr::Vacc *tl = new Expr::Vacc(new std::string("tile_size")); + // max_tiles_n = ((t_0_seq.size() - (tile_size - 1)) / tile_size) * + // tile_size; + return new Statement::Var_Decl( + new Type::Int, + VARNAME_num_tiles_per_axis, + new Expr::Cond( + new Expr::Less(tl, seqsize->minus(new Expr::Const(1))), + new Expr::Div(seqsize->minus(tl->minus(new Expr::Const(1))), tl), + new Expr::Const(0))); +} + /* deep copy of a list of statements */ std::list *copy_statements( std::list *other) { @@ -392,7 +416,26 @@ std::list *cyk_traversal_singlethread(const AST &ast, return stmts; } +std::vector *get_wait_omp(std::string var_outer, std::string var_inner, Expr::Base *step_size, std::string *z, bool no_inner_loop) { + std::vector *stmts = new std::vector(); + stmts->push_back(new Statement::CustomCode( + "#pragma omp ordered")); + Statement::Block *blk_omp2 = new Statement::Block(); + blk_omp2->statements.push_back(new Statement::CustomCode("// force omp to wait for all threads to finish their current batch (of size tile_size)")); + if (!no_inner_loop) { + blk_omp2->statements.push_back(new Statement::Var_Assign( + new Var_Acc::Plain(new std::string(var_inner)), + (new Expr::Vacc(new std::string(var_inner)))->plus( + step_size))); + } + blk_omp2->statements.push_back(new Statement::Var_Assign( + new Var_Acc::Plain(new std::string(var_outer)), new Expr::Vacc(z))); + blk_omp2->statements.push_back(mutex_unlock()); + stmts->push_back(blk_omp2); + + return stmts; +} /* Construct the loop traversal structure for CYK parsing of one track in @@ -537,17 +580,8 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, loop_y->statements.push_back(x); loop_y->statements.push_back(colB.loop); if (with_checkpoint) { - loop_y->statements.push_back(new Statement::CustomCode( - "#pragma omp ordered")); - Statement::Block *blk_omp2 = new Statement::Block(); - blk_omp2->statements.push_back(new Statement::Var_Assign( - new Var_Acc::Plain(new std::string(var_il2)), - (new Expr::Vacc(new std::string(var_il2)))->plus( - new Expr::Vacc(tile_size)))); - blk_omp2->statements.push_back(new Statement::Var_Assign( - new Var_Acc::Plain(new std::string(var_ol2)), z)); - blk_omp2->statements.push_back(mutex_unlock()); - loop_y->statements.push_back(blk_omp2); + std::vector *omp_wait = get_wait_omp(var_ol2, var_il2, new Expr::Vacc(tile_size), z->name(), false); + loop_y->statements.insert(loop_y->statements.end(), omp_wait->begin(), omp_wait->end()); } @@ -587,6 +621,7 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, * This order is necessary for outside computation, as all cells on top and * right of a cell are predecessors. */ +enum OMP_OUTSIDE_CP {no, A, B, C}; Statement::For *get_triag_traversal( // variable name of outer for loop that addresses the anti diagonal std::string name_diag, @@ -601,23 +636,42 @@ Statement::For *get_triag_traversal( std::list *nested_stmts, // first anti diagonal to start with. If != 1 we can skip first x cells, // e.g. diag_start=5 would start at cell 11 in above example - Expr::Base *diag_start) { + Expr::Base *diag_start, + OMP_OUTSIDE_CP cp) { Expr::Base *tl = diameter; + Type::Base *type_diag = new Type::Size(); + if (cp == OMP_OUTSIDE_CP::A) { + diag_start = new Expr::Vacc(new std::string(std::string(VARNAME_OuterLoop2) + OUTSIDE_IDX_SUFFIX + "_start")); + } else if (cp == OMP_OUTSIDE_CP::C) { + type_diag = new Type::External(new std::string("")); + } // tile_diag_x Statement::Var_Decl *lv_diag = new Statement::Var_Decl( - new Type::Size(), + type_diag, name_diag, diag_start); // short cut for tile_diag_x for variable access Expr::Vacc *diag = new Expr::Vacc(*lv_diag); // t_x_j + Expr::Base *start_j = new Expr::Cond( + new Expr::Less(diag, tl), tl->minus(diag), new Expr::Const(0)); + if (cp == OMP_OUTSIDE_CP::A) { + start_j = new Expr::Cond( + new Expr::Vacc(new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX + "_loaded")), + start_j, + new Expr::Vacc(new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX + "_start"))); + } else if (cp == OMP_OUTSIDE_CP::C) { + start_j = new Expr::Cond( + new Expr::Vacc(new std::string(name_col + "_loaded++")), + start_j, + new Expr::Vacc(new std::string(name_col))); + } Statement::Var_Decl *lv_j = new Statement::Var_Decl( - new Type::Size(), + type_diag, name_col, - new Expr::Cond( - new Expr::Less(diag, tl), tl->minus(diag), new Expr::Const(0))); + start_j); // short cut for t_x_j for variable access Expr::Vacc *j = new Expr::Vacc(*lv_j); @@ -627,6 +681,12 @@ Statement::For *get_triag_traversal( tl, (new Expr::Times(tl, new Expr::Const(2)))->minus(diag))); Statement::For *fl_j = new Statement::For(lv_j, cond_j); + if ((cp == OMP_OUTSIDE_CP::A) || (cp == OMP_OUTSIDE_CP::C)) { + if (cp == OMP_OUTSIDE_CP::A) { + fl_j->statements.push_back(new Statement::CustomCode(std::string("++") + VARNAME_InnerLoop2 + OUTSIDE_IDX_SUFFIX + "_loaded;")); + } + fl_j->statements.push_back(mutex_lock()); + } fl_j->push_back(new Statement::Var_Decl( new Type::Size(), name_row, @@ -635,6 +695,10 @@ Statement::For *get_triag_traversal( fl_j->statements.insert(fl_j->statements.end(), nested_stmts->begin(), nested_stmts->end()); } + if (cp == OMP_OUTSIDE_CP::A) { + std::vector *omp_wait = get_wait_omp(std::string(VARNAME_OuterLoop2) + OUTSIDE_IDX_SUFFIX, std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX, new Expr::Const(1), new std::string(name_diag), false); + fl_j->statements.insert(fl_j->statements.end(), omp_wait->begin(), omp_wait->end()); + } Expr::Base *diag_end = tl->plus(new Expr::Const(1)); if (full_square) { @@ -646,14 +710,22 @@ Statement::For *get_triag_traversal( // blk_parallel_outside->statements.push_back(new Statement::CustomCode( // "#pragma omp for ordered schedule(dynamic)")); // } else { + std::string pragma = std::string("#pragma omp for"); + if (cp == OMP_OUTSIDE_CP::A) { + pragma += " ordered schedule(dynamic)"; + } if (insert_pragma) { - fl_diag->statements.push_back(new Statement::CustomCode( - "#pragma omp for")); + fl_diag->statements.push_back(new Statement::CustomCode(pragma)); } // } fl_diag->statements.push_back(fl_j); + if (cp == OMP_OUTSIDE_CP::A) { + fl_diag->statements.push_back(new Statement::Var_Assign(new Var_Acc::Plain( + new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX)), new Expr::Vacc(new std::string(name_diag)))); + } + return fl_diag; } @@ -718,7 +790,6 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, Statement::Var_Decl *max_tiles, bool with_checkpoint, CYKmode mode, std::string part) { // std::string var_ol1 = VARNAME_OuterLoop1; -// std::string var_ol2 = VARNAME_OuterLoop2; // std::string var_il2 = VARNAME_InnerLoop2; // if (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) { // var_ol1 += OUTSIDE_IDX_SUFFIX; @@ -743,7 +814,8 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, true, false, nullptr, - new Expr::Const(1))); + new Expr::Const(1), + OMP_OUTSIDE_CP::no)); stmts->push_back(get_triag_traversal( std::string("matrix_diag_" + std::to_string(track)), @@ -753,7 +825,8 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, false, true, for_tile, - new Expr::Const(1))); + new Expr::Const(1), + with_checkpoint ? OMP_OUTSIDE_CP::A : OMP_OUTSIDE_CP::no)); } if (part == "B") { @@ -768,45 +841,68 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, false, false, nullptr, - new Expr::Const(1)); - - stmts->push_back(new Statement::CustomCode( - "#pragma omp for")); + new Expr::Const(1), + with_checkpoint ? OMP_OUTSIDE_CP::B : OMP_OUTSIDE_CP::no); + + std::string pragma = "#pragma omp for"; + Expr::Base *diag_start = (new Expr::Const(0))->minus(new Expr::Const(1)); + if (with_checkpoint) { + pragma += " ordered schedule(dynamic)"; + diag_start = new Expr::Vacc(new std::string(std::string(VARNAME_OuterLoop1) + OUTSIDE_IDX_SUFFIX)); + } + stmts->push_back(new Statement::CustomCode(pragma)); Statement::Var_Decl *lv_diag = new Statement::Var_Decl( // one left of leftmost tile - new Type::Int(), "y", (new Expr::Const(0))->minus(new Expr::Const(1))); + new Type::Int(), "y", diag_start); Statement::For *fl_diag = new Statement::For( lv_diag, new Expr::Less(new Expr::Vacc(*lv_diag), new Expr::Vacc(*max_tiles))); + if (with_checkpoint) { + fl_diag->statements.push_back(mutex_lock()); + } fl_diag->statements.push_back(new Statement::Var_Decl( new Type::Int(), "x", (new Expr::Vacc(*lv_diag))->plus(new Expr::Const(1)))); fl_diag->statements.push_back(for_tile_b); + if (with_checkpoint) { + std::vector *omp_wait = get_wait_omp(std::string(VARNAME_OuterLoop1) + OUTSIDE_IDX_SUFFIX, std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX, new Expr::Const(1), lv_diag->name, true); + fl_diag->statements.insert(fl_diag->statements.end(), omp_wait->begin(), omp_wait->end()); + + } stmts->push_back(fl_diag); } if (part == "C") { // part C: serial part to fill remaining gapc - Statement::For *for_tile_c = get_triag_traversal( - std::string("diag_" + std::to_string(track)), - seqsize->plus(new Expr::Const(1)), - std::string(*(ast.grammar()->right_running_indices[track])->name() + + Expr::Base *start_diag = new Expr::Cond( + // test the case that input is smaller than a single tile + new Expr::Greater(seqsize, new Expr::Vacc(tile_size)), + (new Expr::Times( + new Expr::Vacc(tile_size), + (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus( + new Expr::Const(1))))->plus(new Expr::Const(1)), + new Expr::Const(1)); + std::string diag_name = std::string("t_" + std::to_string(track) + "_diag_outside"); + if (with_checkpoint) { + start_diag = new Expr::Cond( + new Expr::Vacc(new std::string("t_0_diag_outside_loaded++")), + start_diag, + new Expr::Vacc(new std::string(diag_name))); + } + Statement::For *for_tile_c = get_triag_traversal( + diag_name, + seqsize->plus(new Expr::Const(1)), + std::string(*(ast.grammar()->right_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), - std::string(*(ast.grammar()->left_running_indices[track])->name() + + std::string(*(ast.grammar()->left_running_indices[track])->name() + OUTSIDE_IDX_SUFFIX), - false, - false, - nullptr, - new Expr::Cond( - // test the case that input is smaller than a single tile - new Expr::Greater(seqsize, new Expr::Vacc(tile_size)), - (new Expr::Times( - new Expr::Vacc(tile_size), - (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus( - new Expr::Const(1))))->plus(new Expr::Const(1)), - new Expr::Const(1))); - stmts->push_back(for_tile_c); + false, + false, + nullptr, + start_diag, + with_checkpoint ? OMP_OUTSIDE_CP::C : OMP_OUTSIDE_CP::no); + stmts->push_back(for_tile_c); } return stmts; @@ -859,13 +955,20 @@ std::list *add_nt_calls(std::list &stmts, next_loop_vars->insert( next_loop_vars->end(), loop_vars->begin(), loop_vars->end()); if (((mode != CYKmode::OPENMP_PARALLEL) && - (mode != CYKmode::OPENMP_PARALLEL_OUTSIDE) && - (mode != CYKmode::OPENMP_SERIAL_OUTSIDE)) || + (mode != CYKmode::OPENMP_PARALLEL_OUTSIDE)) || (fl->var_decl->name->find("t_", 0) == 0)) { // openMP code adds in loops that do not traverse NT indices. Only add // loop variable, if it regard to NT indices, which all start with t_ // e.g. t_0_i or t_1_j - next_loop_vars->push_back(fl->var_decl->name); + if (mode == CYKmode::OPENMP_SERIAL_OUTSIDE) { + std::string *diagname = fl->var_decl->name; + if (diagname->find("diag") == 0) { + diagname->replace(4, 4, "i"); // "diag" -> "i" + next_loop_vars->push_back(diagname); + } + } else { + next_loop_vars->push_back(fl->var_decl->name); + } } std::list *new_stmts = add_nt_calls( fl->statements, next_loop_vars, orderedNTs, with_checkpoint, @@ -1017,7 +1120,7 @@ std::list *add_nt_calls(std::list &stmts, } } if (with_checkpoint) { - if (mode == CYKmode::OPENMP_SERIAL) { + if ((mode == CYKmode::OPENMP_SERIAL) || (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { nt_stmts->push_back(mutex_unlock()); } } @@ -1061,25 +1164,25 @@ Fn_Def *print_CYK(const AST &ast) { for (int io = 0; io < 2; ++io) { // iterate through inside and outside fn_cyk->stmts.push_back(new Statement::Var_Decl( new Type::Int(), - *(ast.grammar()->left_running_indices.at(track)->name()) + - suffix, new Expr::Or( + *(idx_i->name()) + suffix, + new Expr::Or( new Expr::Not(new Expr::Vacc( new std::string("load_checkpoint"))), new Expr::Not(idx_i)))); fn_cyk->stmts.push_back(new Statement::Var_Decl( new Type::Int(), - *(ast.grammar()->right_running_indices.at(track)->name()) + - suffix, new Expr::Or( + *(idx_j->name()) + suffix, + new Expr::Or( new Expr::Not(new Expr::Vacc(new std::string( "load_checkpoint"))), new Expr::Not(idx_j)))); if (!ast.grammar()->is_partof_outside()) { break; } else { - suffix = OUTSIDE_IDX_SUFFIX + suffix; idx_i = new Expr::Vacc(new std::string( - *idx_i->name() + OUTSIDE_IDX_SUFFIX)); + std::string("t_") + std::to_string(track) + + std::string("_diag") + OUTSIDE_IDX_SUFFIX)); idx_j = new Expr::Vacc(new std::string( *idx_j->name() + OUTSIDE_IDX_SUFFIX)); } @@ -1134,6 +1237,7 @@ Fn_Def *print_CYK(const AST &ast) { // header if (ast.checkpoint && ast.checkpoint->cyk) { std::string suffix = ""; + std::string step = "tile_size"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside fn_cyk->stmts.push_back(new Statement::CustomCode( "bool " + std::string(VARNAME_OuterLoop1) + suffix + @@ -1154,7 +1258,7 @@ Fn_Def *print_CYK(const AST &ast) { fn_cyk->stmts.push_back(new Statement::CustomCode( "int " + std::string(VARNAME_OuterLoop2) + suffix + "_start = (" + VARNAME_OuterLoop2 + suffix + - "_loaded) ? tile_size : " + + "_loaded) ? " + step + " : " + VARNAME_OuterLoop2 + suffix + ";")); fn_cyk->stmts.push_back(new Statement::CustomCode( "int " + std::string(VARNAME_InnerLoop2) + suffix + @@ -1163,6 +1267,7 @@ Fn_Def *print_CYK(const AST &ast) { break; } else { suffix = OUTSIDE_IDX_SUFFIX; + step = "1"; } } } From 4d64bc7e09d8598974ccdf42cb3dcef982de275a Mon Sep 17 00:00:00 2001 From: Fynn Muermanns Date: Tue, 6 Jun 2023 16:13:19 +0200 Subject: [PATCH 153/189] fix checkpointing + cyk + outside in single-thread case; multi-thread should work as well (need to do some more tests); fix linter errors --- src/checkpoint.hh | 37 +++++++++++++++++------- src/cpp.cc | 14 +++++++-- src/cyk.cc | 73 +++++++++++++++++++++++++++++++++++------------ src/cyk.hh | 3 ++ 4 files changed, 96 insertions(+), 31 deletions(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 1b0bffb2d..bc3ff696c 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -999,16 +999,17 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", stream << indent() << "boost::archive::text_oarchive " "array_out(array_fout);" << endl; for (size_t i = 0; i < n_tracks; i++) { - // archive the indices of the prior iteration to ensure - // that the whole iteration has been completed + // since a mutex is locked before every loop iteration that prevents + // any archiving before it is unlocked again, + // we can directly dump the indices without having to worry + // about potentially incomplete iterations std::string suffix = ""; std::string first_index = "i"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside stream << indent() << "array_out << t_" << i << "_" << first_index - << suffix << " " << (io == 0 ? "+" : "-") << " 1;" << endl; + << suffix << ";" << endl; stream << indent() << "array_out << " - << "(t_" << i << "_j" << suffix << " == 0 ? 0 : t_" << i << "_j" - << suffix << " " << (io == 0 ? "-" : "+") << " 1);" << endl; + << "t_" << i << "_j" << suffix << ";" << endl; if (!outside) { break; } else { @@ -1016,6 +1017,10 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", // here? suffix = "_outside"; first_index = "diag"; + if (io == 0) { + stream << indent() << "array_out << " + << "t_" << i << "_i" << suffix << ";" << endl; + } } } } @@ -1023,9 +1028,12 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", inc_indent(); std::string suffix = ""; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << "array_out << outer_loop_1_idx" << suffix << ";" << endl; - stream << indent() << "array_out << outer_loop_2_idx" << suffix << ";" << endl; - stream << indent() << "array_out << inner_loop_2_idx" << suffix << ";" << endl; + stream << indent() << "array_out << outer_loop_1_idx" + << suffix << ";" << endl; + stream << indent() << "array_out << outer_loop_2_idx" + << suffix << ";" << endl; + stream << indent() << "array_out << inner_loop_2_idx" + << suffix << ";" << endl; if (!outside) { break; } else { @@ -1095,15 +1103,22 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", } else { suffix = "_outside"; first_index = "diag"; + if (io == 0) { + stream << indent() << "array_in >> " + << "t_" << i << "_i" << suffix << ";" << endl; + } } } } stream << indent() << "#ifdef _OPENMP" << endl; std::string suffix = ""; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << " array_in >> outer_loop_1_idx" << suffix << ";" << endl; - stream << indent() << " array_in >> outer_loop_2_idx" << suffix << ";" << endl; - stream << indent() << " array_in >> inner_loop_2_idx" << suffix << ";" << endl; + stream << indent() << " array_in >> outer_loop_1_idx" + << suffix << ";" << endl; + stream << indent() << " array_in >> outer_loop_2_idx" + << suffix << ";" << endl; + stream << indent() << " array_in >> inner_loop_2_idx" + << suffix << ";" << endl; if (!outside) { break; } else { diff --git a/src/cpp.cc b/src/cpp.cc index a43974bcd..02cea05c8 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -1649,8 +1649,10 @@ void Printer::Cpp::print_seq_init(const AST &ast) { std::string first_index = "i"; std::string start_j = "max_tiles_n"; for (int io = 0; io < 2; ++io) { // iterate through inside and outside - stream << indent() << "t_" << i << "_" << first_index << suffix << " = 0;" << endl; - stream << indent() << "t_" << i << "_j" << suffix << " = " << start_j << ";" << endl; + stream << indent() << "t_" << i << "_" + << first_index << suffix << " = 0;" << endl; + stream << indent() << "t_" << i << "_j" + << suffix << " = " << start_j << ";" << endl; if (!ast.grammar()->is_partof_outside()) { break; } else { @@ -1675,6 +1677,10 @@ void Printer::Cpp::print_seq_init(const AST &ast) { } else { suffix = OUTSIDE_IDX_SUFFIX; first_index = "diag"; + if (io == 0) { + stream << indent() << "t_" << i << "_i" + << suffix << " = 0;" << endl; + } } } } @@ -2033,6 +2039,10 @@ void Printer::Cpp::header(const AST &ast) { } else { suffix = OUTSIDE_IDX_SUFFIX; first_index = "diag"; + if (io == 0) { + stream << indent() << *type << " t_" << t << "_i" << suffix + << ";" << endl; + } } } } diff --git a/src/cyk.cc b/src/cyk.cc index 411dff22c..24adbe93c 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -416,13 +416,17 @@ std::list *cyk_traversal_singlethread(const AST &ast, return stmts; } -std::vector *get_wait_omp(std::string var_outer, std::string var_inner, Expr::Base *step_size, std::string *z, bool no_inner_loop) { +std::vector *get_wait_omp( + std::string var_outer, std::string var_inner, Expr::Base *step_size, + std::string *z, bool no_inner_loop) { std::vector *stmts = new std::vector(); stmts->push_back(new Statement::CustomCode( "#pragma omp ordered")); Statement::Block *blk_omp2 = new Statement::Block(); - blk_omp2->statements.push_back(new Statement::CustomCode("// force omp to wait for all threads to finish their current batch (of size tile_size)")); + blk_omp2->statements.push_back( + new Statement::CustomCode("// force omp to wait for all threads to finish " + "their current batch (of size tile_size)")); if (!no_inner_loop) { blk_omp2->statements.push_back(new Statement::Var_Assign( new Var_Acc::Plain(new std::string(var_inner)), @@ -546,7 +550,8 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, "(of size tile_size)")); blk_omp->statements.push_back(new Statement::Var_Assign( new Var_Acc::Plain(new std::string(var_ol1)), - start_z->plus(new Expr::Vacc(tile_size)))); + (new Expr::Vacc(new std::string(var_ol1)))-> + plus(new Expr::Vacc(tile_size)))); blk_omp->statements.push_back(mutex_unlock()); loop_z->statements.push_back(blk_omp); } @@ -580,8 +585,11 @@ std::list *cyk_traversal_multithread_parallel(const AST &ast, loop_y->statements.push_back(x); loop_y->statements.push_back(colB.loop); if (with_checkpoint) { - std::vector *omp_wait = get_wait_omp(var_ol2, var_il2, new Expr::Vacc(tile_size), z->name(), false); - loop_y->statements.insert(loop_y->statements.end(), omp_wait->begin(), omp_wait->end()); + std::vector *omp_wait = + get_wait_omp(var_ol2, var_il2, new Expr::Vacc(tile_size), + z->name(), false); + loop_y->statements.insert(loop_y->statements.end(), + omp_wait->begin(), omp_wait->end()); } @@ -642,7 +650,9 @@ Statement::For *get_triag_traversal( Type::Base *type_diag = new Type::Size(); if (cp == OMP_OUTSIDE_CP::A) { - diag_start = new Expr::Vacc(new std::string(std::string(VARNAME_OuterLoop2) + OUTSIDE_IDX_SUFFIX + "_start")); + diag_start = new Expr::Vacc( + new std::string(std::string(VARNAME_OuterLoop2) + + OUTSIDE_IDX_SUFFIX + "_start")); } else if (cp == OMP_OUTSIDE_CP::C) { type_diag = new Type::External(new std::string("")); } @@ -659,9 +669,11 @@ Statement::For *get_triag_traversal( new Expr::Less(diag, tl), tl->minus(diag), new Expr::Const(0)); if (cp == OMP_OUTSIDE_CP::A) { start_j = new Expr::Cond( - new Expr::Vacc(new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX + "_loaded")), + new Expr::Vacc(new std::string(std::string(VARNAME_InnerLoop2) + + OUTSIDE_IDX_SUFFIX + "_loaded")), start_j, - new Expr::Vacc(new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX + "_start"))); + new Expr::Vacc(new std::string(std::string(VARNAME_InnerLoop2) + + OUTSIDE_IDX_SUFFIX + "_start"))); } else if (cp == OMP_OUTSIDE_CP::C) { start_j = new Expr::Cond( new Expr::Vacc(new std::string(name_col + "_loaded++")), @@ -683,7 +695,9 @@ Statement::For *get_triag_traversal( Statement::For *fl_j = new Statement::For(lv_j, cond_j); if ((cp == OMP_OUTSIDE_CP::A) || (cp == OMP_OUTSIDE_CP::C)) { if (cp == OMP_OUTSIDE_CP::A) { - fl_j->statements.push_back(new Statement::CustomCode(std::string("++") + VARNAME_InnerLoop2 + OUTSIDE_IDX_SUFFIX + "_loaded;")); + fl_j->statements.push_back( + new Statement::CustomCode(std::string("++") + VARNAME_InnerLoop2 + + OUTSIDE_IDX_SUFFIX + "_loaded;")); } fl_j->statements.push_back(mutex_lock()); } @@ -696,8 +710,12 @@ Statement::For *get_triag_traversal( nested_stmts->begin(), nested_stmts->end()); } if (cp == OMP_OUTSIDE_CP::A) { - std::vector *omp_wait = get_wait_omp(std::string(VARNAME_OuterLoop2) + OUTSIDE_IDX_SUFFIX, std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX, new Expr::Const(1), new std::string(name_diag), false); - fl_j->statements.insert(fl_j->statements.end(), omp_wait->begin(), omp_wait->end()); + std::vector *omp_wait = + get_wait_omp(std::string(VARNAME_OuterLoop2) + OUTSIDE_IDX_SUFFIX, + std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX, + new Expr::Const(1), new std::string(name_diag), false); + fl_j->statements.insert(fl_j->statements.end(), + omp_wait->begin(), omp_wait->end()); } Expr::Base *diag_end = tl->plus(new Expr::Const(1)); @@ -723,7 +741,8 @@ Statement::For *get_triag_traversal( if (cp == OMP_OUTSIDE_CP::A) { fl_diag->statements.push_back(new Statement::Var_Assign(new Var_Acc::Plain( - new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX)), new Expr::Vacc(new std::string(name_diag)))); + new std::string(std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX)), + new Expr::Vacc(new std::string(name_diag)))); } return fl_diag; @@ -848,7 +867,9 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, Expr::Base *diag_start = (new Expr::Const(0))->minus(new Expr::Const(1)); if (with_checkpoint) { pragma += " ordered schedule(dynamic)"; - diag_start = new Expr::Vacc(new std::string(std::string(VARNAME_OuterLoop1) + OUTSIDE_IDX_SUFFIX)); + diag_start = new Expr::Vacc(new std::string( + std::string(VARNAME_OuterLoop1) + + OUTSIDE_IDX_SUFFIX)); } stmts->push_back(new Statement::CustomCode(pragma)); Statement::Var_Decl *lv_diag = new Statement::Var_Decl( @@ -866,9 +887,12 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, (new Expr::Vacc(*lv_diag))->plus(new Expr::Const(1)))); fl_diag->statements.push_back(for_tile_b); if (with_checkpoint) { - std::vector *omp_wait = get_wait_omp(std::string(VARNAME_OuterLoop1) + OUTSIDE_IDX_SUFFIX, std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX, new Expr::Const(1), lv_diag->name, true); - fl_diag->statements.insert(fl_diag->statements.end(), omp_wait->begin(), omp_wait->end()); - + std::vector *omp_wait = + get_wait_omp(std::string(VARNAME_OuterLoop1) + OUTSIDE_IDX_SUFFIX, + std::string(VARNAME_InnerLoop2) + OUTSIDE_IDX_SUFFIX, + new Expr::Const(1), lv_diag->name, true); + fl_diag->statements.insert(fl_diag->statements.end(), + omp_wait->begin(), omp_wait->end()); } stmts->push_back(fl_diag); } @@ -883,7 +907,8 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, (new Expr::Vacc(&VARNAME_num_tiles_per_axis))->plus( new Expr::Const(1))))->plus(new Expr::Const(1)), new Expr::Const(1)); - std::string diag_name = std::string("t_" + std::to_string(track) + "_diag_outside"); + std::string diag_name = + std::string("t_" + std::to_string(track) + "_diag_outside"); if (with_checkpoint) { start_diag = new Expr::Cond( new Expr::Vacc(new std::string("t_0_diag_outside_loaded++")), @@ -1120,7 +1145,8 @@ std::list *add_nt_calls(std::list &stmts, } } if (with_checkpoint) { - if ((mode == CYKmode::OPENMP_SERIAL) || (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { + if ((mode == CYKmode::OPENMP_SERIAL) || + (mode == CYKmode::OPENMP_SERIAL_OUTSIDE)) { nt_stmts->push_back(mutex_unlock()); } } @@ -1180,6 +1206,17 @@ Fn_Def *print_CYK(const AST &ast) { if (!ast.grammar()->is_partof_outside()) { break; } else { + if (io == 0) { + std::string i_outside = *(idx_i->name()) + OUTSIDE_IDX_SUFFIX; + fn_cyk->stmts.push_back(new Statement::Var_Decl( + new Type::Int(), i_outside + "_loaded", + new Expr::Or( + new Expr::Not(new Expr::Vacc(new std::string( + "load_checkpoint"))), + new Expr::Not(new Expr::Vacc(new std::string( + i_outside)))))); + } + idx_i = new Expr::Vacc(new std::string( std::string("t_") + std::to_string(track) + std::string("_diag") + OUTSIDE_IDX_SUFFIX)); diff --git a/src/cyk.hh b/src/cyk.hh index 42d93ede2..a629521a9 100644 --- a/src/cyk.hh +++ b/src/cyk.hh @@ -45,6 +45,9 @@ std::tuple*, std::string*> get_tile_computation(const AST &ast, std::string *name_maxtilen, Statement::Var_Decl *input_seq, bool just_tilesize); +Statement::Var_Decl* +get_tile_computation_outside(Statement::Var_Decl *input_seq); + Fn_Def *print_CYK(const AST &ast); #endif /* SRC_CYK_HH_ */ From f47e389496d00cdaee6cb39f80c89cebb86a55cc Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 7 Jun 2023 23:03:47 +0200 Subject: [PATCH 154/189] try to reproduce my issue in github actions --- .github/workflows/reproduce_issue.yml | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/reproduce_issue.yml diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml new file mode 100644 index 000000000..b2ec3297f --- /dev/null +++ b/.github/workflows/reproduce_issue.yml @@ -0,0 +1,81 @@ +name: github action build & CI + +on: + push: + branches: [ outside_cyk_openMPcheckpoint ] + pull_request: + branches: [ outside_cyk_openMPcheckpoint ] + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + tags: + description: 'Test scenario tags' + +jobs: + gapc_ubuntu: + strategy: + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + # as of 21st Sep 2021, ubuntu-16.04 is no longer supported by github actions: https://github.blog/changelog/2021-04-29-github-actions-ubuntu-16-04-lts-virtual-environment-will-be-removed-on-september-20-2021/ + # 18.04 burnout: https://github.com/actions/runner-images/issues/6002 + os: [ubuntu-20.04, ubuntu-22.04] + runs-on: ${{ matrix.os }} + steps: + - name: Update apt + run: sudo apt-get update + - name: Install dependencies + run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip + + - uses: actions/checkout@v3 + with: + ref: outside_cyk_openMPcheckpoint + - name: configure + run: ./configure --prefix $GITHUB_WORKSPACE + - name: make + run: make -j 2 + - name: make install + run: sudo make install + + - name: run unger + run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga > unger_outside.res + + - name: run unger checkpoint + run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL --checkpoint && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga -p 0:0:0:1 > unger_outside_checkpoint.res + + - name: compare + run: diff unger_outside.res unger_outside_checkpoint.res + + gapc_osx: + strategy: + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + os: [macos-11] + runs-on: ${{ matrix.os }} + steps: + - name: Install dependencies + run: brew install bison@2.7 cmake boost gsl gnu-sed libomp gmp cabal-install + + - uses: actions/checkout@v3 + with: + ref: outside_cyk_openMPcheckpoint + - name: configure + run: ./configure --prefix $GITHUB_WORKSPACE + - name: patch configuration for OSX + run: gsed -E "s|^YACC = .+$|YACC = /usr/local/opt/bison@2.7/bin/bison|" -i config.mf && gsed -E "s|^SED = .+$|SED = /usr/local/opt/gnu-sed/libexec/gnubin/sed|" -i config.mf && gsed -E "s/ -D_XOPEN_SOURCE=500 / /" -i config.mf && gsed -E "s/ -std=c\+\+17 / -std=c\+\+11 /" -i config.mf + - name: make + run: make -j 3 + - name: make install + run: sudo make install + + - name: run unger + run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga > unger_outside.res + + - name: run unger checkpoint + run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL --checkpoint && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga -p 0:0:0:1 > unger_outside_checkpoint.res + + - name: compare + run: diff unger_outside.res unger_outside_checkpoint.res + From 5b6dad863679877652a9e7142ef4dc827890fc73 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 7 Jun 2023 23:11:01 +0200 Subject: [PATCH 155/189] adding Fynn's commands --- .github/workflows/reproduce_issue.yml | 62 +++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml index b2ec3297f..b6df831e9 100644 --- a/.github/workflows/reproduce_issue.yml +++ b/.github/workflows/reproduce_issue.yml @@ -2,9 +2,9 @@ name: github action build & CI on: push: - branches: [ outside_cyk_openMPcheckpoint ] + branches: [ outside_cyk_openMPcheckpoint_issue ] pull_request: - branches: [ outside_cyk_openMPcheckpoint ] + branches: [ outside_cyk_openMPcheckpoint_issue ] workflow_dispatch: inputs: logLevel: @@ -31,7 +31,7 @@ jobs: - uses: actions/checkout@v3 with: - ref: outside_cyk_openMPcheckpoint + ref: outside_cyk_openMPcheckpoint_issue - name: configure run: ./configure --prefix $GITHUB_WORKSPACE - name: make @@ -39,6 +39,32 @@ jobs: - name: make install run: sudo make install + - name: Fynn + run: | + gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap + make -f ref.mf + ./ref guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > correct.txt + gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap + make -f ref_cyk.mf + ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt + gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap + CPPFLAGS="-fopenmp" make -f ref_cyk_parallel.mf + ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt + diff correct.txt cmp_1.txt + diff correct.txt cmp_2.txt + gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap + make -f cp_regular.mf + ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_3.txt + gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap + make -f cp_cyk.mf + ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_4.txt + gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap + CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf + ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_5.txt + diff correct.txt cmp_3.txt + diff correct.txt cmp_4.txt + diff correct.txt cmp_5.txt + - name: run unger run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga > unger_outside.res @@ -48,6 +74,7 @@ jobs: - name: compare run: diff unger_outside.res unger_outside_checkpoint.res + gapc_osx: strategy: matrix: @@ -60,7 +87,7 @@ jobs: - uses: actions/checkout@v3 with: - ref: outside_cyk_openMPcheckpoint + ref: outside_cyk_openMPcheckpoint_issue - name: configure run: ./configure --prefix $GITHUB_WORKSPACE - name: patch configuration for OSX @@ -70,6 +97,33 @@ jobs: - name: make install run: sudo make install + - name: Fynn + run: | + gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap + make -f ref.mf + ./ref guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > correct.txt + gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap + make -f ref_cyk.mf + ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt + gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap + CPPFLAGS="-fopenmp" make -f ref_cyk_parallel.mf + ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt + diff correct.txt cmp_1.txt + diff correct.txt cmp_2.txt + gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap + make -f cp_regular.mf + ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_3.txt + gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap + make -f cp_cyk.mf + ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_4.txt + gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap + CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf + ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_5.txt + diff correct.txt cmp_3.txt + diff correct.txt cmp_4.txt + diff correct.txt cmp_5.txt + + - name: run unger run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga > unger_outside.res From 14c94d8ec7ac5898c93fd6bbf860913bac69d70f Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 7 Jun 2023 23:15:14 +0200 Subject: [PATCH 156/189] use the freshly compiled (but not installed) gapc binary --- .github/workflows/reproduce_issue.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml index b6df831e9..6b505a713 100644 --- a/.github/workflows/reproduce_issue.yml +++ b/.github/workflows/reproduce_issue.yml @@ -41,24 +41,24 @@ jobs: - name: Fynn run: | - gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap make -f ref.mf ./ref guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > correct.txt - gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap make -f ref_cyk.mf ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt - gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap CPPFLAGS="-fopenmp" make -f ref_cyk_parallel.mf ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt diff correct.txt cmp_1.txt diff correct.txt cmp_2.txt - gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap make -f cp_regular.mf ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_3.txt - gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap make -f cp_cyk.mf ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_4.txt - gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_5.txt diff correct.txt cmp_3.txt @@ -99,24 +99,24 @@ jobs: - name: Fynn run: | - gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap make -f ref.mf ./ref guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > correct.txt - gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap make -f ref_cyk.mf ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt - gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap CPPFLAGS="-fopenmp" make -f ref_cyk_parallel.mf ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt diff correct.txt cmp_1.txt diff correct.txt cmp_2.txt - gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap make -f cp_regular.mf ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_3.txt - gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap make -f cp_cyk.mf ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_4.txt - gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap + ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_5.txt diff correct.txt cmp_3.txt From c96eb9fec9d9782ec31d9909230cb2e3f439af37 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 10 Jun 2023 23:53:54 +0200 Subject: [PATCH 157/189] set archiving interval to 1 sec in Fynn's tests --- .github/workflows/reproduce_issue.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml index 6b505a713..2d15ba9f9 100644 --- a/.github/workflows/reproduce_issue.yml +++ b/.github/workflows/reproduce_issue.yml @@ -54,13 +54,13 @@ jobs: diff correct.txt cmp_2.txt ./gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap make -f cp_regular.mf - ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_3.txt + ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_3.txt ./gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap make -f cp_cyk.mf - ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_4.txt + ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_4.txt ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf - ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_5.txt + ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_5.txt diff correct.txt cmp_3.txt diff correct.txt cmp_4.txt diff correct.txt cmp_5.txt @@ -112,13 +112,13 @@ jobs: diff correct.txt cmp_2.txt ./gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap make -f cp_regular.mf - ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_3.txt + ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_3.txt ./gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap make -f cp_cyk.mf - ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_4.txt + ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_4.txt ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf - ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_5.txt + ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_5.txt diff correct.txt cmp_3.txt diff correct.txt cmp_4.txt diff correct.txt cmp_5.txt From 9f91fcc3a6029546faf0f7998622b0d3fca1ddcc Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 11 Jun 2023 00:24:57 +0200 Subject: [PATCH 158/189] make OS work with openMP --- .github/workflows/reproduce_issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml index 2d15ba9f9..32715e984 100644 --- a/.github/workflows/reproduce_issue.yml +++ b/.github/workflows/reproduce_issue.yml @@ -106,7 +106,9 @@ jobs: make -f ref_cyk.mf ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt ./gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap - CPPFLAGS="-fopenmp" make -f ref_cyk_parallel.mf + CPPFLAGS_EXTRA=" -Xpreprocessor -fopenmp -lomp " + LDLIBS_EXTRA="-Xpreprocessor -fopenmp -lomp -I\"$(brew --prefix libomp)/include\" -L\"$(brew --prefix libomp)/lib\"" + make -f ref_cyk_parallel.mf ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt diff correct.txt cmp_1.txt diff correct.txt cmp_2.txt From 95b70d1555f7d8aec6f5470cf90bece77f94e222 Mon Sep 17 00:00:00 2001 From: Fynn Muermanns Date: Sun, 11 Jun 2023 00:40:26 +0200 Subject: [PATCH 159/189] also add mac openmp flags in checkpointed openmp cyk program --- .github/workflows/reproduce_issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml index 32715e984..40b2cf7bf 100644 --- a/.github/workflows/reproduce_issue.yml +++ b/.github/workflows/reproduce_issue.yml @@ -119,7 +119,9 @@ jobs: make -f cp_cyk.mf ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_4.txt ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap - CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf + CPPFLAGS_EXTRA=" -Xpreprocessor -fopenmp -lomp " + LDLIBS_EXTRA="-Xpreprocessor -fopenmp -lomp -I\"$(brew --prefix libomp)/include\" -L\"$(brew --prefix libomp)/lib\"" + make -f cp_cyk_parallel.mf ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_5.txt diff correct.txt cmp_3.txt diff correct.txt cmp_4.txt From 340b84cea1b75f656b72dd76a00285cc8a84b416 Mon Sep 17 00:00:00 2001 From: Fynn Muermanns Date: Sun, 11 Jun 2023 16:06:58 +0200 Subject: [PATCH 160/189] don't declare thread as mutable (doesn't need to be) --- src/checkpoint.hh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index bc3ff696c..881228121 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -1316,11 +1316,12 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", "every interval seconds" << endl; stream << indent() << "cancel_token.store(true);" << endl; if (cyk) { - stream << indent() << "std::thread([=, &cancel_token, &mutex]() " - << "mutable {" << endl; + stream << indent() + << "std::thread([this, interval, &cancel_token, &mutex]() {" + << endl; } else { - stream << indent() << "std::thread([=, &cancel_token] () " - << "mutable {" << endl; + stream << indent() + << "std::thread([this, interval, &cancel_token] () {" << endl; } stream << indent() << " while (cancel_token.load()) {" << endl; From 487f12b035b12d97f857623eba1a33f366f804f4 Mon Sep 17 00:00:00 2001 From: Fynn Muermanns Date: Sun, 11 Jun 2023 21:39:47 +0200 Subject: [PATCH 161/189] lock mutex before prints to avoid interference between stdout and stderr --- src/checkpoint.hh | 19 ++++++++++++------- src/cpp.cc | 11 ++++++++--- src/outside/codegen.cc | 10 +++++++++- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 881228121..ab4dfe8dc 100644 --- a/src/checkpoint.hh +++ b/src/checkpoint.hh @@ -1299,7 +1299,8 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", void archive_periodically(Printer::Base &stream, const nt_tables &tables) { inc_indent(); stream << indent() << "void archive_periodically(std::atomic_bool " - "&cancel_token, size_t interval" << endl; + "&cancel_token, size_t interval, " + << "std::mutex &print_mutex" << endl; if (cyk) { stream << indent() << " " << "#ifdef _OPENMP" << endl @@ -1315,20 +1316,24 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", stream << indent() << "// save all tables to the disk periodically " "every interval seconds" << endl; stream << indent() << "cancel_token.store(true);" << endl; + stream << indent() + << "std::thread([this, interval, &cancel_token, &print_mutex"; if (cyk) { - stream << indent() - << "std::thread([this, interval, &cancel_token, &mutex]() {" - << endl; - } else { - stream << indent() - << "std::thread([this, interval, &cancel_token] () {" << endl; + stream << ", &mutex"; } + stream << "] {" << endl; stream << indent() << " while (cancel_token.load()) {" << endl; stream << indent() << " std::this_thread::sleep_for(" "std::chrono::seconds(interval));" << endl; stream << indent() << " " "if (!cancel_token.load()) break;" << endl; + stream << indent() << " " + << "// need to aquire lock before printing to stderr in archive " + << "methods to avoid potential interference during " + << "simultaneous logging to stdout" << endl; + stream << indent() << " " + << "std::lock_guard print_lock(print_mutex);" << endl; if (cyk) { stream << indent() << " #ifdef _OPENMP" << endl; stream << indent() << " " diff --git a/src/cpp.cc b/src/cpp.cc index 02cea05c8..58cf819af 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -1836,8 +1836,8 @@ void Printer::Cpp::print_init_fn(const AST &ast) { stream << indent() << "}" << endl; } stream << indent() << "create_checkpoint_log(opts, arg_string);" << endl; - stream << indent() << "archive_periodically(cancel_token, "; - stream << "checkpoint_interval"; + stream << indent() << "archive_periodically(cancel_token, " + << "checkpoint_interval, print_mutex"; if (ast.checkpoint->cyk) { stream<< ", mutex"; } @@ -2004,6 +2004,7 @@ void Printer::Cpp::header(const AST &ast) { stream << indent() << "std::atomic_bool cancel_token;" << endl; stream << indent() << "bool keep_archives;" << endl; stream << indent() << "bool load_checkpoint;" << endl; + stream << indent() << "std::mutex print_mutex;" << endl; dec_indent(); } stream << indent() << " public:" << endl; @@ -2493,7 +2494,11 @@ void Printer::Cpp::print_value_pp(const AST &ast) { stream << indent() << '}' << endl; return; } - + if (ast.checkpoint && !ast.checkpoint->is_buddy && + !ast.outside_generation()) { + stream << indent() + << "std::lock_guard lock(print_mutex);" << endl; + } stream << indent() << "if (isEmpty(res)) {" << endl; inc_indent(); stream << indent() << "out << \"[]\\n\";" << endl; diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index ab6265bd2..18812cd3a 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -182,6 +182,14 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { stmts = &((*loops->rbegin())->statements); } + // need to aquire lock before printing to stdout to avoid potential + // interference during simultaneous logging to stderr during archiving + // of checkpoints + if (ast.checkpoint && !ast.checkpoint->is_buddy) { + stmts->push_back(new Statement::CustomCode( + "std::lock_guard lock(print_mutex);")); + } + stmts->push_back(new Statement::CustomCode( "out << \"start answers " + *nt->name + "(\"" + idx_param + "\"):\\n\";")); @@ -192,7 +200,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { // produce call of "print_result" Statement::Fn_Call *fnp = new Statement::Fn_Call("print_result"); - fnp->add_arg(new std::string("std::cout")); + fnp->add_arg(new std::string("out")); fnp->add_arg(res->name); stmts->push_back(fnp); From 227236132d7997ca1179247e8ea6781f1004c270 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 12 Jun 2023 09:53:14 +0200 Subject: [PATCH 162/189] no extra test --- .github/workflows/reproduce_issue.yml | 139 -------------------------- 1 file changed, 139 deletions(-) delete mode 100644 .github/workflows/reproduce_issue.yml diff --git a/.github/workflows/reproduce_issue.yml b/.github/workflows/reproduce_issue.yml deleted file mode 100644 index 40b2cf7bf..000000000 --- a/.github/workflows/reproduce_issue.yml +++ /dev/null @@ -1,139 +0,0 @@ -name: github action build & CI - -on: - push: - branches: [ outside_cyk_openMPcheckpoint_issue ] - pull_request: - branches: [ outside_cyk_openMPcheckpoint_issue ] - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - tags: - description: 'Test scenario tags' - -jobs: - gapc_ubuntu: - strategy: - matrix: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners - # as of 21st Sep 2021, ubuntu-16.04 is no longer supported by github actions: https://github.blog/changelog/2021-04-29-github-actions-ubuntu-16-04-lts-virtual-environment-will-be-removed-on-september-20-2021/ - # 18.04 burnout: https://github.com/actions/runner-images/issues/6002 - os: [ubuntu-20.04, ubuntu-22.04] - runs-on: ${{ matrix.os }} - steps: - - name: Update apt - run: sudo apt-get update - - name: Install dependencies - run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip - - - uses: actions/checkout@v3 - with: - ref: outside_cyk_openMPcheckpoint_issue - - name: configure - run: ./configure --prefix $GITHUB_WORKSPACE - - name: make - run: make -j 2 - - name: make install - run: sudo make install - - - name: Fynn - run: | - ./gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap - make -f ref.mf - ./ref guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > correct.txt - ./gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap - make -f ref_cyk.mf - ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt - ./gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap - CPPFLAGS="-fopenmp" make -f ref_cyk_parallel.mf - ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt - diff correct.txt cmp_1.txt - diff correct.txt cmp_2.txt - ./gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap - make -f cp_regular.mf - ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_3.txt - ./gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap - make -f cp_cyk.mf - ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_4.txt - ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap - CPPFLAGS="-fopenmp" make -f cp_cyk_parallel.mf - ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_5.txt - diff correct.txt cmp_3.txt - diff correct.txt cmp_4.txt - diff correct.txt cmp_5.txt - - - name: run unger - run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga > unger_outside.res - - - name: run unger checkpoint - run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL --checkpoint && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga -p 0:0:0:1 > unger_outside_checkpoint.res - - - name: compare - run: diff unger_outside.res unger_outside_checkpoint.res - - - gapc_osx: - strategy: - matrix: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners - os: [macos-11] - runs-on: ${{ matrix.os }} - steps: - - name: Install dependencies - run: brew install bison@2.7 cmake boost gsl gnu-sed libomp gmp cabal-install - - - uses: actions/checkout@v3 - with: - ref: outside_cyk_openMPcheckpoint_issue - - name: configure - run: ./configure --prefix $GITHUB_WORKSPACE - - name: patch configuration for OSX - run: gsed -E "s|^YACC = .+$|YACC = /usr/local/opt/bison@2.7/bin/bison|" -i config.mf && gsed -E "s|^SED = .+$|SED = /usr/local/opt/gnu-sed/libexec/gnubin/sed|" -i config.mf && gsed -E "s/ -D_XOPEN_SOURCE=500 / /" -i config.mf && gsed -E "s/ -std=c\+\+17 / -std=c\+\+11 /" -i config.mf - - name: make - run: make -j 3 - - name: make install - run: sudo make install - - - name: Fynn - run: | - ./gapc --outside_grammar ALL -o ref.cc testdata/grammar_outside/nodangle.gap - make -f ref.mf - ./ref guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > correct.txt - ./gapc --outside_grammar ALL --cyk -o ref_cyk.cc testdata/grammar_outside/nodangle.gap - make -f ref_cyk.mf - ./ref_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_1.txt - ./gapc --outside_grammar ALL --cyk -o ref_cyk_parallel.cc testdata/grammar_outside/nodangle.gap - CPPFLAGS_EXTRA=" -Xpreprocessor -fopenmp -lomp " - LDLIBS_EXTRA="-Xpreprocessor -fopenmp -lomp -I\"$(brew --prefix libomp)/include\" -L\"$(brew --prefix libomp)/lib\"" - make -f ref_cyk_parallel.mf - ./ref_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac > cmp_2.txt - diff correct.txt cmp_1.txt - diff correct.txt cmp_2.txt - ./gapc --outside_grammar ALL --checkpoint -o cp_regular.cc testdata/grammar_outside/nodangle.gap - make -f cp_regular.mf - ./cp_regular guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_3.txt - ./gapc --outside_grammar ALL --checkpoint -o cp_cyk.cc --cyk testdata/grammar_outside/nodangle.gap - make -f cp_cyk.mf - ./cp_cyk guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_4.txt - ./gapc --outside_grammar ALL --checkpoint -o cp_cyk_parallel.cc --cyk testdata/grammar_outside/nodangle.gap - CPPFLAGS_EXTRA=" -Xpreprocessor -fopenmp -lomp " - LDLIBS_EXTRA="-Xpreprocessor -fopenmp -lomp -I\"$(brew --prefix libomp)/include\" -L\"$(brew --prefix libomp)/lib\"" - make -f cp_cyk_parallel.mf - ./cp_cyk_parallel guugacguguacagucguagucguagucguaguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacuaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguagucguagcuguacgagggcuagucguagucugagucguagcugugucguagucguaucacuac -p 0:0:0:1 > cmp_5.txt - diff correct.txt cmp_3.txt - diff correct.txt cmp_4.txt - diff correct.txt cmp_5.txt - - - - name: run unger - run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga > unger_outside.res - - - name: run unger checkpoint - run: ./gapc testdata/grammar_outside/nodangle.gap --outside_grammar ALL --checkpoint && make -f out.mf && ./out uaucgguacuacgugacguugacguguaucgguacuacgugaacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacguga -p 0:0:0:1 > unger_outside_checkpoint.res - - - name: compare - run: diff unger_outside.res unger_outside_checkpoint.res - From 01f502aa15933def2d663aa198e7ef009bd47a61 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 12 Jun 2023 09:55:52 +0200 Subject: [PATCH 163/189] reference our elaborate github discussion of the std::cout issue --- src/outside/codegen.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 18812cd3a..9f41e76b2 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -185,6 +185,8 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { // need to aquire lock before printing to stdout to avoid potential // interference during simultaneous logging to stderr during archiving // of checkpoints + // for more details see: https://github.com/jlab/gapc/pull/215 and + // https://github.com/jlab/gapc/pull/213 if (ast.checkpoint && !ast.checkpoint->is_buddy) { stmts->push_back(new Statement::CustomCode( "std::lock_guard lock(print_mutex);")); From 5d9c8c8aaaaeb26bdf147f20f906e4b6eabe09ed Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Mon, 12 Jun 2023 12:02:17 +0200 Subject: [PATCH 164/189] clean up some old comments --- src/cyk.cc | 13 ------------- src/outside/codegen.hh | 1 - 2 files changed, 14 deletions(-) diff --git a/src/cyk.cc b/src/cyk.cc index 24adbe93c..1163f319e 100644 --- a/src/cyk.cc +++ b/src/cyk.cc @@ -724,10 +724,6 @@ Statement::For *get_triag_traversal( } Expr::Less *cond_diag = new Expr::Less(diag, diag_end); Statement::For *fl_diag = new Statement::For(lv_diag, cond_diag); -// if (ast.checkpoint && ast.checkpoint->cyk) { -// blk_parallel_outside->statements.push_back(new Statement::CustomCode( -// "#pragma omp for ordered schedule(dynamic)")); -// } else { std::string pragma = std::string("#pragma omp for"); if (cp == OMP_OUTSIDE_CP::A) { pragma += " ordered schedule(dynamic)"; @@ -735,7 +731,6 @@ Statement::For *get_triag_traversal( if (insert_pragma) { fl_diag->statements.push_back(new Statement::CustomCode(pragma)); } -// } fl_diag->statements.push_back(fl_j); @@ -808,14 +803,6 @@ std::list *cyk_traversal_multithread_outside(const AST &ast, Expr::Base *seqsize, std::string *tile_size, Statement::Var_Decl *max_tiles, bool with_checkpoint, CYKmode mode, std::string part) { -// std::string var_ol1 = VARNAME_OuterLoop1; -// std::string var_il2 = VARNAME_InnerLoop2; -// if (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) { -// var_ol1 += OUTSIDE_IDX_SUFFIX; -// var_ol2 += OUTSIDE_IDX_SUFFIX; -// var_il2 += OUTSIDE_IDX_SUFFIX; -// } - // as openMP currently only works for single track grammars size_t track = 0; std::list *stmts = new std::list(); diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh index 5cfbeaa0f..a497fb348 100644 --- a/src/outside/codegen.hh +++ b/src/outside/codegen.hh @@ -37,7 +37,6 @@ #include "../statement/fn_call.hh" #include "grammar_transformation.hh" - void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast); #endif // SRC_OUTSIDE_CODEGEN_HH_ From f2371f998101172f65046e6b3698d87c0060e989 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 13 Jun 2023 09:36:17 +0200 Subject: [PATCH 165/189] added missing type results for "is_terminal_type" function --- src/outside/grammar_transformation.cc | 34 ++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 80480b01b..e5bb74c82 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -148,13 +148,35 @@ bool is_terminal_type(Type::Base *t) { if (t->is(Type::SINGLE)) { return t->is_terminal(); } + if (t->is(Type::REFERENCABLE)) { // a pointer to an object + return (dynamic_cast(t)->base->is_terminal()); + } + if (t->is(Type::SIGNATURE) || // a basic ADP component + t->is(Type::TABLE) || // a DP matrix to store non-terminal results + t->is(Type::LIST) || // the answer list of an algebra function + t->is(Type::TUPLE) || // a pair of results + t->is(Type::CHOICE) || // flag an algebra function as a choice function + t->is(Type::RANGE) || // codegen, set of begin/end iterators + t->is(Type::SIZE) // internal type for code generation = unsigned int + ) { + return false; + } + if ((dynamic_cast(t)) || // the name of a new user defined tuple + (dynamic_cast(t)) || // definition of a new user type + (dynamic_cast(t)) || // a DP matrix, see Type::TABLE + (dynamic_cast(t)) // base class with a name + ) { + return false; + } + if (dynamic_cast(t)) { + // last resort, check if the base class is flagged a being a terminal + return t->is_terminal(); + } - /* TODO(sjanssen): I need to find out if following types are either terminals - * or not: Signature, Table, Base, List, Name, Tuple, Def, Choice, Size, - * Range, Table, Generic, Referencable - */ - assert(false && "I have been lazy and did not yet define if above mentioned" - " types are terminals or not"); + throw LogError(t->location, "Unknown Type, thus I cannot determine if it is " + "a terminal type or not. Please extend function " + "is_terminal_type in src/outside/grammar_transfo" + "rmation.cc of gapc sources!"); return false; } From 77afd35699798607dcef0e85b7314d1a56a255a0 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 13 Jun 2023 09:58:37 +0200 Subject: [PATCH 166/189] completed TODO --- src/outside/grammar_transformation.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index e5bb74c82..b6a2f4d1c 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -956,7 +956,6 @@ void Grammar::convert_to_outside() { } } - // TODO(smj): double check if this is necessary or at least do a silent test /* re-run "check_semantics" to properly initialize novel non- * terminals, links to non-terminals, update yield size analysis and * update table dimensions for NTs From e39272aac7e3bbb8e03ca1c1ea7659b35e31f583 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 13 Jun 2023 09:59:39 +0200 Subject: [PATCH 167/189] test what happens if table dims are not re-setted in grammar_transformation --- src/outside/grammar_transformation.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index b6a2f4d1c..5403c57f0 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -949,12 +949,12 @@ void Grammar::convert_to_outside() { * We therefore here reset the flag of all NTs to enable re-computation * of optimal table dimensions ... within the outside context. */ - for (hashtable::iterator i = NTs.begin(); - i != NTs.end(); ++i) { - if ((*i).second->is(Symbol::NONTERMINAL)) { - dynamic_cast((*i).second)->reset_table_dim(); - } - } +// for (hashtable::iterator i = NTs.begin(); +// i != NTs.end(); ++i) { +// if ((*i).second->is(Symbol::NONTERMINAL)) { +// dynamic_cast((*i).second)->reset_table_dim(); +// } +// } /* re-run "check_semantics" to properly initialize novel non- * terminals, links to non-terminals, update yield size analysis and From 9bebbeed5c53187333b365d89e8c9c8b28443bfc Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 13 Jun 2023 13:08:04 +0200 Subject: [PATCH 168/189] remove LOOPDEBUG prints and add documentation of the basic idea in middle_end --- src/alt.cc | 38 ----------------------- src/outside/middle_end.cc | 63 ++++++++++++++++++++++++++------------- src/symbol.cc | 15 ---------- 3 files changed, 43 insertions(+), 73 deletions(-) diff --git a/src/alt.cc b/src/alt.cc index cd90b87d0..774a6fc03 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -1075,25 +1075,6 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, const Yield::Size &ys, const Yield::Size &lhs, const Yield::Size &rhs, std::list &loops, bool for_outside_generation, bool outmost, bool is_left_not_right) { -#ifdef LOOPDEBUG - std::cerr << " next_index_var next_var="; - if (next_var) { - std::cerr << *next_var; - } else { - std::cerr << "NULL"; - } - std::cerr << ", last_var="; - if (last_var) { - std::cerr << *last_var; - } else { - std::cerr << "NULL"; - } - std::cerr << ", lhs=" << lhs; - std::cerr << ", ys=" << ys; - std::cerr << ", rhs=" << rhs; - std::cerr << ", outmost=" << (outmost ? "yes": "no"); -#endif - /* only for outside NTs: * If left/right of the rhs outside NT are grammar components with at least * one moving boundary, we need to start leftmost/rightmost with a new @@ -1115,15 +1096,8 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, outmost = false; } -#ifdef LOOPDEBUG - std::cerr << ", outmost_l2=" << (outmost ? "yes": "no"); -#endif - if ((ys.low() != ys.high()) || outmost) { if ((rhs.low() == rhs.high()) && !outmost) { -#ifdef LOOPDEBUG - std::cerr << " --> " << *right << "\n"; -#endif return right; } else { std::ostringstream o; @@ -1172,21 +1146,9 @@ Expr::Base *Alt::next_index_var(unsigned &k, size_t track, Statement::For *f = new Statement::For (loopvariable, cond); loops.push_back(f); -#ifdef LOOPDEBUG - std::cerr << " --> " << *ivar << "\n"; -#endif return ivar; } } else { -#ifdef LOOPDEBUG - std::cerr << " --> "; - if (next_var) { - std::cerr << *next_var; - } else { - std::cerr << "NULL"; - } - std::cerr << "\n"; -#endif return next_var; } } diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc index 33f713487..b506ed600 100644 --- a/src/outside/middle_end.cc +++ b/src/outside/middle_end.cc @@ -21,6 +21,49 @@ }}} */ +/* After transforming the inside grammar into a grammar that also contains + * outside non-terminals, we need to ensure that parser components (terminals + * and non-terminals) of algebra functions operate in reverse direction, i.e. + * from i,j towards left and right ends of the input sequence - instead of + * further splitting i,j into smaller pieces. + * + * For inside non-terminals we split a given subword i,j into multiple parts, + * e.g. bl(BASE, REGION, weak, BASE) will be split into + * bl({i}_BASE_{i+1}, {i+1}_REGION_{k1}, {k1}_weak_{k2}, {k2}_BASE_{k2+1}) + * --> two moving boundaries to split i,j into two variable parts + two + * constant BASE parts. Yield sizes dictate positions of moving boundaries. + * + * An outside non-terminal needs to "grow" towards left/right end of the input + * sequence, e.g. + * bl({k1+1}_BASE_{k1}, {k1}_REGION_{i}, {i}_outside_weak_{j}, {j}_BASE_{j+1}) + * + * It is important to know that by definition, only one outside non-terminal can + * occur on the r.h.s. of and outside non-terminal. Thus, this single r.h.s. + * outside non-terminal is the starting point from which indices need to be + * assigned independently towards left and right end of the input sequence. + * Furthermore, indices of this single r.h.s. outside non-terminal must be + * expanded to encompas the complete sub-word, e.g. + * ..., {i}_outside_weak_{j}, .... + * must become + * ..., {k1+1}_outside_weak_{j+1} + * for our example. + * + * Since production rules can be nested, e.g. + * cadd(incl(dangle), ml_comps1) + * (see testdata/grammar_outside/mini_twoLevelIL.gap for more complex examples) + * we operate in three phases here: + * 1) identify the single r.h.s. outside non-terminal and collect all + * "Parsers" (terminal or non-terminal) left and right of this pivotal + * element. + * functions: "outside_collect_parsers" + * 2) assign indices and moving boundaries from the pivotal parser towards + * the left/right ends of the input sequence + * function: "iterate_indices" + * 3) propagate the left/right-most indices to the single r.h.s. outside + * non-terminal (= the pivotal parser) + * functions: "outside_uppropagate_indices" + */ + #include "middle_end.hh" @@ -216,9 +259,6 @@ void iterate_indices(bool is_left_not_right, Yield::Size rhs_ys(rhs); rhs_ys += ys; -#ifdef LOOPDEBUG - std::cerr << (is_left_not_right ? "2" : "4") << ") "; -#endif next_var = Alt::next_index_var( k, track, next_var, last_var, upstream_index, ys, lhs, rhs, (*i)->simple_loops, true, false, is_left_not_right); @@ -293,17 +333,6 @@ void iterate_indices(bool is_left_not_right, void outside_init_indices( Alt::Base *alt, Expr::Vacc *left, Expr::Vacc *right, unsigned int &k, size_t track, Expr::Vacc *left_most, Expr::Vacc *right_most) { -#ifdef LOOPDEBUG - if (alt->is(Alt::SIMPLE)) { - std::cerr << " alt::Simple '" - << *(dynamic_cast(alt)->name) << "':\n"; - } else if (alt->is(Alt::LINK)) { - std::cerr << " alt::Link '" - << *(dynamic_cast(alt)->name) << "':\n"; - } else { - std::cerr << " alt '?':\n"; - } -#endif std::vector left_parser; std::vector right_parser; unsigned int num_outside_nts = 0; @@ -326,9 +355,6 @@ void outside_init_indices( // phase 2: based on the collected Parsers, assign left and right indices // to Parsers for grammar components LEFT of outside NT Yield::Size ys_all = sum_ys(left_parser, 0); -#ifdef LOOPDEBUG - std::cerr << "1) "; -#endif // +99 to ensure that we skip ALL elements of the left_parser list Yield::Size ys_lhs = sum_ys(left_parser, left_parser.size()+99); Yield::Size ys; @@ -342,9 +368,6 @@ void outside_init_indices( // for grammar components RIGHT of outside NT if (right_parser.size() > 0) { ys_all = sum_ys(right_parser, 0); -#ifdef LOOPDEBUG - std::cerr << "3) "; -#endif // +99 to ensure that we skip ALL elements of the right_parser list Yield::Size ys_rhs = sum_ys(right_parser, right_parser.size() + 99); diff --git a/src/symbol.cc b/src/symbol.cc index 97c29f9bd..d4defab6b 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -751,27 +751,12 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, left_indices[track] = left; right_indices[track] = right; -#ifdef LOOPDEBUG - std::cerr << "init_indices for NT " << *this->name - << ": (left=" << *left << ", right=" << *right << ")\n"; -#endif unsigned int c = 0; for (std::list::iterator i = alts.begin(); i != alts.end(); ++i, ++c) { if ((*i)->is_partof_outside()) { outside_init_indices(*i, left, right, k, track, left_most, right_most); } else { -#ifdef LOOPDEBUG - if ((*i)->is(Alt::SIMPLE)) { - std::cerr << " alt::Simple '" - << *(dynamic_cast(*i)->name) << "':\n"; - } else if ((*i)->is(Alt::LINK)) { - std::cerr << " alt::Link '" - << *(dynamic_cast(*i)->name) << "':\n"; - } else { - std::cerr << " alt '?':\n"; - } -#endif (*i)->init_indices(left, right, k, track); } } From 61da637ff7d944469b41b3044a963c57c39c0ed2 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 07:41:26 +0200 Subject: [PATCH 169/189] fixed "const fct(...)" --> "fct(...) const" --- src/alt.hh | 6 +++--- src/fn_arg.hh | 2 +- src/grammar.hh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/alt.hh b/src/alt.hh index 6fd1ead6d..1f9ea0147 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -338,7 +338,7 @@ class Base { virtual unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); - const bool is_partof_outside() { + bool is_partof_outside() const { return _is_partof_outside; } void set_partof_outside() { @@ -533,7 +533,7 @@ class Simple : public Base { public: void set_ntparas(std::list *l); - const std::list get_ntparas() { + std::list get_ntparas() const { return ntparas; } void remove_ntparas() { @@ -689,7 +689,7 @@ class Link : public Base { public: void set_ntparas(const Loc &loc, std::list *l); - const std::list get_ntparas() { + std::list get_ntparas() const { return ntparas; } void remove_ntparas() { diff --git a/src/fn_arg.hh b/src/fn_arg.hh index 215e2eae7..a4f6192b0 100644 --- a/src/fn_arg.hh +++ b/src/fn_arg.hh @@ -150,7 +150,7 @@ class Base { virtual void init_multi_ys() = 0; virtual const Yield::Multi &multi_ys() const { return m_ys; } - const bool is_partof_outside() { + bool is_partof_outside() const { return _is_partof_outside; } void set_partof_outside() { diff --git a/src/grammar.hh b/src/grammar.hh index d8e9b5cd3..397c77d83 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -232,7 +232,7 @@ class Grammar { */ void convert_to_outside(); - const bool is_partof_outside() { + bool is_partof_outside() const { return _is_partof_outside; } void set_partof_outside() { From 06a688dce38b679bdde8f68533d2bdf19bc83715 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 07:44:08 +0200 Subject: [PATCH 170/189] properly clean up object --- src/outside/grammar_transformation.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 5403c57f0..f6c6d7b8d 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -93,6 +93,8 @@ void Grammar::check_outside_requested_nonexisting_nts() { } throw LogError(this->location, msg); } + + delete warn_missing_nts; } // traverses the grammar and collect all algebra function names used From ef1be23bacbd2de83c46d71b0740c4d7e5386d49 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 14:18:39 +0200 Subject: [PATCH 171/189] use const instead of hard coding ALL --- src/gapc.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gapc.cc b/src/gapc.cc index 2427a35a8..3500fdadd 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -105,10 +105,10 @@ static void parse_options(int argc, char **argv, Options *rec) { "specialized GAP programs that recognize a subset of candidates of the " "original grammar.") ("outside_grammar", po::value< std::vector >(), - "generate an outside version of the grammar and report outside results " - "for an inside non-terminal. Provide multiple times for lists of " - "non-terminals or type \"ALL\" to report results for all non-" - "terminals.") + std::string("generate an outside version of the grammar and report " + "outside results for an inside non-terminal. Provide multiple times for " + "lists of non-terminals or type \"" + std::string(OUTSIDE_ALL) + "\" to " + "report results for all non-terminals.").c_str()) ("verbose", "show suppressed warnings and messages") ("log-level,l", po::value(), "the log level, valid values are 0 (VERBOSE), 1 (INFO), 2 (NORMAL), 3 " From c1d398ff3b2524c0143456fe59667ed2e1005178 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 14:32:14 +0200 Subject: [PATCH 172/189] make it really a constant --- src/cyk.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cyk.hh b/src/cyk.hh index a629521a9..85f5b2fce 100644 --- a/src/cyk.hh +++ b/src/cyk.hh @@ -39,7 +39,7 @@ #include "statement/fn_call.hh" #include "var_acc.hh" -static const char *OUTSIDE_IDX_SUFFIX = "_outside"; +static const char * const OUTSIDE_IDX_SUFFIX = "_outside"; std::tuple*, std::string*> get_tile_computation(const AST &ast, std::string *name_maxtilen, From 5249b7af31588fd8b71c6ede80041f859871d85d Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 14:32:37 +0200 Subject: [PATCH 173/189] omit Type::Name check --- src/outside/grammar_transformation.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index f6c6d7b8d..934a4de60 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -163,8 +163,7 @@ bool is_terminal_type(Type::Base *t) { ) { return false; } - if ((dynamic_cast(t)) || // the name of a new user defined tuple - (dynamic_cast(t)) || // definition of a new user type + if ((dynamic_cast(t)) || // definition of a new user type (dynamic_cast(t)) || // a DP matrix, see Type::TABLE (dynamic_cast(t)) // base class with a name ) { From 75df316ed30d933343065f46bd4640231e2423c6 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 14:32:55 +0200 Subject: [PATCH 174/189] make const --- src/outside/grammar_transformation.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh index e3fa7d179..be29f3aba 100644 --- a/src/outside/grammar_transformation.hh +++ b/src/outside/grammar_transformation.hh @@ -39,8 +39,8 @@ #include "../type/multi.hh" #include "../fn_arg.hh" -static const char *OUTSIDE_NT_PREFIX = "outside_"; -static const char *OUTSIDE_ALL = "ALL"; +static const char * const OUTSIDE_NT_PREFIX = "outside_"; +static const char * const OUTSIDE_ALL = "ALL"; // check if a type (used in Signature or Algebra) belongs to a terminal parser // or a non-terminal parser From 43de262e9b410a06aea1e177d73f058b7841e1b7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 14:40:33 +0200 Subject: [PATCH 175/189] clean up report_nts --- src/outside/codegen.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 9f41e76b2..229b7d6dd 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -225,5 +225,7 @@ void print_insideoutside_report_fn(Printer::Cpp &stream, const AST &ast) { stream << *fn << endl; stream.in_class = old_in_class; + + delete report_nts; } From d8be368af80e3840dcb1e8e3ef90d5f5a7bef433 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 14:40:44 +0200 Subject: [PATCH 176/189] avoid memory leaks --- src/outside/grammar_transformation.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index 934a4de60..dbb347321 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -550,6 +550,11 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { // remove all alternatives lhs_nt->alts.clear(); } + ~Flip_lhs_rhs_nonterminals() { + delete alt_clones; + delete lhs_nt->name; + delete lhs_nt; + } void visit(Alt::Base &alt) { if (alt.top_level) { // record the current top level alternative. Starting point for cloning @@ -681,6 +686,9 @@ struct Collect_and_Insert_outside_axioms : public Visitor { outside_nts(outside_nts) { terminating_lhs_nts = new std::set(); } + ~Collect_and_Insert_outside_axioms() { + delete terminating_lhs_nts; + } void visit(Alt::Link &alt) { /* also check that alt.nt is not NULL as at this stage outside NTs are not From fb9d861cca9f920b8a3eeb3951f7fa31efbe4b89 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 14 Jun 2023 15:19:47 +0200 Subject: [PATCH 177/189] do not delete lhs_nt->name --- src/outside/grammar_transformation.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc index dbb347321..9b656d7e3 100644 --- a/src/outside/grammar_transformation.cc +++ b/src/outside/grammar_transformation.cc @@ -552,7 +552,7 @@ struct Flip_lhs_rhs_nonterminals : public Visitor { } ~Flip_lhs_rhs_nonterminals() { delete alt_clones; - delete lhs_nt->name; + // delete lhs_nt->name; --> leads to failing mod_test_outside?! delete lhs_nt; } void visit(Alt::Base &alt) { From 287028b6c95f8560c599014997bc949f184c1657 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sat, 17 Jun 2023 16:03:38 +0200 Subject: [PATCH 178/189] more elaborate explanation about complete_track filter --- rtlib/filter.hh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rtlib/filter.hh b/rtlib/filter.hh index ee23e1ec8..8f37eb7d0 100644 --- a/rtlib/filter.hh +++ b/rtlib/filter.hh @@ -127,8 +127,15 @@ inline bool samesize(const Basic_Sequence &s1, return j1-i1 == j2-i2; } -// for the transition from outside parts of a outside generated grammar into -// the inside parts. +/* only for outside grammar generation: an outside parse (= a derivation + * starting at one of the outside_X non-terminals) at (i,j) consumes user input + * towards (0,n) by either extending towards the outside with another outside + * non-terminal or consumes subwords within (i,j) via inside non-terminals. + * Once the parse is maximal, we need to transition to the original inside + * rule that parsed the empty word to provide the recursion basis. This is what + * the complete_track filter ensures: the remaining input sub-word only + * "consumes" the empty word at the end, i.e. (n,n). + */ template inline bool complete_track( const Basic_Sequence &seq, T i, T j) { From 8eabb331be5dcc7af244b361b39ff9cabb17dde7 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 18 Jun 2023 12:34:03 +0200 Subject: [PATCH 179/189] better explanation --- rtlib/filter.hh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/rtlib/filter.hh b/rtlib/filter.hh index 8f37eb7d0..c149df9ea 100644 --- a/rtlib/filter.hh +++ b/rtlib/filter.hh @@ -127,14 +127,13 @@ inline bool samesize(const Basic_Sequence &s1, return j1-i1 == j2-i2; } -/* only for outside grammar generation: an outside parse (= a derivation - * starting at one of the outside_X non-terminals) at (i,j) consumes user input - * towards (0,n) by either extending towards the outside with another outside - * non-terminal or consumes subwords within (i,j) via inside non-terminals. - * Once the parse is maximal, we need to transition to the original inside - * rule that parsed the empty word to provide the recursion basis. This is what - * the complete_track filter ensures: the remaining input sub-word only - * "consumes" the empty word at the end, i.e. (n,n). +/* The recursion basis for outside candidates is the empty parse via the inside + * part of the user provided grammar (won't work if user grammar cannot parse + * the empty word!). However, an empty word could in principle be parsed between + * every two characters of the input. To enforce that this only happens after + * the complete track (= input sequence) has been consumed via outside parts, + * we apply this filter at the transition between outside and inside grammar + * parts, i.e. only at location (n,n). */ template inline bool complete_track( From f825f9d86fd1457add8f98aedcc90d4350cc85ad Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 18 Jun 2023 12:47:53 +0200 Subject: [PATCH 180/189] fix typo --- src/outside/codegen.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc index 229b7d6dd..161d9e7cf 100644 --- a/src/outside/codegen.cc +++ b/src/outside/codegen.cc @@ -25,10 +25,10 @@ std::list *NTs_to_report(const AST &ast) { - /* define which non-terminals shell be reported to the user + /* define which non-terminals shall be reported to the user * order of user arguments (--outside_grammar) shall take precedence over * NTs as occurring in source code of grammar. - * - User shell be warned, if outside version of NT has not been generated. + * - User shall be warned, if outside version of NT has not been generated. * This happens for NTs without rhs NTs. * - User was already informed about NTs he/she requested but are not part of * the grammar. */ From 86be4248163eae04049e45d378d82060f777e781 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Sun, 18 Jun 2023 12:48:03 +0200 Subject: [PATCH 181/189] add hint to plot-grammar --- src/gapc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gapc.cc b/src/gapc.cc index 3500fdadd..71e6b0c5c 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -108,7 +108,8 @@ static void parse_options(int argc, char **argv, Options *rec) { std::string("generate an outside version of the grammar and report " "outside results for an inside non-terminal. Provide multiple times for " "lists of non-terminals or type \"" + std::string(OUTSIDE_ALL) + "\" to " - "report results for all non-terminals.").c_str()) + "report results for all non-terminals.\nRefer to --plot-grammar should " + "you want 'see' the generated grammar.").c_str()) ("verbose", "show suppressed warnings and messages") ("log-level,l", po::value(), "the log level, valid values are 0 (VERBOSE), 1 (INFO), 2 (NORMAL), 3 " From 63bd6bf6dc5b220c613e874fd0e9f7ebe3ff3fe9 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 27 Jun 2023 09:14:56 +0200 Subject: [PATCH 182/189] increase test to avoid fails on OSx --- testdata/regresstest/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/regresstest/config b/testdata/regresstest/config index c98fc97e1..eaeb43efe 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -526,7 +526,7 @@ export OMP_NUM_THREADS check_new_old_eq adpf.gap unused count "uacgugacguugacguguaucgguacuacgugacguugacguguaucgguac" cyk_singletrack GAPC="../../../gapc --cyk --checkpoint" -check_checkpoint_eq adpf.gap unused pf "uacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguac" cyk_openmp_checkpoint 1 +check_checkpoint_eq adpf.gap unused pf "uacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuacgugacguugacguguaucgguacuguacugguacgugaucguguguacgggcgggggggggggggggggaucgaugcuguauguuuaucguguaugcguugacuggcgauguuauuauauaucugaucguagcguguaucgguacuacgugacguugacguguaucgguacuguacugguacgugaucguguguacgggcgggggggggggggggggaucgaugcuguauguuuaucguguaugcguugacuggcgauguuauuauauaucugaucguagcguguaucgguacuacgugacguugacguguaucgguacuguacugguacgugaucguguguacgggcgggggggggggggggggaucgaugcuguauguuuaucguguaugcguugacuggcgauguuauuauauaucugaucguagcuagcugacugauguugacguguacugaguugacguaugc" cyk_openmp_checkpoint 1 # deactivate openMP CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA" From 4d230d666d6af6fd978d16aac0ec537f86be6698 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 4 Jul 2023 15:50:33 +0200 Subject: [PATCH 183/189] linting --- testdata/gapc_filter/ext_hmm.hh | 73 ++++++++++----------------------- 1 file changed, 21 insertions(+), 52 deletions(-) diff --git a/testdata/gapc_filter/ext_hmm.hh b/testdata/gapc_filter/ext_hmm.hh index f9afeb5a1..a915d5289 100644 --- a/testdata/gapc_filter/ext_hmm.hh +++ b/testdata/gapc_filter/ext_hmm.hh @@ -1,6 +1,8 @@ #ifndef EXT_HMM_HH #define EXT_HMM_HH +#include + template inline T negexpsum(T t) { @@ -35,68 +37,35 @@ negexpsum(std::pair &p) { return negexpsum(p.first, p.second); } -const static double THRESHOLD = 0.000000001; -inline List_Ref > filterLowProbLabels(List_Ref > candidates_orig) { - //return candidates_orig; +static const double THRESHOLD = 0.000000001; +inline List_Ref > filterLowProbLabels( + List_Ref > candidates_orig) { + // return candidates_orig; // do nothing if there is just one candidate at all if (candidates_orig.ref().size() <= 1) { - return candidates_orig; + return candidates_orig; } List_Ref > candidates; // obtain most probable candidate up to here double bestValue = (*candidates_orig.ref().begin()).second; - for (List_Ref >::iterator i = candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { - if (bestValue > (*i).second) { - bestValue = (*i).second; - } + for (List_Ref >::iterator i = + candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { + if (bestValue > (*i).second) { + bestValue = (*i).second; + } } - // only keep candidates that are not smaller than the best candidate times THRESHOLD - // a value that should be changable by the user instead of hard coding it here - for (List_Ref >::iterator i = candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { - if ((*i).second <= (bestValue + log(1/THRESHOLD))) { - candidates.ref().push_back(*i); - } + /* only keep candidates that are not smaller than the best candidate times + * THRESHOLD a value that should be changable by the user instead of hard + * coding it here */ + for (List_Ref >::iterator i = + candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { + if ((*i).second <= (bestValue + log(1/THRESHOLD))) { + candidates.ref().push_back(*i); + } } return candidates; } -//template -//struct filterLowProbLabels2 { -// double bestValue; -// filterLowProbLabels2() : bestValue(0.0) { -// } -// void update(const T &src) { -// if (src.second > bestValue) { -// bestValue = src.second; -// } -// } -// bool ok(const T &x) const { -// return x.second <= lowProbabilityFilter(); -//// //sum = sum + x.second; -//// //return true; -//// double thresh = pow(22.56 * lowProbabilityFilter(), (x.first.size()-1)); -//// //double thresh = 0.1 * sum; -////// if (sum > 0) { -//// std::cerr << sum << ", " << x.second << "\t" << x.first << "\n"; -////// } -////// if (x.second != 1.0) { -////// std::cerr << (thresh > x.second) << "\t" << thresh << "\t" << x.second << "\n"; -////// } -//// //std::cerr << (pow(0.01, x.first.size())) << " " << x.second << "\n"; // "thresh: " << x.second << ", sum: " << sum << "\n"; -//// //return (sum > 0.01) || (count <= 1); -//// return true; //x.second > 0.3; -//// return (x.second > thresh) || (x.second == 1.0); -//// //return x.second > 0.5; -// } -//}; -// -//template -//inline double getPfuncValue(std::pair x) { -// return sum_elems(x.second.pf); -//} - - - -#endif +#endif // EXT_HMM_HH From 5cfa64477f078ba37e66f0ac742566875ae8be22 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Tue, 4 Jul 2023 15:53:20 +0200 Subject: [PATCH 184/189] remove unused function --- testdata/gapc_filter/isntimes.hh | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/testdata/gapc_filter/isntimes.hh b/testdata/gapc_filter/isntimes.hh index 7cb308693..9738d96a2 100644 --- a/testdata/gapc_filter/isntimes.hh +++ b/testdata/gapc_filter/isntimes.hh @@ -2,13 +2,13 @@ #define ISNTIMES_HH template -inline bool isntimes(const Basic_Sequence &seq, T i, T j, alphabet x, unsigned int size) -{ +inline bool isntimes(const Basic_Sequence &seq, T i, T j, + alphabet x, unsigned int size) { if (j &seq, T i, T j, al return true; } -//a filter to force that a parsed character corresponds to a nucleotide (and not a gap or some structure parts) -template -inline bool isAnyBase(const Basic_Sequence<> &seq, T i, T j) { - if (j Date: Tue, 4 Jul 2023 15:54:07 +0200 Subject: [PATCH 185/189] linting --- testdata/gapc_filter/isntimes.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testdata/gapc_filter/isntimes.hh b/testdata/gapc_filter/isntimes.hh index 9738d96a2..3a3e1e277 100644 --- a/testdata/gapc_filter/isntimes.hh +++ b/testdata/gapc_filter/isntimes.hh @@ -4,17 +4,17 @@ template inline bool isntimes(const Basic_Sequence &seq, T i, T j, alphabet x, unsigned int size) { - if (j Date: Tue, 4 Jul 2023 16:06:28 +0200 Subject: [PATCH 186/189] remove unused algebra function --- testdata/grammar_outside/mini_complexIL.gap | 29 +++------------------ 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/testdata/grammar_outside/mini_complexIL.gap b/testdata/grammar_outside/mini_complexIL.gap index 85de279c9..40508ab8b 100644 --- a/testdata/grammar_outside/mini_complexIL.gap +++ b/testdata/grammar_outside/mini_complexIL.gap @@ -3,10 +3,10 @@ import rna input rna signature sig_foldrna(alphabet,answer) { - answer nil(Subsequence); //empty structure - choice [answer] h([answer]); - answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair - answer comp(Subsequence, Subsequence, Subsequence, Subsequence, answer, Subsequence, answer); + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer comp(Subsequence, Subsequence, Subsequence, Subsequence, answer, Subsequence, answer); } algebra alg_count auto count; @@ -27,27 +27,6 @@ algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { } } -//algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { -// string nil(Subsequence loc) { -// string r; -// return r; -// } -// -// choice [string] h([string] i) { -// return i; -// } -// -// string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { -// string res; -// append(res, '('); -// append(res, '.', size(lregion)); -// append(res, e); -// append(res, '.', size(rregion)); -// append(res, ')'); -// return res; -// } -//} - grammar gra_nodangle uses sig_foldrna(axiom = struct) { struct = nil(LOC) | iloop From 524ced9a0a80fdd1847abbdd51fac19f0cec7ca0 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 5 Jul 2023 22:33:15 +0200 Subject: [PATCH 187/189] updating debian package --- debian/changelog | 301 +++++++++++++++++++++++++++++++++++++++++++++++ debian/copyright | 2 +- 2 files changed, 302 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 6c62da7f5..c58086d01 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,304 @@ +bellmansgapc (2023.07.05-0ubuntu0ppa1~xenial1) xenial; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + +bellmansgapc (2023.07.05-0ubuntu0ppa1~mantic1) mantic; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + +bellmansgapc (2023.07.05-0ubuntu0ppa1~lunar1) lunar; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + +bellmansgapc (2023.07.05-0ubuntu0ppa1~kinetic1) kinetic; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + +bellmansgapc (2023.07.05-0ubuntu0ppa1~jammy1) jammy; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + +bellmansgapc (2023.07.05-0ubuntu0ppa1~focal1) focal; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + +bellmansgapc (2023.07.05-0ubuntu0ppa1~bionic1) bionic; urgency=medium + + * features: + + --checkpoint: Thanks to Fynn Muermanns, gapc code generation can now add + generic code to periodically (e.g. every hour) dump + contents of the partially computed DP matrices to files. + Should an execution of a long running job abort + prematurely, the binary can be restarted and pick up + computation from the last dumped checkpoint. + + --plot-grammar: new levels of detail available for plotting the used + grammar. 4: adding yield size information for parsers, + 5: optimized table dimensions for non-terminals. + + automatically generated enum algebras will now also report non-terminal + parameters for better manual inspection + + --printCall can now be invoked with the generated binaries. Thus, the + binary will tell you which gapc command led to its + generation. Thanks to Fynn Muermanns. + + * maintenance: + + CYK code generation is now nicely abstracted into the source file + src/cyk.{cc,hh} instead of being intermingled in src/cpp.cc + + plot_grammar code is moved into a dedicated src/plot_grammar.cc file + + librna + - is exposing additional functions to support Guanine-Quadruplex energy + contribution calculation for RNA problems + - updated the ViennaRNA code base from 2.4.17 to 2.5.1, thanks to Fynn + Muermanns + - significant speed-ups due to clever hashing / pre-computation of energy + contributions, thanks to Fynn Muermanns. + + * fixes: + + --plot-grammar: + - properly escape & chars + - unfortunately, graphviz -> dot does not necessarily preserve child + node ordering. Using "clusters" mitigates (but does not solve in 100%) + this issue significantly + + fixed yield size computation of constant terminal parsers + + guards operate on *unsigned* int borders, which sometimes led + to underflows. + + warn users about negative candidate values when using expsum + + -- janssenlab Mon, 5 July 2023 22:30:00 +0200 + bellmansgapc (2022.07.04-0ubuntu0ppa1~bionic1) bionic; urgency=medium * the new command line parameter "plot-grammar" allows to generate an additional output file (default is out.dot) that contains GraphViz code that renders the chosen grammar in user defined level of detail (1 to 3). diff --git a/debian/copyright b/debian/copyright index 4aa0abb2c..60a7b8aaa 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,7 +8,7 @@ It was downloaded from: Upstream Author(s): - Stefan Janssen + Stefan Janssen Georg Sauthoff Copyright: From 84e1c61b4787c0e23ef0ae8e2b72e75466ba25c9 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 5 Jul 2023 23:04:31 +0200 Subject: [PATCH 188/189] also execute outside tests on OSX --- .github/workflows/outside.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.github/workflows/outside.yml b/.github/workflows/outside.yml index 8c36c4ff0..c379ece9b 100644 --- a/.github/workflows/outside.yml +++ b/.github/workflows/outside.yml @@ -32,3 +32,32 @@ jobs: - name: test-mod_outside run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu + + gapc_osx: + strategy: + matrix: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + os: [macos-11] + runs-on: ${{ matrix.os }} + steps: + - name: Install dependencies + run: brew install bison@2.7 cmake boost gsl gnu-sed libomp gmp cabal-install + - name: update cabal + run: cabal update + - name: add random Haskell lib + run: cabal install --lib random + - name: Checkout truth + run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + + - uses: actions/checkout@v3 + - name: configure + run: ./configure --prefix $GITHUB_WORKSPACE + - name: patch configuration for OSX + run: gsed -E "s|^YACC = .+$|YACC = /usr/local/opt/bison@2.7/bin/bison|" -i config.mf && gsed -E "s|^SED = .+$|SED = /usr/local/opt/gnu-sed/libexec/gnubin/sed|" -i config.mf && gsed -E "s/ -D_XOPEN_SOURCE=500 / /" -i config.mf && gsed -E "s/ -std=c\+\+17 / -std=c\+\+11 /" -i config.mf + - name: make + run: make -j 3 + - name: make install + run: sudo make install + + - name: test-mod_outside + run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_osx From d974b115ebd33c400b45713547c6f8e936fab416 Mon Sep 17 00:00:00 2001 From: Stefan Janssen Date: Wed, 5 Jul 2023 23:20:08 +0200 Subject: [PATCH 189/189] merge outside mod tests into "normal" workflow --- .github/workflows/c-cpp.yml | 10 ++++-- .github/workflows/outside.yml | 63 ----------------------------------- 2 files changed, 7 insertions(+), 66 deletions(-) delete mode 100644 .github/workflows/outside.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c69b46932..f6ffdf46b 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -4,7 +4,7 @@ on: push: branches: [ master ] pull_request: - branches: [ master, outside ] + branches: [ master ] workflow_dispatch: inputs: logLevel: @@ -31,7 +31,7 @@ jobs: run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip - name: Checkout truth - run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch master https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure @@ -43,6 +43,8 @@ jobs: - name: test-mod run: make test-mod TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu + - name: test-mod_outside + run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu - name: test-regress run: make test-regress TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth - name: test-ambiguity @@ -79,7 +81,7 @@ jobs: - name: add random Haskell lib run: cabal install --lib random - name: Checkout truth - run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + run: git clone --branch master https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - uses: actions/checkout@v3 - name: configure @@ -93,6 +95,8 @@ jobs: - name: test-mod run: make test-mod TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_osx + - name: test-mod_outside + run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_osx - name: test-regress run: make test-regress TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth - name: test-ambiguity diff --git a/.github/workflows/outside.yml b/.github/workflows/outside.yml deleted file mode 100644 index c379ece9b..000000000 --- a/.github/workflows/outside.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: test outside injection - -on: - push: - branches: [ master ] - pull_request: - branches: [ master, outside ] - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - tags: - description: 'Test scenario tags' - -jobs: - gapc_ubuntu: - runs-on: ubuntu-latest - steps: - - name: Update apt - run: sudo apt-get update - - name: Install dependencies - run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip - - - name: Checkout truth - run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - - - uses: actions/checkout@v2 - - name: configure - run: ./configure --prefix $GITHUB_WORKSPACE - - - name: test-mod_outside - run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu - - gapc_osx: - strategy: - matrix: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners - os: [macos-11] - runs-on: ${{ matrix.os }} - steps: - - name: Install dependencies - run: brew install bison@2.7 cmake boost gsl gnu-sed libomp gmp cabal-install - - name: update cabal - run: cabal update - - name: add random Haskell lib - run: cabal install --lib random - - name: Checkout truth - run: git clone --branch outside_v2 https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite - - - uses: actions/checkout@v3 - - name: configure - run: ./configure --prefix $GITHUB_WORKSPACE - - name: patch configuration for OSX - run: gsed -E "s|^YACC = .+$|YACC = /usr/local/opt/bison@2.7/bin/bison|" -i config.mf && gsed -E "s|^SED = .+$|SED = /usr/local/opt/gnu-sed/libexec/gnubin/sed|" -i config.mf && gsed -E "s/ -D_XOPEN_SOURCE=500 / /" -i config.mf && gsed -E "s/ -std=c\+\+17 / -std=c\+\+11 /" -i config.mf - - name: make - run: make -j 3 - - name: make install - run: sudo make install - - - name: test-mod_outside - run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_osx