diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 581dee234..f6ffdf46b 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -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 @@ -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/Makefile b/Makefile index 0964d60d5..45dd3dead 100644 --- a/Makefile +++ b/Makefile @@ -41,8 +41,10 @@ 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) \ + $(MODOUTSIDETESTS_CXX) \ $(wildcard testdata/test/*.cc) \ rtlib/string.cc \ @@ -97,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 \ @@ -128,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: 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 @@ -283,11 +286,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 @@ -307,6 +312,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/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: diff --git a/rtlib/filter.hh b/rtlib/filter.hh index 4d4075ba5..c149df9ea 100644 --- a/rtlib/filter.hh +++ b/rtlib/filter.hh @@ -127,5 +127,19 @@ inline bool samesize(const Basic_Sequence &s1, return j1-i1 == j2-i2; } +/* 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( + const Basic_Sequence &seq, T i, T j) { + return ((i == seq.n) && (j == seq.n)); +} + #endif // RTLIB_FILTER_HH_ 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"); diff --git a/src/alt.cc b/src/alt.cc index 35794dd73..774a6fc03 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; } @@ -1068,11 +1070,34 @@ 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) { - if (ys.low() != ys.high()) { - if (rhs.low() == rhs.high()) { + 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) { + /* 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; + } + + if ((ys.low() != ys.high()) || outmost) { + if ((rhs.low() == rhs.high()) && !outmost) { return right; } else { std::ostringstream o; @@ -1080,13 +1105,23 @@ Expr::Base *Alt::Simple::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 @@ -1101,7 +1136,7 @@ Expr::Base *Alt::Simple::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()))); } @@ -1110,6 +1145,7 @@ Expr::Base *Alt::Simple::next_index_var(unsigned &k, size_t track, new ::Type::Size(), ivar, index.first); Statement::For *f = new Statement::For (loopvariable, cond); loops.push_back(f); + return ivar; } } else { @@ -1141,7 +1177,8 @@ 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, false, false, false); std::pair res(0, 0); if (lhs.low() == lhs.high()) { @@ -1510,6 +1547,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) { @@ -1851,6 +1891,28 @@ 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; @@ -1873,19 +1935,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); @@ -1925,11 +1978,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); @@ -2510,7 +2573,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 0d0408517..1f9ea0147 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -50,6 +50,7 @@ // class Filter; #include "adp_mode.hh" +#include "outside/middle_end_fwd.hh" class Grammar; class Signature_Base; @@ -67,6 +68,13 @@ 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, + bool for_outside_generation, bool outmost, bool is_left_not_right); + class Base { private: /* @@ -76,6 +84,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; @@ -138,6 +149,14 @@ class Base { 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) { @@ -266,7 +285,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: @@ -275,10 +295,9 @@ class Base { return m_ys; } - private: - std::vector > multi_filter; - public: + // analogous to filters, multi_filter should be public + std::vector > multi_filter; void add_multitrack_filter( const std::list &l, Filter::Type t, const Loc &loc); virtual bool multi_detect_loop( @@ -318,6 +337,22 @@ class Base { std::ostream &out, std::vector *childIDs = NULL); virtual unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + + bool is_partof_outside() const { + return _is_partof_outside; + } + 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, + std::list &simple_loops); + virtual void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -387,21 +422,20 @@ 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, const std::list::iterator &end) const; + public: std::list loops; + + private: std::list foreach_loops; 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, @@ -440,6 +474,9 @@ 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); @@ -496,14 +533,42 @@ class Simple : public Base { public: void set_ntparas(std::list *l); + std::list get_ntparas() const { + 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); + /* 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); + private: 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; }; @@ -515,6 +580,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*) @@ -618,12 +689,34 @@ class Link : public Base { public: void set_ntparas(const Loc &loc, std::list *l); + std::list get_ntparas() const { + return ntparas; + } + void remove_ntparas() { + ntparas.clear(); + } void ntparas_to_dot(std::ostream &out); bool check_ntparas(); 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; + } + + 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); }; @@ -693,6 +786,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); }; @@ -765,6 +866,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); }; } // namespace Alt diff --git a/src/ast.cc b/src/ast.cc index c53598ce4..e06354f38 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); } @@ -148,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/ast.hh b/src/ast.hh index c070c6d32..b10bb49e8 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,19 @@ class AST { } Printer::Checkpoint *checkpoint; + + bool outside_generation() const { + if (!outside_nt_list) { + return false; + } + return outside_nt_list->size() > 0; + } + void set_outside_nt_list(std::vector *nts) { + outside_nt_list = nts; + } + std::vector *get_outside_nt_list() const { + return this->outside_nt_list; + } }; #endif // SRC_AST_HH_ diff --git a/src/checkpoint.hh b/src/checkpoint.hh index 4bfaea98f..ab4dfe8dc 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(); @@ -998,17 +999,47 @@ 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 - stream << indent() << "array_out << t_" << i << "_i + 1;" << endl; - stream << indent() << "array_out << " - << "(t_" << i << "_j == 0 ? 0 : t_" << i << "_j - 1);" << endl; + // 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 << ";" << endl; + stream << indent() << "array_out << " + << "t_" << i << "_j" << suffix << ";" << endl; + if (!outside) { + break; + } else { + // TODO(sjanssen) why can't I use OUTSIDE_IDX_SUFFIX from cyk.hh + // here? + suffix = "_outside"; + first_index = "diag"; + if (io == 0) { + stream << indent() << "array_out << " + << "t_" << i << "_i" << suffix << ";" << endl; + } + } + } } 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; @@ -1045,7 +1076,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,14 +1091,41 @@ 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 = ""; + std::string first_index = "i"; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + 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"; + if (io == 0) { + stream << indent() << "array_in >> " + << "t_" << i << "_i" << suffix << ";" << endl; + } + } + } } 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; @@ -1241,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 @@ -1257,19 +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([=, &cancel_token, &mutex]() " - << "mutable {" << endl; - } else { - stream << indent() << "std::thread([=, &cancel_token] () " - << "mutable {" << 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 69bf45efa..58cf819af 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -49,6 +49,7 @@ #include "grammar.hh" #include "options.hh" +#include "outside/codegen.hh" #include "cyk.hh" static std::string make_comments(const std::string &s, const std::string &c) { @@ -83,7 +84,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; @@ -1606,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; } @@ -1618,19 +1624,65 @@ 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++) { - stream << indent() << "t_" << i << "_i = 0;" << endl; - stream << indent() << "t_" << i << "_j = 0;" << endl; + std::string suffix = ""; + std::string first_index = "i"; + 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 << " = 0;" << endl; + if (!ast.grammar()->is_partof_outside()) { + break; + } else { + suffix = OUTSIDE_IDX_SUFFIX; + first_index = "diag"; + if (io == 0) { + stream << indent() << "t_" << i << "_i" + << suffix << " = 0;" << endl; + } + } + } } dec_indent(); stream << indent() << "#endif" << endl << endl; @@ -1784,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"; } @@ -1891,6 +1943,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; @@ -1949,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; @@ -1964,6 +2020,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) { @@ -1971,12 +2028,42 @@ 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 = ""; + std::string first_index = "i"; + for (int io = 0; io < 2; ++io) { // iterate through inside and outside + 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"; + if (io == 0) { + stream << indent() << *type << " t_" << t << "_i" << suffix + << ";" << endl; + } + } + } } 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; } @@ -2068,9 +2155,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); @@ -2405,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/cyk.cc b/src/cyk.cc index 513e4decd..1163f319e 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); @@ -82,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) { @@ -108,10 +136,12 @@ class CYKloop { } }; -enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL}; +enum CYKmode {SINGLETHREAD, OPENMP_PARALLEL, OPENMP_SERIAL, + SINGLETHREAD_OUTSIDE, + OPENMP_PARALLEL_OUTSIDE, OPENMP_SERIAL_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) { @@ -130,18 +160,22 @@ 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( + 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; @@ -171,13 +205,22 @@ 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) || + (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); - 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) && + (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); + loop->inc = x; + } Statement::Var_Decl *var_nonloop = var_row->clone(); var_nonloop->rhs = new Expr::Const(1); @@ -241,6 +284,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 @@ -256,7 +303,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); @@ -283,6 +330,67 @@ std::list *cyk_traversal_singlethread_singletrack( return stmts; } +/* + * 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( + 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); + + 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)); + + Expr::Base *col_start = seqend->minus(idx_row); + Expr::Base *col_end = seqend->plus(new Expr::Const(1)); + CYKloop col = get_for_column( + idx_col, + 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); + CYKloop row = get_for_row(idx_row, + row_start, 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, @@ -294,14 +402,44 @@ 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; } +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 @@ -367,13 +505,15 @@ std::list *cyk_traversal_singlethread(const AST &ast, */ 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) { + + 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(); - 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( @@ -381,16 +521,18 @@ 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], - seq, 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]; + 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) { 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); @@ -407,31 +549,30 @@ 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)), - start_z->plus(new Expr::Vacc(tile_size)))); + new Var_Acc::Plain(new std::string(var_ol1)), + (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); } 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], - seq, 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; 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); @@ -444,24 +585,18 @@ 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(VARNAME_InnerLoop2)), - (new Expr::Vacc(new std::string(VARNAME_InnerLoop2)))->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)); - 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()); } 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); @@ -474,7 +609,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); @@ -482,6 +617,309 @@ 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. + */ +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, + // 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, + 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( + 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( + type_diag, + name_col, + start_j); + // 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); + 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, + diag->plus(j)->minus(tl))); + if (nested_stmts) { + 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) { + 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); + 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)); + } + + 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; +} + +/* 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) { + // as openMP currently only works for single track grammars + size_t track = 0; + 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), + OMP_OUTSIDE_CP::no)); + + 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), + with_checkpoint ? OMP_OUTSIDE_CP::A : OMP_OUTSIDE_CP::no)); + } + + 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), + 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", 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 + 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() + + OUTSIDE_IDX_SUFFIX), + false, + false, + nullptr, + start_diag, + with_checkpoint ? OMP_OUTSIDE_CP::C : OMP_OUTSIDE_CP::no); + stmts->push_back(for_tile_c); + } + + return stmts; +} + size_t count_nt_calls_and_loops(Statement::For *loop) { size_t res = 0; @@ -517,7 +955,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) { @@ -528,16 +966,25 @@ 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_ // 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, - mode); + mode, ast); fl->statements.insert( fl->statements.end(), new_stmts->begin(), new_stmts->end()); } @@ -553,7 +1000,10 @@ 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) || + (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(); @@ -562,9 +1012,13 @@ 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()); @@ -576,27 +1030,98 @@ std::list *add_nt_calls(std::list &stmts, if (!(*i)->is_tabulated()) { continue; } + 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(); 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(), - idx->name()) != loop_vars->end()) { - used_indices++; + 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)); + } + 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->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->plus((new Expr::Vacc( + 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_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))); + } } 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) || + (mode == CYKmode::OPENMP_PARALLEL_OUTSIDE) || + (mode == CYKmode::OPENMP_SERIAL_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); + 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_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)))); + } 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); + } } } if (used_indices == loop_vars->size()) { @@ -607,7 +1132,8 @@ 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()); } } @@ -645,19 +1171,46 @@ 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(), + *(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(), + *(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 { + 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)); + idx_j = new Expr::Vacc(new std::string( + *idx_j->name() + OUTSIDE_IDX_SUFFIX)); + } + } } } @@ -665,16 +1218,35 @@ 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, 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); + 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(), + 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")); // FIXME generalize for multi-track ... @@ -688,26 +1260,40 @@ 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 = ""; + 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 + + "_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) ? " + step + " : " + + 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; + step = "1"; + } + } } fn_cyk->stmts.push_back(new Statement::CustomCode("#pragma omp parallel")); Statement::Block *blk_parallel = new Statement::Block(); @@ -725,11 +1311,11 @@ 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(), - 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(), @@ -743,10 +1329,96 @@ 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()); + + 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::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); + + 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( + "// OPENMP < 3 requires signed int here ...")); + + // parallel part + // 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, "A"); + // inject NT calls + add_nt_calls( + *stmts_outsideA, 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_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_outsideB->begin(), stmts_outsideB->end()); + + blk_parallel_outside->statements.push_back(new Statement::CustomCode( + "// end parallel")); + 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 = + 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); + } } fn_cyk->stmts.push_back(new Statement::CustomCode("#endif")); diff --git a/src/cyk.hh b/src/cyk.hh index 2611e48b0..85f5b2fce 100644 --- a/src/cyk.hh +++ b/src/cyk.hh @@ -39,10 +39,15 @@ #include "statement/fn_call.hh" #include "var_acc.hh" +static const char * const 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); +Statement::Var_Decl* +get_tile_computation_outside(Statement::Var_Decl *input_seq); + Fn_Def *print_CYK(const AST &ast); #endif /* SRC_CYK_HH_ */ 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 { 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/fn_arg.cc b/src/fn_arg.cc index 4b84b3d22..992cfec1f 100644 --- a/src/fn_arg.cc +++ b/src/fn_arg.cc @@ -284,6 +284,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/fn_arg.hh b/src/fn_arg.hh index 03d705998..f41b3e17d 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; @@ -55,6 +56,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; @@ -146,6 +151,21 @@ class Base { public: virtual void init_multi_ys() = 0; virtual const Yield::Multi &multi_ys() const { return m_ys; } + + bool is_partof_outside() const { + return _is_partof_outside; + } + 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, + std::list &simple_loops); + virtual void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -195,6 +215,14 @@ 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, + std::list &simple_loops); + void outside_uppropagate_indices( + Expr::Vacc *left, Expr::Vacc *right, size_t track); }; @@ -246,6 +274,13 @@ 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, + 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 568f786ce..71e6b0c5c 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -52,6 +52,8 @@ #include "printer/cfg_pretty_print.hh" #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; @@ -102,6 +104,12 @@ 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 >(), + 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.\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 " @@ -234,6 +242,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 +365,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()) { @@ -374,6 +386,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); @@ -682,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. diff --git a/src/grammar.cc b/src/grammar.cc index 7b6486d7b..56536bf4b 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()) { @@ -372,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(); @@ -490,6 +494,20 @@ 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(); + r = r && b; + + // 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; } @@ -655,7 +673,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); + } } } } @@ -836,6 +858,7 @@ void Grammar::traverse(Visitor &v) { i != NTs.end(); ++i) { i->second->traverse(v); } + v.visit_end(*this); } @@ -860,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; @@ -889,8 +915,12 @@ void Grammar::init_indices() { unsigned k = 0; + // 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); + (*i)->init_indices(l, r, k, idx, left_most, right_most); } } } diff --git a/src/grammar.hh b/src/grammar.hh index 7f3caefa4..397c77d83 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. @@ -213,6 +216,35 @@ 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(); + + /* 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(); + + /* not yet complete: will inject additional production rules such that + * the given (inside-) grammar is turned into an outside grammar. + */ + void convert_to_outside(); + + bool is_partof_outside() const { + return _is_partof_outside; + } + 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/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/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 diff --git a/src/outside/codegen.cc b/src/outside/codegen.cc new file mode 100644 index 000000000..161d9e7cf --- /dev/null +++ b/src/outside/codegen.cc @@ -0,0 +1,231 @@ +/* {{{ + + 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" + + +std::list *NTs_to_report(const AST &ast) { + /* 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 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. */ + 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 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 += ", "; + } + } + 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)); + + // 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) { + 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 + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), nt->right_indices[track], + nt->left_indices[track]); + loopvariable->set_itr(true); + 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]); + 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 += "\",\""; + } + } + std::list *stmts = new std::list(); + if (loops->size() > 0) { + 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 + // 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);")); + } + + stmts->push_back(new Statement::CustomCode( + "out << \"start answers " + *nt->name + "(\"" + idx_param + + "\"):\\n\";")); + + Statement::Var_Decl *res = new Statement::Var_Decl( + (*nt->code_list().begin())->return_type, "res_" + *nt->name, fn_nt); + 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("out")); + fnp->add_arg(res->name); + stmts->push_back(fnp); + + // produce: out << "//end answers outside_iloop(" << t_0_i << "," + // << t_0_j << ")\n"; + stmts->push_back(new Statement::CustomCode( + "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 << endl; + + stream.in_class = old_in_class; + + delete report_nts; +} + diff --git a/src/outside/codegen.hh b/src/outside/codegen.hh new file mode 100644 index 000000000..a497fb348 --- /dev/null +++ b/src/outside/codegen.hh @@ -0,0 +1,42 @@ +/* {{{ + + 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 +#include +#include + +#include "../ast.hh" +#include "../printer.hh" +#include "../cpp.hh" +#include "../statement_fwd.hh" +#include "../expr.hh" +#include "../fn_def.hh" +#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/outside/grammar_transformation.cc b/src/outside/grammar_transformation.cc new file mode 100644 index 000000000..9b656d7e3 --- /dev/null +++ b/src/outside/grammar_transformation.cc @@ -0,0 +1,976 @@ +/* {{{ + + 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 "../expr/new.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; +} + +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. + */ + + 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(); + + // 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); + } + + delete warn_missing_nts; +} + +// 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; + } + + bool is_used(std::string *algfct_name) { + assert(is_traversed); + return used_algfct.find(*algfct_name) != used_algfct.end(); + } +}; + +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(); + } + 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)) || // 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(); + } + + 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; +} + +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 (!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) + 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())) { + 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; +} + +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, + * - 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) { + // 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) { + 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); + } + } +} + +/* 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_parseComponents : public Visitor { + unsigned int number_components = 0; + + Count_parseComponents() { + number_components = 0; + } + + void visit_begin(Alt::Simple &alt) { + if (!alt.is_terminal()) { + number_components++; + } + } + void visit(Alt::Link &alt) { + if (alt.nt->is(Symbol::NONTERMINAL)) { + number_components++; + } + } +}; + +/* 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; + + explicit 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 + * 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; + + // a clone of the original inside lhs NT + Symbol::NT *lhs_nt; + + // the rhs top level alternative + Alt::Base *topalt = nullptr; + + explicit 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(); + } + ~Flip_lhs_rhs_nonterminals() { + delete alt_clones; + // delete lhs_nt->name; --> leads to failing mod_test_outside?! + delete lhs_nt; + } + 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)) { + /* 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 + */ + Count_parseComponents nrNTs = Count_parseComponents(); + alt.nt->traverse(nrNTs); + 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 + * 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( + 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) + // 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; + + /* 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 + */ + alt.remove_ntparas(); + if (lhs_nt->ntargs().size() > 0) { + alt.set_ntparas(Loc(), sync_ntparams(lhs_nt->ntargs())); + } + + + // d) + 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; + 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(); + } + } + } + } + + void visit(Grammar &g) { + throw LogError( + "Please only apply at individual NTs, not the full grammar!"); + } +}; + +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 + * 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; + + // 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; + + Collect_and_Insert_outside_axioms( + hashtable outside_nts) : + 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 + * 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++; + } + } + + void visit_itr(Symbol::NT &nt) { + if (rhs_nts == 0) { + // 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()) { + 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 &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 + 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 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!"); + } + + // 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; + // 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->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())); + } + 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 { + throw LogError("You inside grammar does not seem to terminate, which " + "should have been reported earlier via semantic checks?!"); + } + + // set grammar's axiom non-terminal + grammar.axiom = nt_axiom; + + // set grammar's axiom name + grammar.axiom_name = nt_axiom->name; + + // redirect grammar's axiom's location + grammar.axiom_loc = nt_axiom->location; + + // initialize links of the new 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, + */ +Alt::Link *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); + 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; + } + + 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); + + /* 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()); + /* 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->set_outside_inside_transition(); + if (rhs_inside->tracks() == 1) { + link->filters.push_back(f); + } else { + link->add_multitrack_filter(*comptracks, f->type, Loc()); + } + 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); + + // 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() { + // 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; + + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + 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); + resolve_blocks(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) { + 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); + } + } + } + + /* inject one alternative to the inside axiom which enables the transition + * from outside parts into the original inside part of the grammar */ + 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(); + 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); + + // add new outside non-terminal to the grammar + this->add_nt(dynamic_cast((*i).second)); + } + + // 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(); + + // 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); + } + + // 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 + * no longer nullptr. */ + 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 + * "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."); +} diff --git a/src/outside/grammar_transformation.hh b/src/outside/grammar_transformation.hh new file mode 100644 index 000000000..be29f3aba --- /dev/null +++ b/src/outside/grammar_transformation.hh @@ -0,0 +1,59 @@ +/* {{{ + + 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_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" +#include "../fn_arg.hh" + +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 +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_ diff --git a/src/outside/middle_end.cc b/src/outside/middle_end.cc new file mode 100644 index 000000000..b506ed600 --- /dev/null +++ b/src/outside/middle_end.cc @@ -0,0 +1,485 @@ +/* {{{ + + 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 . + +}}} */ + +/* 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" + + +void Alt::Base::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + 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, + 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); + } +} +void Alt::Link::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + 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, simple_loops); + if (num_outside_nts < 1) { + left_parsers.push_back(p); + } else { + right_parsers.insert(right_parsers.begin(), p); + } + } +} +void Alt::Block::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_parsers, + unsigned int &num_outside_nts, + size_t track, + std::list &simple_loops) { + // 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, + 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, 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, + 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, + 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 { + right_parsers.insert(right_parsers.begin(), p); + } +} +void Fn_Arg::Alt::outside_collect_parsers( + std::vector &left_parsers, + std::vector &right_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); +} + +Yield::Size sum_ys(std::vector parser, size_t pos_start) { + Yield::Size ys; + // don't risk undefined yield sizes! + ys.set(0, 0); + + 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; +} + +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)->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->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) { + Yield::Size lhs; + lhs.set(0, 0); + size_t pos = 0; + 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); + 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, true, false, is_left_not_right); + + // 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 + 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()) { + 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()) { + 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) { + res.second = next_var->minus(rhs.low()); + } else { + res.first = next_var->plus(rhs.low()); + } + lhs += ys; + } else { + 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()); + 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; + } + } + 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; + } else { + (*i)->left_indices.at(track) = res.first; + (*i)->right_indices.at(track) = res.second; + } + } +} + +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) { + std::vector left_parser; + std::vector right_parser; + unsigned int num_outside_nts = 0; + + /* 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 + // 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, 0); + // +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; + 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, 0); + // +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); + + 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); + } + + 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 + 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)) { + 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; + } +} + +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))) { + 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, 0).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, 0).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); + } +} + diff --git a/src/outside/middle_end.hh b/src/outside/middle_end.hh new file mode 100644 index 000000000..938751a6e --- /dev/null +++ b/src/outside/middle_end.hh @@ -0,0 +1,81 @@ +/* {{{ + + 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 +#include +#include +#include "../symbol.hh" +#include "../expr.hh" +#include "../fn_arg.hh" +#include "../alt.hh" +#include "../statement.hh" +#include "../visitor.hh" + +class Parser { + public: + 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, + std::list &simple_loops) : + yield_size(ys), + left_indices(left_indices), + right_indices(right_indices), + simple_loops(simple_loops) { + } +}; + +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); + +Yield::Size sum_ys(std::vector parser, + size_t pos_start); + +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_ diff --git a/src/outside/middle_end_fwd.hh b/src/outside/middle_end_fwd.hh new file mode 100644 index 000000000..32d95ba91 --- /dev/null +++ b/src/outside/middle_end_fwd.hh @@ -0,0 +1,31 @@ +/* {{{ + + 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_ + + +class Parser; + + +#endif /* SRC_OUTSIDE_MIDDLE_END_FWD_HH_ */ diff --git a/src/statement.hh b/src/statement.hh index d7fda68ef..e20a432da 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) { diff --git a/src/statement/base.hh b/src/statement/base.hh index 9dacb60d3..70b7c76f6 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, CUSTOMCODE + DECREASE, INCREASE, SORTER, SWITCH, CUSTOMCODE }; diff --git a/src/symbol.cc b/src/symbol.cc index c994d9e1f..d4defab6b 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) @@ -742,16 +743,23 @@ 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; - - for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) - (*i)->init_indices(left, right, k, track); + 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 { + (*i)->init_indices(left, right, k, track); + } + } } Statement::Base *Symbol::NT::build_return_empty(const Code::Mode &mode) { @@ -1195,6 +1203,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()); @@ -1225,8 +1235,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()); @@ -1578,11 +1586,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..6906a9675 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; @@ -126,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; } @@ -252,6 +257,13 @@ class Base { virtual unsigned int to_dot(unsigned int *nodeID, std::ostream &out, bool is_rhs, Symbol::NT *axiom, int plot_grammar); + + bool is_partof_outside() const { + return _is_partof_outside; + } + void set_partof_outside() { + _is_partof_outside = true; + } }; @@ -339,6 +351,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; @@ -354,7 +372,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; @@ -422,9 +440,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); diff --git a/src/visitor.cc b/src/visitor.cc index 97a771091..d5f7bb9bc 100644 --- a/src/visitor.cc +++ b/src/visitor.cc @@ -47,3 +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 08a75038e..83f8f7270 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,11 @@ 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); }; #endif // SRC_VISITOR_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 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/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/ext_hmm.hh b/testdata/gapc_filter/ext_hmm.hh new file mode 100644 index 000000000..a915d5289 --- /dev/null +++ b/testdata/gapc_filter/ext_hmm.hh @@ -0,0 +1,71 @@ +#ifndef EXT_HMM_HH +#define EXT_HMM_HH + +#include + +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); +} + +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; + } + + 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; +} + +#endif // EXT_HMM_HH diff --git a/testdata/gapc_filter/isntimes.hh b/testdata/gapc_filter/isntimes.hh new file mode 100644 index 000000000..3a3e1e277 --- /dev/null +++ b/testdata/gapc_filter/isntimes.hh @@ -0,0 +1,21 @@ +#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 < i) + return false; + + if (j-i != size) + return false; + + for (T k = i; k < j; k++) { + if (seq[k] != x) + return false; + } + + return true; +} + +#endif 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 diff --git a/testdata/grammar2/alignments_cyk.gap b/testdata/grammar2/alignments_cyk.gap index a31ceea83..0521f4981 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; @@ -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); 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..8bc7858b8 --- /dev/null +++ b/testdata/grammar_outside/elmamun.gap @@ -0,0 +1,203 @@ +/* +# 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) + | nil(EMPTY) + # 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..40508ab8b --- /dev/null +++ b/testdata/grammar_outside/mini_complexIL.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, 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; + } +} + +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/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); 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..9cc06269e --- /dev/null +++ b/testdata/modtest/outside_checksemantics.cc @@ -0,0 +1,80 @@ +#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; + 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(); + + // 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 + // 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 = 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(); + } +} diff --git a/testdata/modtest/outside_grammar.cc b/testdata/modtest/outside_grammar.cc new file mode 100644 index 000000000..9131b259b --- /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->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, 1); +} 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); +} 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(); +} + 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; +} 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 diff --git a/testdata/regresstest/config b/testdata/regresstest/config index 23edb7e35..eaeb43efe 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -482,14 +482,8 @@ 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 -#regression tests, i.e. compare gapc output with truth -DEFAULT_LDLIBS_EXTRA=$LDLIBS_EXTRA -DEFAULT_CPPFLAGS_EXTRA=$CPPFLAGS_EXTRA -DEFAULT_GAPC=$GAPC - - -# ======= following are test of the new CYK code generation of file src/cyk.cc ======= -GRAMMAR=../../grammar2 +# ======= following are test of the new CYK code generation of file src/cyk.cc ======= +GRAMMAR=../../grammar2 GAPC="../../../gapc" check_new_old_eq_twotrack alignments_cyk.gap unused maxM "GUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUG" cyk_maxM "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUAGUCGUAGUCGUAGUCGUuguacg" @@ -504,14 +498,14 @@ check_new_old_eq_twotrack alignments_cyk.gap unused count "freizeit" cyk_twotrac # an example where nested for loops are empty and should be removed in the CYK function GRAMMAR=../../grammar check_new_old_eq_twotrack affinelocsim2.gap unused affinecnt "CUGAAACGUAGUCUGAAAAGCCCGCGUAGUCGUAGUCGUAGUCGUACGUUAGCGUUGAGUCGUAGUCGUAGUUGAGUUCGGUAGUCGUAGUCGUGUACCACACAUGUGCGUAGUCGUCAGUCGUAGUCGUACGUCGUCUAGCGUGUCGUAUGCGUACGUAGUCGAGUCUGACGAGUGCGUGGGUCUGAGUCGUCGUUAGGCCAGUCGUAGUCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUU" checkpoint11 "CGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUCGUAGUCGUAGUCGUAGUCGUACGUCGUAUGCUGAGCAAAAAAUCGUAGUCCUGAGUCGUAGCAUGCGUACGACGUGUCCGUAGCGUACGUGUAGUACGUAGUCGAUCGUCUGAGUGUCGUAGUCGUAGUCCGUAGUCUGUAGUGUCGUACGUCGUGUAGUCGUAGCUGUAGUCGUAGUCGUAGUCGUUGCGUAGUCGUAGCGUACGUAGUGUAGUCGUCGUGUAGCGUACGUGU" -GRAMMAR=../../grammar2 +GRAMMAR=../../grammar2 check_new_old_eq_twotrack alignments_cyk.gap unused maxM "GUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUG" cyk_maxM "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUAGUCGUAGUCGUAGUCGUuguacg" # CYK single threaded with checkpointing for two track grammar GAPC="../../../gapc --cyk --checkpoint" GRAMMAR=../../grammar check_checkpoint_eq affinelocsim2.gap unused affinecnt "CUGAAACGUAGUCUGAAAAGCCCGCGUAGUCGUAGUCGUAGUCGUACGUUAGCGUUGAGUCGUAGUCGUAGUUGAGUUCGGUAGUCGUAGUCGUGUACCACACAUGUGCGUAGUCGUCAGUCGUAGUCGUACGUCGUCUAGCGUGUCGUAUGCGUACGUAGUCGAGUCUGACGAGUGCGUGGGUCUGAGUCGUCGUUAGGCCAGUCGUAGUCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUU" checkpoint11 1 "CGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUCGUAUGGCUGUAGCUGUCGUAGCUAUGCGUGUACGUCGUAGUGCUAGUCGUAGUCGUAGUCGUCGUGUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUGAUGCUGAUCGUCGACGUGACGUCGUGUAGCUAGUCGUGUAGUCGUAGUCGUAGCGGGGCAGCGGUAUUUUGCGAUCGUAGUCGUAGUCGUAGUCGUAGUGUAGUGUCGUCCGUUCGUAGUCGUAGUCGUAGUCGUACGUCGUAUGCUGAGCAAAAAAUCGUAGUCCUGAGUCGUAGCAUGCGUACGACGUGUCCGUAGCGUACGUGUAGUACGUAGUCGAUCGUCUGAGUGUCGUAGUCGUAGUCCGUAGUCUGUAGUGUCGUACGUCGUGUAGUCGUAGCUGUAGUCGUAGUCGUAGUCGUUGCGUAGUCGUAGCGUACGUAGUGUAGUCGUCGUGUAGCGUACGUGU" -GRAMMAR=../../grammar2 +GRAMMAR=../../grammar2 check_checkpoint_eq alignments_cyk.gap unused maxM "GUCAGUGUCCGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUCGUGAUGUCGUAGCGUAGUCGUGUCCGUAGUCGUAGUCGUAGUCGUGUAGUCGUAGUCGUAGUCGUAGUCGUAGUCGUGUAGCUGUAGUCGUUGAGCUAGGCGUAGUCGUAGUCGUGUAGUCGUGUGUGUGUACGUAGUCCGUAGUCGUG" cyk_maxM 1 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUAGUCGUAGUCGUAGUCGUuguacg" # single track @@ -532,4 +526,109 @@ 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" +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" +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 + +# 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 + +# 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 + +# 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 + +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=""