diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 581dee234..2d04a5b2e 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -4,7 +4,7 @@ on: push: branches: [ master ] pull_request: - branches: [ master ] + branches: [ master, outside_looporder ] workflow_dispatch: inputs: logLevel: diff --git a/.github/workflows/outside.yml b/.github/workflows/outside.yml new file mode 100644 index 000000000..168daa139 --- /dev/null +++ b/.github/workflows/outside.yml @@ -0,0 +1,34 @@ +name: test outside injection + +on: + push: + branches: [ master ] + pull_request: + branches: [ master, outside_looporder ] + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + tags: + description: 'Test scenario tags' + +jobs: + gapc_ubuntu: + runs-on: ubuntu-latest + steps: + - name: Update apt + run: sudo apt-get update + - name: Install dependencies + run: sudo apt-get install flex bison make libboost-all-dev libgsl-dev python3 python3-pip + + - name: Checkout truth + run: git clone --branch master https://github.com/jlab/gapc-test-suite.git $GITHUB_WORKSPACE/../gapc-test-suite + + - uses: actions/checkout@v2 + - name: configure + run: ./configure --prefix $GITHUB_WORKSPACE + + - name: test-mod + run: make -j 2 test-mod_outside TRUTH_DIR=$GITHUB_WORKSPACE/../gapc-test-suite/Truth TRUTH_SUFFIX=_ubuntu diff --git a/Makefile b/Makefile index 0964d60d5..52c49c966 100644 --- a/Makefile +++ b/Makefile @@ -128,7 +128,7 @@ gapc: src/gapc.o $(MAIN_OBJ) src/version.o src/prefix.o stats \ test_rt_tab \ -multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys parser: src/version.o src/prefix.o +multi_cyk multi_deps multi_indices multi_list_size multi_eliminate_lists_more multi_eliminate_lists multi_algebra multi_signature multi_rt_approx multi_rt_all multi_in_out multi_self_rec multi_calls multi_table_dim multi_max_filter multi_loops multi_ys multi_print_grammar outside_resolve_blocks outside_indices parser: src/version.o src/prefix.o backtrack: src/version.o @@ -283,11 +283,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 +309,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/rtlib/filter.hh b/rtlib/filter.hh index 4d4075ba5..30731a7c3 100644 --- a/rtlib/filter.hh +++ b/rtlib/filter.hh @@ -127,5 +127,10 @@ inline bool samesize(const Basic_Sequence &s1, return j1-i1 == j2-i2; } +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 952568040..96c3e900b 100644 --- a/src/alt.cc +++ b/src/alt.cc @@ -58,7 +58,7 @@ Alt::Base::Base(Type t, const Loc &l) : terminal_type(false), location(l), ret_decl(NULL), filter_guards(NULL), choice_fn_type_(Expr::Fn_Call::NONE), - tracks_(0), track_pos_(0) { + tracks_(0), track_pos_(0), is_partof_outside(false) { } @@ -1324,7 +1324,6 @@ void Alt::Simple::init_foreach() { } } - void Alt::Simple::ret_decl_empty_block(Statement::If *stmt) { if (!datatype->simple()->is(::Type::LIST)) { Statement::Fn_Call *e = new Statement::Fn_Call(Statement::Fn_Call::EMPTY); @@ -1508,18 +1507,90 @@ void Alt::Simple::init_body(AST &ast) { } } +void Alt::Link::init_outside_guards() { + std::list l; + unsigned int track = 0; + std::vector::iterator j = right_indices.begin(); + for (std::vector::iterator i = left_indices.begin(); + i != left_indices.end(); ++i, ++j, ++track) { + std::ostringstream o_left; o_left << "t_" << track << "_right_most"; + Expr::Vacc *leftmost = new Expr::Vacc(new std::string(o_left.str())); + l.push_back(new Expr::Greater_Eq((*i), leftmost)); + } + + Expr::Base *cond = Expr::seq_to_tree( + l.begin(), l.end()); + + guards = new Statement::If(cond); + // ret_decl_empty_block(guards); +} void Alt::Simple::init_guards() { std::list l; + std::list l_inside; assert(m_ys.tracks() == left_indices.size()); Yield::Multi::iterator k = m_ys.begin(); + Yield::Multi::iterator k_inside = m_ys_inside.begin(); std::vector::iterator j = right_indices.begin(); + std::vector::iterator it_left_inner_indices = + this->left_inside_indices.begin(); + std::vector::iterator it_right_inner_indices = + this->right_inside_indices.begin(); + + unsigned int track = 0; for (std::vector::iterator i = left_indices.begin(); - i != left_indices.end(); ++i, ++j, ++k) { - Expr::Base *e = (*j)->minus(*i); - l.push_back(new Expr::Greater_Eq(e, (*k).low())); - if ((*k).high() != Yield::Poly(Yield::UP)) { - l.push_back(new Expr::Less_Eq(e, (*k).high())); + i != left_indices.end(); + ++i, ++j, ++k, ++k_inside, ++track, ++it_left_inner_indices, + ++it_right_inner_indices) { + if (this->is_partof_outside) { + // obtain yield sizes left and right of outside non-terminal + std::pair *ys = + this->get_outside_accum_yieldsizes(track); + + std::ostringstream o_left; o_left << "t_" << track << "_left_most"; + Expr::Vacc *leftmost = new Expr::Vacc(new std::string(o_left.str())); + assert(*it_left_inner_indices); + Expr::Vacc *lname = dynamic_cast(*it_left_inner_indices); + if (lname && (lname->name()->compare(*leftmost->name()) == 0)) { + // the rare case where guards check themselves + // happens e.g. if table has only one dimension + l.push_back(new Expr::Greater_Eq( + lname->minus(leftmost), new Expr::Const(0))); + } else { + l.push_back(new Expr::Greater_Eq((*it_left_inner_indices), + leftmost->plus(ys->first->low()))); + // l.push_back(new Expr::Greater_Eq((*it_left_inner_indices) + // ->minus(ys->first->low()), leftmost)); + } + + std::ostringstream o_right; o_right << "t_" << track << "_right_most"; + Expr::Vacc *rightmost = new Expr::Vacc(new std::string(o_right.str())); + assert(*it_right_inner_indices); + Expr::Vacc *rname = dynamic_cast(*it_right_inner_indices); + if (rname && (rname->name()->compare(*rightmost->name()) == 0)) { + // the rare case where guards check themselves + // happens e.g. if table has only one dimension + l.push_back(new Expr::Less_Eq( + rname->minus(rightmost), new Expr::Const(0))); + } else { + l.push_back(new Expr::Less_Eq( + (*it_right_inner_indices)->plus(ys->second->low()), rightmost)); + } + + // additionally, add guards from original inside rules + if (k_inside != m_ys_inside.end()) { + Expr::Base *e = (*j)->minus(*i); + l_inside.push_back(new Expr::Greater_Eq(e, (*k_inside).low())); + if ((*k_inside).high() != Yield::Poly(Yield::UP)) { + l_inside.push_back(new Expr::Less_Eq(e, (*k_inside).high())); + } + } + } else { + Expr::Base *e = (*j)->minus(*i); + l.push_back(new Expr::Greater_Eq(e, (*k).low())); + if ((*k).high() != Yield::Poly(Yield::UP)) { + l.push_back(new Expr::Less_Eq(e, (*k).high())); + } } } @@ -1528,6 +1599,17 @@ void Alt::Simple::init_guards() { guards = new Statement::If(cond); ret_decl_empty_block(guards); + + if (l_inside.size() > 0) { + Expr::Base *cond = Expr::seq_to_tree( + l_inside.begin(), l_inside.end()); + + guards_inside = new Statement::If(cond); + ret_decl_empty_block(guards_inside); + } else { + // don't leave this variable in an undefined state + guards_inside = NULL; + } } @@ -1853,6 +1935,24 @@ std::list *Alt::Simple::add_for_loops( } return stmts; } +std::list *Alt::Simple::add_guards( + std::list *stmts, + Statement::If *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; + } + return stmts; +} void Alt::Simple::codegen(AST &ast) { // std::cout << "-----------Simple IN" << std::endl; @@ -1874,21 +1974,21 @@ void Alt::Simple::codegen(AST &ast) { push_back_ret_decl(); std::list *stmts = &statements; - 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 (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; +// } + stmts = add_guards(stmts, guards); init_filter_guards(ast); @@ -1928,11 +2028,38 @@ void Alt::Simple::codegen(AST &ast) { } } - // add filter_guards - stmts = add_filter_guards(stmts, filter_guards); + if (is_partof_outside) { + // syntactic filter indices are only initialized through the for-loops + // in outside alternatives thus, reverse the order of filters/loops: + + // add for loops for moving boundaries + stmts = add_for_loops(stmts, loops, has_index_overlay()); + +// if (guards_inside) { +// stmts->push_back(guards_inside); +// 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_inside->then; +// } + // guards_inside have already initialized through init_guards() + stmts = add_guards(stmts, guards_inside); + + // 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 for loops for moving boundaries + stmts = add_for_loops(stmts, loops, has_index_overlay()); + } add_subopt_guards(stmts, ast); @@ -1996,7 +2123,7 @@ void Alt::Simple::codegen(AST &ast) { } -void Alt::Link::add_args(Expr::Fn_Call *fn) { +void Alt::Link::add_args(Expr::Fn_Call *fn, bool for_outside_grammar) { if (is_explicit()) { fn->add(indices); fn->add(ntparas); @@ -2021,6 +2148,13 @@ void Alt::Link::add_args(Expr::Fn_Call *fn) { std::vector::iterator j = left_indices.begin(); for (std::vector::const_iterator i = tables.begin(); i != tables.end(); ++i, ++j, ++k) { + if (for_outside_grammar && this->is_outside_inside_transition) { + if ((*i).is_const_table()) { + fn->add_arg(*j); + fn->add_arg(*j); + continue; + } + } if (!(*i).delete_left_index()) { fn->add_arg(*j); } @@ -2056,13 +2190,28 @@ void Alt::Link::codegen(AST &ast) { add_seqs(fn, ast); } - add_args(fn); + add_args(fn, ast.grammar()->is_outside()); if (nt->is(Symbol::NONTERMINAL) && ast.code_mode() == Code::Mode::SUBOPT) { fn->exprs.push_back(new Expr::Vacc(new std::string("global_score"))); fn->exprs.push_back(new Expr::Vacc(new std::string("delta"))); } +// std::list *stmts = &statements; +// 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; +// } + init_filter_guards(ast); if (filter_guards) { Statement::Var_Assign *v = new Statement::Var_Assign(*ret_decl, fn); @@ -2478,6 +2627,7 @@ void Alt::Simple::init_multi_ys() { input, i.e. NOT for CONST_xxx terminal parser, that inject values for later use in algebras. */ + // TODO(sjanssen) isn't there a better method to check for constants? if (name->rfind("CONST_", 0) != 0) { Yield::Poly max_terminal_arg_yield = Yield::Poly(0); for (std::list::iterator i = args.begin(); @@ -2513,7 +2663,16 @@ void Alt::Simple::init_multi_ys() { void Alt::Link::init_multi_ys() { - m_ys = nt->multi_ys(); + // TODO(sjanssen): would it make sense to run an outside specific yield + // size analysis for more thight guards?? + 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(); } @@ -2954,3 +3113,721 @@ bool Alt::Base::choice_set() { return datatype->simple()->is(::Type::LIST) && eval_nullary_fn; } +void Alt::Base::get_nonterminals(std::list *nt_list) { +} +void Alt::Simple::get_nonterminals(std::list *nt_list) { + for (Fn_Arg::Base *arg : this->args) { + Fn_Arg::Alt *arg_alt = dynamic_cast(arg); + if (arg_alt) { + // recurse into arguments + arg_alt->alt->get_nonterminals(nt_list); + } + } +} +void Alt::Link::get_nonterminals(std::list *nt_list) { + // test if Link is a non-terminal + if (this->nt) { + if (this->nt->is(Symbol::NONTERMINAL)) { + nt_list->push_back(dynamic_cast(this->nt)); + } else if (this->nt->is(Symbol::TERMINAL)) { + } + } else { + throw LogError("Link is something else"); + } +} +void Alt::Block::get_nonterminals(std::list *nt_list) { + for (Alt::Base *alt : this->alts) { + // recurse into alternatives + alt->get_nonterminals(nt_list); + } +} +void Alt::Multi::get_nonterminals(std::list *nt_list) { + for (std::list::iterator i = list.begin(); i != list.end(); ++i) { + (*i)->get_nonterminals(nt_list); + } +} + +// recursively flag this alternative as being part of an inside (=false=default) +// or outside (=true) production rule +void Alt::Base::set_partof_outside(bool is_outside) { +} +void Alt::Simple::set_partof_outside(bool is_outside) { + this->is_partof_outside = is_outside; + for (std::list::iterator i = args.begin(); + i != args.end(); ++i) { + Fn_Arg::Alt *arg_alt = dynamic_cast(*i); + if (arg_alt) { + arg_alt->alt->set_partof_outside(is_outside); + } + } +} +void Alt::Link::set_partof_outside(bool is_outside) { + if (this->nt) { + this->is_partof_outside = is_outside; + } else { + throw LogError("Link is something else"); + } +} +void Alt::Block::set_partof_outside(bool is_outside) { + for (std::list::iterator i = this->alts.begin(); + i != this->alts.end(); ++i) { + (*i)->set_partof_outside(is_outside); + } +} +void Alt::Multi::set_partof_outside(bool is_outside) { + for (std::list::iterator i = list.begin(); i != list.end(); ++i) { + (*i)->set_partof_outside(is_outside); + } +} + + +bool Alt::Base::replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences) { + return false; +} +bool Alt::Simple::replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences) { + for (std::list::iterator it_arg = this->args.begin(); + it_arg != this->args.end(); ++it_arg) { + Fn_Arg::Alt *arg_alt = dynamic_cast(*it_arg); + if (arg_alt) { + if (arg_alt->alt->replace_nonterminal(find, replace, skip_occurences)) { + return true; + } + } + } + return false; +} +bool Alt::Link::replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences) { + if (this->nt) { + if (this->nt->is(Symbol::NONTERMINAL)) { + if (this->nt == find) { + if (skip_occurences[*(find->name)] == 0) { + // replace old NT (=find) with novel NT (=replace) + this->nt = replace; + this->m_ys = replace->multi_ys(); + this->name = replace->name; + this->is_partof_outside = replace->is_partof_outside; + return true; + } else { + skip_occurences[*(find->name)]--; + } + } + } else if (this->nt->is(Symbol::TERMINAL)) { + } + } else { + throw LogError("Link is something else"); + } + return false; +} +bool Alt::Block::replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences) { + for (Alt::Base *alt : this->alts) { + // recurse into alternatives + if (alt->replace_nonterminal(find, replace, skip_occurences)) { + return true; + } + } + return false; +} +bool Alt::Multi::replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences) { + for (std::list::iterator i = list.begin(); i != list.end(); ++i) { + if ((*i)->replace_nonterminal(find, replace, skip_occurences)) { + return true; + } + } + return false; +} + +// traverses an alternative, collects all non-terminals and returns the one +// outside non-terminal if present, otherwise NULL +Symbol::NT *get_outside_NT(Alt::Base *alt) { + std::list *nt_list = new std::list(); + alt->get_nonterminals(nt_list); + for (std::list::iterator i = nt_list->begin(); + i != nt_list->end(); ++i) { + // std::cerr << *((*i)->name) << "\n"; + if ((*i)->is_partof_outside == false) { + // i-- because we need to make sure not to destroy the iterator + // we are using at this moment: + // https://www.techiedelight.com/remove-elements-list-iterating-cpp/ + nt_list->erase(i--); + } + } + // by design of the outside NT injection, there can at most be ONE + // outside-nt on any rhs of a production! + assert(nt_list->size() <= 1); + if (nt_list->size() == 1) { + return nt_list->front(); + } + return NULL; +} + +Expr::Base *get_next_var_name(unsigned &k, size_t track) { + std::ostringstream o; + o << "t_" << track << "_k_" << k; + k++; + Expr::Vacc *ivar = new Expr::Vacc(new std::string(o.str())); + return ivar; +} +Expr::Base *Alt::Simple::get_next_var_right2left(Expr::Base *left_index, + Expr::Base *innermost_left_index, unsigned &k, size_t track, + Yield::Size ys_this, Yield::Size *ys_lefts) { + if (ys_this.low() == ys_this.high()) { + // constant yield size + if ((ys_lefts->low() == 0) && (ys_lefts->high() == 0)) { + return innermost_left_index; + } else { + return left_index->plus(ys_this.low()); + } + } + + if (ys_lefts->low() == ys_lefts->high()) { + return innermost_left_index->minus(ys_lefts->low()); + } + + // variable yield size + Expr::Base *next_index = get_next_var_name(k, track); + + // add for loop + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), next_index, left_index->plus(ys_this.low())); + loopvariable->set_itr(true); + Expr::Base *cond = new Expr::Less_Eq(next_index, + innermost_left_index->minus(ys_lefts->low())); + Statement::For *f = new Statement::For(loopvariable, cond); + loops.push_back(f); + + return next_index; +} +Expr::Base *Alt::Simple::get_next_var_left2right(Expr::Base *right_index, + Expr::Base *innermost_right_index, unsigned &k, size_t track, + Yield::Size ys_this, Yield::Size *ys_rights) { + Expr::Base *next_index; + + // constant yield size + if (ys_this.low() == ys_this.high()) { + if ((ys_rights->low() == 0) && (ys_rights->high() == 0)) { + // we might fall back to j, if yield between outside NT and current + // right hand side argument is 0 + next_index = innermost_right_index; + } else { + // normally, we just decrease the current index + next_index = right_index->minus(ys_this.low()); + } + } else { + // constant yield size, on the left hand side towards outside non terminal + // e.g. ..., outside_bar, BASE, foo, ... + // where border between BASE and foo shall be j+1 instead of k_x + if (ys_rights->low() == ys_rights->high()) { + next_index = innermost_right_index->plus(ys_rights->low()); + } else { + // variable yield size + next_index = get_next_var_name(k, track); + + // add for loop + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), next_index, + innermost_right_index->plus(ys_rights->low())); + loopvariable->set_itr(true); + Expr::Base *cond = new Expr::Less_Eq(next_index, + right_index->minus(ys_this.low())); + Statement::For *f = new Statement::For(loopvariable, cond); + loops.push_back(f); + } + } + + return next_index; +} + +void Alt::Base::expand_outside_nt_indices(Expr::Base *left, + Expr::Base *right, size_t track) { + this->left_indices[track] = left; + this->right_indices[track] = right; +} +void Alt::Simple::expand_outside_nt_indices(Expr::Base *left, + Expr::Base *right, size_t track) { + // 1) identify outside non-terminal + for (std::list::const_iterator i = args.begin(); + i != args.end(); ++i) { + Symbol::NT *ont = get_outside_NT((*i)->alt_ref()); + if (ont) { + // e.g. outside_iloop + Alt::Link *link = dynamic_cast((*i)->alt_ref()); + if (link) { + if (link->nt == ont) { + // the link->nt could also be a terminal + Symbol::NT *check = dynamic_cast(link->nt); + assert(check); + // we have identified this fn_arg as the one being the outside + // non-terminal, 2) let's expand its indices + link->expand_outside_nt_indices(left, right, track); + // we are done + return; + } + } + // e.g. incl(outside_iloop) + Alt::Simple *algfct = dynamic_cast((*i)->alt_ref()); + if (algfct) { + algfct->expand_outside_nt_indices(left, right, track); + } + } + } +} +void Alt::Link::expand_outside_nt_indices(Expr::Base *left, + Expr::Base *right, size_t track) { + Alt::Base::expand_outside_nt_indices(left, right, track); +} +void Alt::Block::expand_outside_nt_indices(Expr::Base *left, + Expr::Base *right, size_t track) { + throw LogError( + "Alt::Block::expand_outside_nt_indices blocks must be resolved prior " + "to outside generation, see function Grammar::resolve_blocks!"); +} +void Alt::Multi::expand_outside_nt_indices(Expr::Base *left, + Expr::Base *right, size_t track) { + throw LogError( + "Alt::Block::expand_outside_nt_indices is not yet implemented!"); +} +void Alt::Base::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + Alt::Base::init_indices(left, right, k, track); +} + +void Alt::Simple::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + + if (this->is_terminal_) { + // a parameterized Terminal like ROPE("manfred") is of type Alt::Simple + // and will therefore be called here, while ROPE without a parameter + // would be of type Alt::Link + Alt::Base::init_indices_outside(left, right, k, track, center_left, + center_right, is_right_of_outside_nt); + // store original left/right for e.g. + // correct initialization of IF guards; see function init_guards() + this->left_inside_indices.resize(this->left_indices.size()); + this->right_inside_indices.resize(this->right_indices.size()); + this->left_inside_indices[track] = left; + this->right_inside_indices[track] = right; + return; + } + // if this alternative is called from an outside non-terminal, but does + // not contain another outside non-terminal, e.g. hl(BASE, REGION, BASE) + // we can default to inside indices generation! + if (this->is_partof_outside == false) { + Alt::Simple::init_indices(left, right, k, track); + return; + } +// std::cerr << *this->name << ": Alt::Simple::init_indices_outside(" +// << *left << ", " << *right << ", "; +// if (center_left) { +// std::cerr << *center_left; +// } else { +// std::cerr << center_left; +// } +// std::cerr << ", "; +// if (center_right) { +// std::cerr << *center_right; +// } else { +// std::cerr << center_right; +// } +// std::cerr << ", " << is_right_of_outside_nt << ")\n"; + + std::list *args_left = new std::list(); + std::list *args_right = new std::list(); + Fn_Arg::Base *arg_outside = NULL; + Symbol::NT *nt_outside = NULL; + for (std::list::const_iterator i = args.begin(); + i != args.end(); ++i) { + Fn_Arg::Const *constarg = dynamic_cast(*i); + if (constarg != NULL) { + // argument is a constant like 'A' in CHAR('A') + continue; + } + Symbol::NT *ont = get_outside_NT((*i)->alt_ref()); + if (ont) { + Alt::Link *link = dynamic_cast((*i)->alt_ref()); + if (link) { + if (link->nt == ont) { + // the link->nt could also be a terminal + Symbol::NT *check = dynamic_cast(link->nt); + assert(check); + nt_outside = check; + } + } + arg_outside = *i; + continue; + } + if ((arg_outside == NULL) && (is_right_of_outside_nt == false)) { + args_left->push_back(*i); + } else { + args_right->push_back(*i); + } + } + + // yield sizes for sub-structure + std::pair *ys_sub = + new std::pair( + new Yield::Size(), new Yield::Size()); + if (arg_outside != NULL) { + ys_sub = arg_outside->alt_ref()->get_outside_accum_yieldsizes(track, + is_right_of_outside_nt); + } + std::pair *ys_this = + this->get_outside_accum_yieldsizes(track, is_right_of_outside_nt); + + // arguments left of outside NT + Expr::Base *left_index; + if (center_left) { + left_index = center_left; + } else { + if (ys_this->first->low() != ys_this->first->high()) { + left_index = get_next_var_name(k, track); + + // add for-loop + std::ostringstream o; + o << "t_" << track << "_left_most"; + Expr::Vacc *left_border = new Expr::Vacc(new std::string(o.str())); + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), left_index, left_border); + loopvariable->set_itr(true); + Expr::Base *cond = new Expr::Less_Eq(left_index, left->minus( + ys_this->first->low())); + Statement::For *f = new Statement::For(loopvariable, cond); + loops.push_back(f); + } else { + // no new index if there are no parsers or only parsers with const + // yield size left of outside nt + // e.g. incl(outside_foo) + // e.g. sadd(BASE, outside_foo) + left_index = left->minus(ys_this->first->low()); + } + } + Expr::Base *leftmost_index = left_index; + Expr::Base *right_index = left_index; + for (std::list::const_iterator i = args_left->begin(); + i != args_left->end(); ++i) { + Yield::Size ys_arg = (*i)->multi_ys()(track); + Yield::Size *ys_right2center = new Yield::Size(); + *ys_right2center += *(ys_sub->first); + *ys_right2center += *(sum_ys_rights(&ys_arg, i, args_left->end(), track)); + if ((arg_outside == NULL) && (ys_arg.low() > 0)) { + // if this level does NOT hold the outside non-terminal, but args + // are left of the outside non-terminal propagate the rightmost index + // (must be the one from the outside non-terminal in higher levels) + // as the left index + left = right; + } + right_index = get_next_var_right2left(left_index, left, k, track, ys_arg, + ys_right2center); + (*i)->init_indices_outside(left_index, right_index, k, track, + leftmost_index, center_right); + left_index = right_index; + } + Expr::Base *lhs_right_index = right_index; + + // arguments right of outside NT + if (center_right) { + right_index = center_right; + } else { + if (ys_this->second->low() != ys_this->second->high()) { + right_index = get_next_var_name(k, track); + + // add for-loop + std::ostringstream o; + o << "t_" << track << "_right_most"; + Expr::Vacc *right_border = new Expr::Vacc(new std::string(o.str())); + Statement::Var_Decl *loopvariable = new Statement::Var_Decl( + new ::Type::Size(), right_index, right->plus(ys_this->second->low())); + loopvariable->set_itr(true); + Expr::Base *cond = new Expr::Less_Eq(right_index, right_border); + Statement::For *f = new Statement::For(loopvariable, cond); + loops.push_back(f); + } else { + // no new index if there are no parsers or only parsers with const + // yield size right of outside nt + // e.g. incl(outside_foo) + // e.g. adds(outside_foo, BASE) + right_index = right->plus(ys_this->second->low()); + } + } + Expr::Base *rightmost_index = right_index; + left_index = NULL; + if (is_right_of_outside_nt) { + right = left; + } + for (std::list::const_reverse_iterator + i = args_right->rbegin(); i != args_right->rend(); ++i) { + Yield::Size ys_arg = (*i)->multi_ys()(track); + Yield::Size *ys_left2center = new Yield::Size(); + *ys_left2center += *(ys_sub->second); + *ys_left2center += *(sum_ys_lefts(&ys_arg, i, args_right->rend(), track)); + left_index = get_next_var_left2right(right_index, right, k, track, + ys_arg, ys_left2center); + (*i)->init_indices_outside(left_index, right_index, k, + track, center_left, rightmost_index, true); + right_index = left_index; + } + + Alt::Base::init_indices_outside(leftmost_index, rightmost_index, k, track, + center_left, center_right); + // store original left/right for e.g. + // correct initialization of IF guards; see function init_guards() + this->left_inside_indices.resize(this->left_indices.size()); + this->right_inside_indices.resize(this->right_indices.size()); + this->left_inside_indices[track] = left; + this->right_inside_indices[track] = right; + + // argument containing outside NT + if (arg_outside != NULL) { + arg_outside->init_indices_outside(left, right, k, track, + lhs_right_index, right_index); + this->expand_outside_nt_indices(leftmost_index, rightmost_index, track); + } +} +void Alt::Link::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + Alt::Base::init_indices_outside(left, right, k, track, center_left, + center_right); +} +void Alt::Block::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + throw LogError("Alt::Block::init_indices_outside blocks must be " + "resolved prior to outside generation, see function " + "Grammar::resolve_blocks!"); +} +void Alt::Multi::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + + Alt::Base::init_indices_outside(left, right, k, track, center_left, + center_right); + 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, thus we here deal only with + // ONE list element, chosen by the track + (*i)->init_indices_outside(left, right, k, 0, center_left, center_right); +} + +std::pair *Alt::Base::get_outside_accum_yieldsizes( + size_t track, bool is_right_of_outside_nt) { + std::pair *res = + new std::pair( + new Yield::Size(), new Yield::Size()); + return res; +} +std::pair +*Alt::Simple::get_outside_accum_yieldsizes(size_t track, + bool is_right_of_outside_nt) { + // first = left, second = right + std::pair *res = + new std::pair( + new Yield::Size(), new Yield::Size()); + + Fn_Arg::Base *arg_outside = NULL; + for (std::list::const_iterator i = args.begin(); + i != args.end(); ++i) { + Fn_Arg::Const *constarg = dynamic_cast(*i); + if (constarg != NULL) { + // skip constant arguments like CHAR('A') + continue; + } + Symbol::NT *ont = get_outside_NT((*i)->alt_ref()); + if (ont) { + arg_outside = *i; + std::pair *sub_ys = + arg_outside->alt_ref()->get_outside_accum_yieldsizes( + track, is_right_of_outside_nt); + *(res->first) += *(sub_ys->first); + *(res->second) += *(sub_ys->second); + continue; + } + if ((arg_outside == NULL) && (is_right_of_outside_nt == false)) { + *(res->first) += (*i)->multi_ys()(track); + } else { + // if the alternative links to a non-terminal AND the non-terminal + // has a sub-quadratic table, we do NOT add the yield size + if (arg_outside != NULL) { + if (arg_outside->alt_ref()->is(Alt::LINK)) { + Symbol::NT *linkedNT = dynamic_cast( + dynamic_cast(arg_outside->alt_ref())->nt); + if (linkedNT) { + if (linkedNT->tables()[track].is_cyk_right()) { + continue; + } + } + } + } + *(res->second) += (*i)->multi_ys()(track); + } + } + + return res; +} +std::pair +*Alt::Link::get_outside_accum_yieldsizes(size_t track, + bool is_right_of_outside_nt) { + return Alt::Base::get_outside_accum_yieldsizes(track, is_right_of_outside_nt); +} +std::pair +*Alt::Block::get_outside_accum_yieldsizes(size_t track, + bool is_right_of_outside_nt) { + throw LogError( + "Alt::Block::get_outside_accum_yieldsizes blocks must be resolved prior " + "to outside generation, see function Grammar::resolve_blocks!"); + return NULL; +} +std::pair +*Alt::Multi::get_outside_accum_yieldsizes(size_t track, + bool is_right_of_outside_nt) { + throw LogError( + "Alt::Block::get_outside_accum_yieldsizes is not yet implemented!"); + return NULL; +} + + +Yield::Size *Alt::Simple::sum_ys_lefts( + Yield::Size *y, std::list::const_reverse_iterator i, + const std::list::const_reverse_iterator &end, size_t track) + const { + Yield::Size *res = new Yield::Size(); +// *res += *y; + ++i; + for (; i != end; ++i) { + *res += (*i)->multi_ys()(track); + } + return res; +} +Yield::Size *Alt::Simple::sum_ys_rights( + Yield::Size *y, std::list::const_iterator i, + const std::list::const_iterator &end, size_t track) + const { + Yield::Size *res = new Yield::Size(); +// *res += *y; + ++i; + for (; i != end; ++i) { + *res += (*i)->multi_ys()(track); + } + return res; +} + + +// find_block can traverse a (top-level) alternative and returns +// the first occurrence of a Alt::Block instance OR NULL if this +// alternative does not contain any Alt::Block instances. +Alt::Base *Alt::Base::find_block() { + throw LogError("Should not be called directly!"); + return NULL; +} +Alt::Base *Alt::Simple::find_block() { + for (std::list::iterator i = this->args.begin(); + i != this->args.end(); ++i) { + Fn_Arg::Alt *fn_arg = dynamic_cast(*i); + if (fn_arg) { + Alt::Block *block = dynamic_cast((*i)->alt_ref()); + if (block) { + return (*i)->alt_ref(); + } else { + Alt::Base *sub = (*i)->alt_ref()->find_block(); + if (sub) { + return sub; + } + } + } + } + return NULL; +} +Alt::Base *Alt::Link::find_block() { + // a Link is a leaf and thus cannot have a Block as a child + return NULL; +} +Alt::Base *Alt::Block::find_block() { + return this; +} +Alt::Base *Alt::Multi::find_block() { + for (std::list::iterator i = this->list.begin(); + i != this->list.end(); ++i) { + Alt::Block *block = dynamic_cast(*i); + if (block) { + return *i; + } else { + Alt::Base *sub = (*i)->find_block(); + if (sub) { + return sub; + } + } + } + return NULL; +} + +Alt::Base *Alt::Base::find_block_parent(const Alt::Base &block) { + throw LogError("Should not be called directly!"); + return NULL; +} +Alt::Base *Alt::Simple::find_block_parent(const Alt::Base &block) { + for (std::list::iterator i = this->args.begin(); + i != this->args.end(); ++i) { + Fn_Arg::Alt *fn_arg = dynamic_cast(*i); + if (fn_arg) { + Alt::Block *child_block = dynamic_cast((*i)->alt_ref()); + if (child_block) { + if (child_block == &block) { + return this; + } + } else { + Alt::Base *sub = (*i)->alt_ref()->find_block_parent(block); + if (sub) { + return sub; + } + } + } + } + return NULL; +} +Alt::Base *Alt::Link::find_block_parent(const Alt::Base &block) { + // a Link is a leaf and thus cannot have a Block as a child + return NULL; +} +Alt::Base *Alt::Block::find_block_parent(const Alt::Base &block) { + for (std::list::iterator i = this->alts.begin(); + i != this->alts.end(); ++i) { + Alt::Block *child_block = dynamic_cast(*i); + if (child_block) { + if (child_block == &block) { + return this; + } + } else { + Alt::Base *sub = (*i)->find_block_parent(block); + if (sub) { + return sub; + } + } + } + return NULL; +} +Alt::Base *Alt::Multi::find_block_parent(const Alt::Base &block) { + for (std::list::iterator i = this->list.begin(); + i != this->list.end(); ++i) { + Alt::Block *child_block = dynamic_cast(*i); + if (child_block) { + if (child_block == &block) { + return this; + } + } else { + Alt::Base *sub = (*i)->find_block_parent(block); + if (sub) { + return sub; + } + } + } + return NULL; +} diff --git a/src/alt.hh b/src/alt.hh index 0d0408517..26230af00 100644 --- a/src/alt.hh +++ b/src/alt.hh @@ -28,6 +28,7 @@ #include #include #include +#include #include "grammar.hh" #include "runtime.hh" @@ -136,6 +137,10 @@ class Base { protected: std::vector left_indices; std::vector right_indices; + // for outside non-terminals: store original inner left/right indices for + // guards construction + std::vector left_inside_indices; + std::vector right_inside_indices; public: Statement::Var_Decl *ret_decl; @@ -219,6 +224,22 @@ class Base { virtual void init_indices( Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track); + // recurses into alternatives, finds the single outside NT and updates + // only its left and right indices used after init_indices_outside + // initializes all other incides + // e.g. foo(k1_REGION_i, i_bar_j, j_REGION_k2) --> foo(k1_REGION_i, + // ^ ^ + // k1_bar_k2, j_REGION_k2) + // ^^ ^^ + virtual void expand_outside_nt_indices(Expr::Base *left, Expr::Base *right, + size_t track); + virtual std::pair *get_outside_accum_yieldsizes( + size_t track, bool is_right_of_outside_nt = false); + // sets indices for outside rules, respecting yield sizes + virtual void init_indices_outside( + Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track, + Expr::Base *center_left, Expr::Base *center_right, + bool is_right_of_outside_nt = false); virtual void init_ret_decl(unsigned int i, const std::string &prefix); @@ -269,13 +290,15 @@ class Base { protected: Yield::Multi m_ys; + public: virtual void init_multi_ys(); const Yield::Multi &multi_ys() const { return m_ys; } + Yield::Multi m_ys_inside; - private: + public: std::vector > multi_filter; public: @@ -316,8 +339,45 @@ class Base { bool choice_set(); unsigned int to_dot_semanticfilters(unsigned int *nodeID, unsigned int thisID, std::ostream &out, std::vector *childIDs = NULL); + virtual unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, - int plot_level); + int plot_level); + + // traverses the alternative (=rhs of a production) and collects pointers + // to all referenced non-terminals e.g. + // ml_comps = cadd(incl(dangle), ml_comps1) + // should return [*dangle, *ml_comps1] + virtual void get_nonterminals(std::list *nt_list); + + // flag alternative as being part of a generated outside non-terminal + // such that code generation can discriminate between inside (default) + // and outside. + virtual void set_partof_outside(bool is_outside); + // traverses the alternative (=rhs of a production), iff non-terminal find + // is contained, replace with first occurence of non-terminal replace + virtual bool replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences); + + // returns either the single outside non-terminal or NULL + Symbol::NT *get_outside_nt(Alt::Base *alt); + + protected: + // private flag to indicate if alternative is for inside (the default) or + // outside production rules. See set_partof_outside() + bool is_partof_outside; + + public: + bool get_is_partof_outside() { + return this->is_partof_outside; + } + // traverses production rule and returns pointer to topmost Alt::Block IFF + // production rule contains an Alt::Block, otherwise NULL + virtual Alt::Base* find_block(); + // given a Alt::Block reference, returns the Alt::Base reference of the + // parent with child Alt::Block (necessary to change pointer when resolving + // blocks) + virtual Alt::Base *find_block_parent(const Alt::Base &block); + bool inside_end = false; }; @@ -402,6 +462,7 @@ class Simple : public Base { std::list body_stmts; Statement::If *guards; + Statement::If *guards_inside; void ret_decl_empty_block(Statement::If *stmt); void deep_erase_if_backtrace( Statement::If *stmt, std::vector::iterator start, @@ -432,6 +493,20 @@ class Simple : public Base { public: void init_indices( Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track); + Expr::Base *get_next_var_right2left(Expr::Base *left_index, + Expr::Base *innermost_left_index, unsigned &k, size_t track, + Yield::Size ys_this, Yield::Size *ys_lefts); + Expr::Base *get_next_var_left2right(Expr::Base *right_index, + Expr::Base *innermost_right_index, unsigned &k, size_t track, + Yield::Size ys_this, Yield::Size *ys_rights); + void expand_outside_nt_indices(Expr::Base *left, Expr::Base *right, + size_t track); + std::pair *get_outside_accum_yieldsizes( + size_t track, bool is_right_of_outside_nt = false); + void init_indices_outside( + Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track, + Expr::Base *center_left, Expr::Base *center_right, + bool is_right_of_outside_nt = false); void put_indices(std::ostream &s); void reset(); @@ -458,6 +533,9 @@ class Simple : public Base { std::list *stmts, std::list loops, bool has_index_overlay); + std::list *add_guards( + std::list *stmts, + Statement::If *guards); void sum_rhs( Yield::Multi &y, std::list::const_iterator i, const std::list::const_iterator &end) const; @@ -465,6 +543,14 @@ class Simple : public Base { Yield::Size &y, std::list::const_iterator i, const std::list::const_iterator &end, size_t track) const; + Yield::Size *sum_ys_lefts( + Yield::Size *y, std::list::const_reverse_iterator i, + const std::list::const_reverse_iterator &end, size_t track) + const; + Yield::Size *sum_ys_rights( + Yield::Size *y, std::list::const_iterator i, + const std::list::const_iterator &end, size_t track) const; + public: bool multi_detect_loop( @@ -500,6 +586,14 @@ class Simple : public Base { unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + void get_nonterminals(std::list *nt_list); + void set_partof_outside(bool is_outside); + bool replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences); + + Alt::Base* find_block(); + Alt::Base *find_block_parent(const Alt::Base &block); + private: std::list *insert_index_stmts( std::list *stmts); @@ -526,9 +620,9 @@ class Link : public Base { Symbol::Base *nt; - // Inits the insatnce and sets the local fields according to + // Inits the instance and sets the local fields according to // the parameter values of the non-terminal name. It also sets - // the pointer to the non-terminal grammar-node explicitely + // the pointer to the non-terminal grammar-node explicitly // to NULL. Link(std::string *n, const Loc&l) : Base(LINK, l), name(n), nt(NULL) { @@ -575,6 +669,14 @@ class Link : public Base { void init_indices( Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track); + std::pair *get_outside_accum_yieldsizes( + size_t track, bool is_right_of_outside_nt = false); + void expand_outside_nt_indices(Expr::Base *left, Expr::Base *right, + size_t track); + void init_indices_outside( + Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track, + Expr::Base *center_left, Expr::Base *center_right, + bool is_right_of_outside_nt = false); // void init_ret_decl(unsigned int i); @@ -599,7 +701,7 @@ class Link : public Base { void multi_init_calls(const Runtime::Poly &p, size_t base_tracks); private: - void add_args(Expr::Fn_Call *fn); + void add_args(Expr::Fn_Call *fn, bool for_outside_grammar = false); private: std::list indices; @@ -615,6 +717,7 @@ class Link : public Base { private: std::list ntparas; + Statement::If *guards; public: void set_ntparas(const Loc &loc, std::list *l); @@ -622,8 +725,22 @@ class Link : public Base { bool check_ntparas(); void optimize_choice(); + + void get_nonterminals(std::list *nt_list); + void set_partof_outside(bool is_outside); + bool replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + void init_outside_guards(); + Alt::Base* find_block(); + Alt::Base *find_block_parent(const Alt::Base &block); + + /* 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; }; @@ -674,6 +791,14 @@ class Block : public Base { void traverse(Visitor &v); void init_indices( Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track); + void expand_outside_nt_indices(Expr::Base *left, Expr::Base *right, + size_t track); + std::pair *get_outside_accum_yieldsizes( + size_t track, bool is_right_of_outside_nt = false); + void init_indices_outside( + Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track, + Expr::Base *center_left, Expr::Base *center_right, + bool is_right_of_outside_nt = false); void codegen(AST &ast); @@ -691,8 +816,15 @@ class Block : public Base { void multi_collect_factors(Runtime::Poly &p); void multi_init_calls(const Runtime::Poly &p, size_t base_tracks); + + void get_nonterminals(std::list *nt_list); + void set_partof_outside(bool is_outside); + bool replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + Alt::Base* find_block(); + Alt::Base *find_block_parent(const Alt::Base &block); }; @@ -744,6 +876,15 @@ class Multi : public Base { void init_indices( Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track); + void expand_outside_nt_indices(Expr::Base *left, Expr::Base *right, + size_t track); + std::pair *get_outside_accum_yieldsizes( + size_t track, bool is_right_of_outside_nt = false); + void init_indices_outside( + Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track, + Expr::Base *center_left, Expr::Base *center_right, + bool is_right_of_outside_nt = false); + void codegen(AST &ast); void print_dot_edge(std::ostream &out, Symbol::NT &nt); void print(std::ostream &s); @@ -763,8 +904,15 @@ class Multi : public Base { void types(std::list< ::Type::Base*> &) const; const std::list &ret_decls() const; void init_ret_decl(unsigned int i, const std::string &prefix); + + void get_nonterminals(std::list *nt_list); + void set_partof_outside(bool is_outside); + bool replace_nonterminal(Symbol::NT *find, Symbol::NT *replace, + hashtable &skip_occurences); unsigned int* to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + Alt::Base* find_block(); + Alt::Base *find_block_parent(const Alt::Base &block); }; } // namespace Alt diff --git a/src/checkpoint.hh b/src/checkpoint.hh index c0ba33c86..6cb09eef0 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 for_outside) { inc_indent(); stream << indent() << "void archive_cyk_indices() {" << endl; inc_indent(); @@ -1004,6 +1005,17 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", stream << indent() << "array_out << " << "(t_" << i << "_j == 0 ? 0 : t_" << i << "_j - 1);" << endl; } + if (for_outside) { + 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 << outside_t_" << i << "_i + 1;" + << endl; + stream << indent() << "array_out << " + << "(outside_t_" << i << "_j == 0 ? 0 : outside_t_" << i + << "_j - 1);" << endl; + } + } stream << indent() << "#ifdef _OPENMP" << endl; stream << indent() << " array_out << outer_loop_1_idx;" << endl; stream << indent() << " array_out << outer_loop_2_idx;" << endl; @@ -1042,7 +1054,8 @@ 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 for_outside) { inc_indent(); stream << indent() << "void load_cyk_indices() {" << endl; inc_indent(); @@ -1060,6 +1073,12 @@ SUPPORTED_EXTERNAL_TYPES = {"Rope", "answer_pknot_mfe", "pktype", stream << indent() << "array_in >> t_" << i << "_i;" << endl; stream << indent() << "array_in >> t_" << i << "_j;" << endl; } + if (for_outside) { + for (size_t i = 0; i < n_tracks; i++) { + stream << indent() << "array_in >> outside_t_" << i << "_i;" << endl; + stream << indent() << "array_in >> outside_t_" << i << "_j;" << endl; + } + } stream << indent() << "#ifdef _OPENMP" << endl; stream << indent() << " array_in >> outer_loop_1_idx;" << endl; stream << indent() << " array_in >> outer_loop_2_idx;" << endl; diff --git a/src/cpp.cc b/src/cpp.cc index 817cc0cc8..0373371e8 100644 --- a/src/cpp.cc +++ b/src/cpp.cc @@ -1552,6 +1552,12 @@ void Printer::Cpp::print_seq_init(const AST &ast) { stream << indent() << "t_" << i << "_i = 0;" << endl; stream << indent() << "t_" << i << "_j = 0;" << endl; } + if (ast.grammar()->is_outside()) { + for (size_t i = 0; i < ast.grammar()->axiom->tracks(); i++) { + stream << indent() << "outside_t_" << i << "_i = 0;" << endl; + stream << indent() << "outside_t_" << i << "_j = 0;" << endl; + } + } stream << indent() << "#ifdef _OPENMP" << endl; inc_indent(); stream << indent() << "outer_loop_1_idx = 0;" << endl; @@ -1855,6 +1861,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.grammar()).is_outside()) { + stream << "#define OUTSIDE\n"; + } stream << "#define GAPC_CALL_STRING \"" << gapc_call_string << "\"" << endl; @@ -1933,6 +1942,12 @@ void Printer::Cpp::header(const AST &ast) { stream << indent() << *type << " t_" << t << "_i;" << endl; stream << indent() << *type << " t_" << t << "_j;" << endl; } + if (ast.grammar()->is_outside()) { + for (size_t t = 0; t < ast.grammar()->axiom->tracks(); t++) { + stream << indent() << *type << " outside_t_" << t << "_i;" << endl; + stream << indent() << *type << " outside_t_" << t << "_j;" << endl; + } + } stream << "#ifdef _OPENMP" << endl; stream << indent() << "int outer_loop_1_idx, outer_loop_2_idx, " << "inner_loop_2_idx;" << endl; @@ -1960,66 +1975,67 @@ void Printer::Cpp::header(const AST &ast) { } -void Printer::Cpp::print_openmp_cyk_nt_calls(const AST &ast) { +void Printer::Cpp::print_openmp_cyk_nt_calls(const AST &ast, + bool for_outsideNTs) { std::list &tord = ast.grammar()->topological_ord(); assert(tord.size() <= ast.grammar()->NTs.size()); std::ostringstream o1; for (std::list::iterator i = tord.begin(); i != tord.end(); ++i) { - assert(!(*i)->tables().empty()); - if ((*i)->is_tabulated() && !(*i)->tables().front().is_cyk_right()) { - o1 << indent() << "nt_tabulate_" << *(*i)->name << "(" - << multi_index_str((*i)->tables(), (*i)->multi_ys()) - << ");\n"; + if ((*i)->is_partof_outside == for_outsideNTs) { + assert(!(*i)->tables().empty()); + if ((*i)->is_tabulated() && !(*i)->tables().front().is_cyk_right()) { + o1 << indent() << "nt_tabulate_" << *(*i)->name << "(" + << multi_index_str((*i)->tables(), (*i)->multi_ys(), + (*i)->is_partof_outside) + << ");\n"; + } } } std::string nt_calls = o1.str(); stream << nt_calls; } -void Printer::Cpp::print_openmp_cyk_all_nt_calls(const AST &ast) { +void Printer::Cpp::print_openmp_cyk_all_nt_calls(const AST &ast, + bool for_outsideNTs) { std::list &tord = ast.grammar()->topological_ord(); std::ostringstream o2; for (std::list::iterator i = tord.begin(); i != tord.end(); ++i) { - if ((*i)->is_tabulated()) { - o2 << indent() << "nt_tabulate_" << *(*i)->name << "(" - << multi_index_str((*i)->tables(), (*i)->multi_ys()) - << ");\n"; + if ((*i)->is_partof_outside == for_outsideNTs) { + if ((*i)->is_tabulated()) { + o2 << indent() << "nt_tabulate_" << *(*i)->name << "(" + << multi_index_str((*i)->tables(), (*i)->multi_ys(), + (*i)->is_partof_outside) + << ");\n"; + } } } std::string all_nt_calls = o2.str(); stream << all_nt_calls; } -void Printer::Cpp::print_openmp_cyk_helpervars() { - stream << indent() << "unsigned int n = t_0_seq.size();" << endl; - if (!ast->checkpoint) { - stream << indent() << "unsigned int tile_size = 32;" << endl; - stream << "#ifdef TILE_SIZE" << endl; - stream << indent() << "tile_size = TILE_SIZE;" << endl; - stream << "#endif" << endl; +void Printer::Cpp::print_openmp_cyk_helpervars(bool for_outsideNTs) { + stream << indent() << "unsigned int "; + if (for_outsideNTs) { + stream << "t_0_"; + } + stream << "n = t_0_seq.size();" << endl; + if (!for_outsideNTs) { + if (!ast->checkpoint) { + stream << indent() << "unsigned int tile_size = 32;" << endl; + stream << "#ifdef TILE_SIZE" << endl; + stream << indent() << "tile_size = TILE_SIZE;" << endl; + stream << "#endif" << endl; + } + stream << indent() << "assert(tile_size);" << endl; + stream << indent() << "unsigned int max_tiles = n / tile_size;" << endl; + stream << indent() << "int max_tiles_n = max_tiles * tile_size;" << endl; } - stream << indent() << "assert(tile_size);" << endl; - stream << indent() << "unsigned int max_tiles = n / tile_size;" << endl; - stream << indent() << "int max_tiles_n = max_tiles * tile_size;" << endl; } - -// FIXME adjust for multi-track (> 1 track) -void Printer::Cpp::print_openmp_cyk(const AST &ast) { - // FIXME abstract from unsigned int, int -> perhaps wait for OpenMP 3 - // since OpenMP < 3 doesn't allow unsigned int in workshared fors - - // paral_start - stream << indent() << "#pragma omp parallel" << endl; - stream << indent() << '{' << endl; - inc_indent(); - - // helper_vars - print_openmp_cyk_helpervars(); - - bool checkpoint = ast.checkpoint && ast.checkpoint->cyk; - +void Printer::Cpp::print_openmp_cyk_loops_diag(const AST &ast, + bool checkpoint, + bool for_outsideNTs) { /* * need ordered clause in omp statement, because this will * ensure that each thread syncs with all other threads @@ -2031,7 +2047,7 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { if (checkpoint) { stream << indent() << "#pragma omp for ordered schedule(dynamic)" << endl; } else { - stream << indent() << "#pragma omp for" << endl; + stream << indent() << "#pragma omp for" << endl; } stream << indent() << "// OPENMP < 3 requires signed int here ..." << endl; stream << indent(); @@ -2046,13 +2062,14 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { if (checkpoint) { stream << indent() << "mutex.lock_shared();" << endl; } - stream << indent() << "for (unsigned int t_0_j = z; " - << "t_0_j < z + tile_size; ++t_0_j) {" << endl; + stream << indent(); + stream << "for (unsigned int t_0_j = z; t_0_j < z + tile_size; ++t_0_j) {"; + stream << endl; inc_indent(); - stream << indent() << "for (int t_0_i = t_0_j + 1; " - << "t_0_i > z; --t_0_i) {" << endl; + stream << indent() << "for (int t_0_i = t_0_j + 1; t_0_i > z; --t_0_i) {"; + stream << endl; inc_indent(); - print_openmp_cyk_nt_calls(ast); + print_openmp_cyk_nt_calls(ast, for_outsideNTs); dec_indent(); stream << indent() << "}" << endl; dec_indent(); @@ -2071,8 +2088,10 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { } dec_indent(); stream << indent() << "}" << endl; - - // middle +} +void Printer::Cpp::print_openmp_cyk_loops_middle(const AST &ast, + bool checkpoint, + bool for_outsideNTs) { stream << endl; if (checkpoint) { stream << indent() @@ -2088,25 +2107,26 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { stream << indent() << "mutex.lock_shared();" << endl; } else { stream << indent() - << "for (int z = tile_size; " - << "z < max_tiles_n; z+=tile_size) {" << endl; + << "for (int z = tile_size; z < max_tiles_n; z+=tile_size) {" + << endl; inc_indent(); stream << indent() << "#pragma omp for" << endl; - stream << indent() << "for (int y = z; y < max_tiles_n; y+=tile_size) {" - << endl; + stream << indent() + << "for (int y = z; y < max_tiles_n; y+=tile_size) {" << endl; inc_indent(); } stream << indent() << "unsigned int x = y - z + tile_size;" << endl; stream << indent() - << "for (unsigned int t_0_j = y; " - << "t_0_j < y + tile_size; ++t_0_j) {" << endl; + << "for (unsigned int t_0_j = y; t_0_j < y + tile_size; ++t_0_j) {" + << endl; inc_indent(); stream << indent() - << "for (unsigned int t_0_i = x; " - << "t_0_i > x - tile_size; --t_0_i) {" << endl; + << "for (unsigned int t_0_i = x; t_0_i > x - tile_size;" + << " --t_0_i) {" + << endl; inc_indent(); - print_openmp_cyk_nt_calls(ast); + print_openmp_cyk_nt_calls(ast, for_outsideNTs); // paral_end dec_indent(); @@ -2119,7 +2139,9 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { inc_indent(); stream << indent() << "inner_loop_2_idx += tile_size;" << endl; stream << indent() << "outer_loop_2_idx = z;" << endl; - stream << indent() << "mutex.unlock_shared();" << endl; + if (for_outsideNTs) { + stream << indent() << "mutex.unlock_shared();" << endl; + } dec_indent(); stream << indent() << "}" << endl; } @@ -2133,11 +2155,10 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { dec_indent(); stream << indent() << "} // end parallel" << endl; stream << endl; - - // REPEAT: helper_vars - print_openmp_cyk_helpervars(); - - // single +} +void Printer::Cpp::print_openmp_cyk_loops_single(const AST &ast, + bool checkpoint, + bool for_outsideNTs) { if (checkpoint) { stream << indent() << "for (t_0_j = (t_0_j_loaded++) ? max_tiles_n : t_0_j; " @@ -2162,10 +2183,8 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { if (ast.checkpoint && ast.checkpoint->cyk) { stream << indent() << "mutex.lock_shared();" << endl; } - - print_openmp_cyk_all_nt_calls(ast); - - if (ast.checkpoint && ast.checkpoint->cyk) { + print_openmp_cyk_all_nt_calls(ast, for_outsideNTs); + if (ast.checkpoint && ast.checkpoint->cyk && for_outsideNTs) { stream << indent() << "mutex.unlock_shared();" << endl; } @@ -2176,9 +2195,62 @@ void Printer::Cpp::print_openmp_cyk(const AST &ast) { stream << indent() << "}" << endl; } +// FIXME adjust for multi-track (> 1 track) +void Printer::Cpp::print_openmp_cyk(const AST &ast) { + // FIXME abstract from unsigned int, int -> perhaps wait for OpenMP 3 + // since OpenMP < 3 doesn't allow unsigned int in workshared fors + + // paral_start + stream << indent() << "#pragma omp parallel" << endl; + stream << indent() << '{' << endl; + inc_indent(); + + // helper_vars + print_openmp_cyk_helpervars(); + + bool checkpoint = ast.checkpoint && ast.checkpoint->cyk; + + // diag + print_openmp_cyk_loops_diag(ast, checkpoint); + + // middle + print_openmp_cyk_loops_middle(ast, checkpoint); + + // REPEAT: helper_vars + print_openmp_cyk_helpervars(); + + // single + print_openmp_cyk_loops_single(ast, checkpoint); + + // same as above but for outside non terminals + if (ast.grammar()->is_outside()) { + // paral_start + stream << endl << indent() << "// repeat for outside non-terminals" << endl; + stream << indent() << "#pragma omp parallel" << endl; + stream << indent() << '{' << endl; + inc_indent(); + + // helper_vars + print_openmp_cyk_helpervars(true); + + // diag + print_openmp_cyk_loops_diag(ast, checkpoint, true); + + // middle + print_openmp_cyk_loops_middle(ast, checkpoint, true); + + // REPEAT: helper_vars + print_openmp_cyk_helpervars(true); + + // single + print_openmp_cyk_loops_single(ast, checkpoint, true); + } +} + std::string Printer::Cpp::multi_index_str( - const std::vector
&tables, const Yield::Multi &mys) { + const std::vector
&tables, const Yield::Multi &mys, + bool is_outside) { assert(tables.size() == mys.tracks()); std::ostringstream o; size_t track = 0; @@ -2186,10 +2258,18 @@ std::string Printer::Cpp::multi_index_str( for (std::vector
::const_iterator i = tables.begin(); i != tables.end(); ++i, ++j, ++track) { if (!(*i).delete_left_index()) { - o << ", t_" << track << "_i-1"; + if (is_outside == false) { + o << ", t_" << track << "_i-1"; + } else { + o << ", (t_" << track << "_j - t_" << track << "_i + 1)"; + } } if (!(*i).delete_right_index()) { - o << ", t_" << track << "_j"; + if (is_outside == false) { + o << ", t_" << track << "_j"; + } else { + o << ", (t_" << track << "_n - t_" << track << "_i + 1)"; + } } } std::string r(o.str()); @@ -2205,20 +2285,23 @@ void Printer::Cpp::multi_print_inner_cyk( const std::list &l, const std::list &tord, size_t track, size_t tracks, size_t track_pos, - Type::Base *t, bool checkpoint) { + Type::Base *t, bool checkpoint, bool no_mutex_def, bool for_outsideNTs) { assert(track < tracks); if (track+1 != tracks) { multi_print_cyk(tord, track+1, tracks, track_pos, t); return; } - if (checkpoint) { + if (checkpoint && !no_mutex_def) { stream << indent() << "std::lock_guard lock(mutex);" << endl; } for (std::list::const_iterator i = l.begin(); i != l.end(); ++i) { - std::string index_str = multi_index_str((*i)->tables(), (*i)->multi_ys()); - stream << indent() << "nt_tabulate_" << *(*i)->name << '(' - << index_str << ");" << endl; + if ((*i)->is_partof_outside == for_outsideNTs) { + std::string index_str = multi_index_str((*i)->tables(), (*i)->multi_ys(), + (*i)->is_partof_outside); + stream << indent() << "nt_tabulate_" << *(*i)->name << '(' + << index_str << ");" << endl; + } } } @@ -2255,58 +2338,54 @@ void Printer::Cpp::multi_partition_nts( } } - -void Printer::Cpp::multi_print_cyk( - const std::list &tord, size_t track, size_t tracks, - size_t track_pos, Type::Base *t) { - std::list all, inner, left, right; - multi_partition_nts(tord, all, inner, left, right, track, tracks, track_pos); - - size_t real_track = !track_pos ? track : track_pos; - - std::ostringstream sis, sjs, sns; - sis << "t_" << track << "_i"; - sjs << "t_" << track << "_j"; - sns << "t_" << real_track << "_n"; - std::string is(sis.str()), js(sjs.str()), ns(sns.str()); - - stream << indent() << *t << " t_" << track << "_n = t_" << real_track - << "_seq.size();" << endl << endl; - - bool checkpoint = ast->checkpoint && ast->checkpoint->cyk; - - // SMJ 2023-02-18: I've added the x: xxx loops comments, but - // am not 100% sure if they are correct in multitrack contexts - if (!inner.empty()) { +void Printer::Cpp::multi_print_cyk_loops_quadratic( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *inner, + std::list *left, + std::string *is, + std::string *js, + std::string *ns, bool checkpoint, bool for_outsideNTs) { + std::string oprefix = ""; + if (for_outsideNTs) { + oprefix = "outside_"; + } + if (!inner->empty()) { if (checkpoint) { /* - in checkpointing mode, the loop indices - (e.g. t_0_i and t_0_j in single-track mode; - names can differ in multi-track mode) - are members of the out class instead of local loop variables - so they can be archived/loaded; - if they are loaded, the loop variable (e.g. t_0_j) starts - from whatever value was loaded from the checkpoint, - which is handled through a marker - for every loop variable (e.g. "t_0_j_loaded"); - initially, all of these marker values are set to 0, which will - set each loop variable to whatever value was loaded from the checkpoint; - after that, the respective marker value will be set to 1, - so the loop variable will be set to whatever - value is usually would be set to + in checkpointing mode, the loop indices + (e.g. t_0_i and t_0_j in single-track mode; + names can differ in multi-track mode) + are members of the out class instead of local loop variables + so they can be archived/loaded; + if they are loaded, the loop variable (e.g. t_0_j) starts + from whatever value was loaded from the checkpoint, + which is handled through a marker + for every loop variable (e.g. "t_0_j_loaded"); + initially, all of these marker values are set to 0, which will + set each loop variable to whatever value was loaded from the checkpoint; + after that, the respective marker value will be set to 1, + so the loop variable will be set to whatever + value is usually would be set to */ - stream << indent() << "for (" << js << " = (" << js << "_loaded++) " - << "? 0 : " << js << "; " - << js << " < " << ns << "; " << "++" << js << ") {" + stream << indent() << "for (" << *js << " = (" << oprefix << *js + << "_loaded++) " + << "? 0 : " << oprefix << *js << "; " + << *js << " < " << *ns << "; " << "++" << *js << ") {" << endl; - inc_indent(); } else { - stream << indent() << "for (" << *t << " " << js << " = 0; " - << js << " < " << ns << "; " << "++" << js << ") {" - << endl; - inc_indent(); + stream << indent() << "for (" << *t << " " << *js << " = 0; " << *js + << " < " << *ns << "; " << "++" << *js << ") {" << endl; + } + inc_indent(); + if (for_outsideNTs) { + multi_print_cyk_loops_quadratic_inner( + tord, track, tracks, track_pos, t, left, is, + checkpoint, for_outsideNTs); } - stream << indent() << "// A: quadratic loops" << endl; if (checkpoint) { /* @@ -2317,74 +2396,201 @@ void Printer::Cpp::multi_print_cyk( for t_0_i in the first inner loop pass; afterwards it will regularly be set to t_0_j + 1; */ - stream << indent() << "for (" << is << " = (" << is << "_loaded++) " - << "? " << js << " + 1 : " << is << "; " - << is << " > 1; " << is << "--) {" << endl; - inc_indent(); + stream << indent() << "for (" << *is << " = (" << oprefix << *is + << "_loaded++) " + << "? " << *js << " + 1 : " << oprefix << *is << "; " + << *is << " > 1; " << *is << "--) {" << endl; } else { - stream << indent() << "for (" << *t << " " << is << " = " - << js << " + 1; " << is << " > 1; " << is << "--) {" << endl; - inc_indent(); + stream << indent() << "for (" << *t << " " << *is << " = " << *js + << " + 1; " << *is << " > 1; " << *is << "--) {" << endl; } + inc_indent(); - multi_print_inner_cyk(inner, tord, track, tracks, track_pos, t, checkpoint); + multi_print_inner_cyk(*inner, tord, track, tracks, track_pos, t, + checkpoint, false, for_outsideNTs); dec_indent(); stream << indent() << "}" << endl << endl; - if (!left.empty()) { - stream << indent() << "// B: inner quadratic loops" << endl; - stream << indent() << *t << " " << is << " = 1;" << endl; - multi_print_inner_cyk(left, tord, track, tracks, - track_pos, t, checkpoint); + if (!for_outsideNTs) { + multi_print_cyk_loops_quadratic_inner( + tord, track, tracks, track_pos, t, left, is, + checkpoint, for_outsideNTs); } dec_indent(); stream << indent() << "}" << endl << endl; } - if (inner.empty() && !left.empty()) { +} +void Printer::Cpp::multi_print_cyk_loops_quadratic_inner( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *left, + std::string *is, + bool checkpoint, + bool for_outsideNTs) { + if (!left->empty()) { + stream << indent() << "// B: inner quadratic loops" << endl; + stream << indent(); + if (!for_outsideNTs) { + stream << *t << " "; + } + stream << *is << " = 1;" << endl; + multi_print_inner_cyk(*left, tord, track, tracks, track_pos, t, + checkpoint, for_outsideNTs, for_outsideNTs); + } +} +void Printer::Cpp::multi_print_cyk_loops_linear( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *inner, + std::list *left, + std::list *right, + std::string *is, + std::string *js, + std::string *ns, + bool checkpoint, + bool for_outsideNTs + ) { + std::string oprefix = ""; + if (for_outsideNTs) { + oprefix = "outside_"; + } + if (inner->empty() && !left->empty()) { stream << indent() << "// C: linear loops" << endl; if (checkpoint) { - stream << indent() << "for (" << js << " = (" << js << "_loaded++) " - << "? 0 : " << js << "; " << js << " < " << ns - << "; " << "++" << js << ") {" << endl; - inc_indent(); + stream << indent() << "for (" << *js << " = (" << oprefix << *js + << "_loaded++) " + << "? 0 : " << oprefix << *js << "; " << *js << " < " << *ns + << "; " << "++" << *js << ") {" << endl; } else { - stream << indent() << "for (" << *t << " " << js << " = 0; " - << js << " < " << ns - << "; " << "++" << js << ") {" << endl; - inc_indent(); + stream << indent() << "for (" << *t << " " << *js << " = 0; " + << *js << " < " << *ns + << "; " << "++" << *js << ") {" << endl; + } + inc_indent(); + stream << indent(); + if (!for_outsideNTs) { + stream << *t << " "; } - stream << indent() << *t << " " << is << " = 1;" << endl; - multi_print_inner_cyk(left, tord, track, tracks, track_pos, t, checkpoint); + stream << *is << " = 1;" << endl; + multi_print_inner_cyk(*left, tord, track, tracks, track_pos, t, + checkpoint, false, for_outsideNTs); dec_indent(); stream << indent() << "}" << endl << endl; } - if (!right.empty()) { + if (!right->empty()) { stream << indent() << "// C: linear loops" << endl; - stream << indent() << *t << " " << js << " = " << ns << ";" << endl; + stream << indent(); + if (!for_outsideNTs) { + stream << *t << " "; + } + stream << *js << " = " << *ns << ";" << endl; if (checkpoint) { /* in checkpointing mode, the entire quadratic loop (A) will be skipped if the loaded value for t_0_j == t_0_n, so this is the loop that would get executed next */ - stream << indent() << "for (" << is << " = (" << is << "_loaded++) " - << "? " << js << " + 1 : " << is << "; " - << is << " > 1; " << is << "--) {" << endl; - inc_indent(); + stream << indent() << "for (" << *is << " = (" << oprefix << *is + << "_loaded++) " + << "? " << *js << " + 1 : " << oprefix << *is << "; " + << *is << " > 1; " << *is << "--) {" << endl; } else { - stream << indent() << "for (" << *t << " "<< is << " = " << js << " + 1; " - << is << " > 1; " << is << "--) {" << endl; - inc_indent(); + stream << indent() << "for (" << *t << " "<< *is << " = " << *js + << " + 1; " << *is << " > 1; " << *is << "--) {" << endl; } - multi_print_inner_cyk(right, tord, track, tracks, track_pos, t, checkpoint); + inc_indent(); + multi_print_inner_cyk(*right, tord, track, tracks, track_pos, t, + checkpoint, false, for_outsideNTs); dec_indent(); stream << indent() << "}" << endl << endl; } - - if (!all.empty()) { +} +void Printer::Cpp::multi_print_cyk_loops_constant( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *all, + std::string *is, + bool checkpoint, + bool for_outsideNTs + ) { + if (!all->empty()) { stream << indent() << "// D: constant loops" << endl; - stream << indent() << *t << " " << is << " = 1;" << endl; - multi_print_inner_cyk(all, tord, track, tracks, track_pos, t, checkpoint); + stream << indent(); + if (!for_outsideNTs) { + stream << *t << " "; + } + stream << *is << " = 1;" << endl; + /* when constructing commands to compute constant results, there is no + * enclosing loop context, i.e. mutex definition will occure in function + * context. Since we repeat these commands for outside contexts, the + * mutex would be defined twice. We avoid this here. */ + bool no_mutex_def = for_outsideNTs; + multi_print_inner_cyk(*all, tord, track, tracks, track_pos, t, + checkpoint, no_mutex_def, for_outsideNTs); + } +} + +void Printer::Cpp::multi_print_cyk( + const std::list &tord, size_t track, size_t tracks, + size_t track_pos, Type::Base *t) { + std::list all, inner, left, right; + multi_partition_nts(tord, all, inner, left, right, track, tracks, track_pos); + + size_t real_track = !track_pos ? track : track_pos; + + std::ostringstream sis, sjs, sns; + sis << "t_" << track << "_i"; + sjs << "t_" << track << "_j"; + sns << "t_" << real_track << "_n"; + std::string is(sis.str()), js(sjs.str()), ns(sns.str()); + + stream << indent() << *t << " t_" << track << "_n = t_" << real_track + << "_seq.size();" << endl << endl; + + bool checkpoint = ast->checkpoint && ast->checkpoint->cyk; + + // inside NTs + multi_print_cyk_loops_quadratic( + tord, track, tracks, track_pos, t, &inner, &left, &is, &js, &ns, + checkpoint, false); + multi_print_cyk_loops_linear( + tord, track, tracks, track_pos, t, &inner, &left, &right, &is, &js, &ns, + checkpoint, false); + multi_print_cyk_loops_constant( + tord, track, tracks, track_pos, t, &all, &is, + checkpoint, false); + if (checkpoint && this->ast->grammar()->is_outside()) { + stream << indent() << "mutex.unlock();" << endl; + } + + // outside NTs (which access inside NT values) + if (this->ast->grammar()->is_outside()) { + stream << endl << endl; + stream << indent() << "// now compute for outside non-terminals" << endl; + multi_print_cyk_loops_quadratic( + tord, track, tracks, track_pos, t, &inner, &left, &is, &js, &ns, + checkpoint, true); + multi_print_cyk_loops_linear( + tord, track, tracks, track_pos, t, &inner, &left, &right, &is, &js, &ns, + checkpoint, true); + if (checkpoint) { + stream << indent() << "mutex.lock();" << endl; + } + multi_print_cyk_loops_constant( + tord, track, tracks, track_pos, t, &all, &is, + checkpoint, true); + if (checkpoint) { + stream << indent() << "mutex.unlock();" << endl; + } } } @@ -2431,6 +2637,17 @@ void Printer::Cpp::print_cyk_fn(const AST &ast) { << "_j_loaded = !load_checkpoint ||" << " !t_" << track_i << "_j;" << endl; } + if (ast.grammar()->is_outside()) { + for (size_t track_i = 0; + track_i < ast.grammar()->axiom->tracks(); ++track_i) { + stream << indent() << "int outside_t_" << track_i + << "_i_loaded = !load_checkpoint ||" + << " !outside_t_" << track_i << "_i;" << endl; + stream << indent() << "int outside_t_" << track_i + << "_j_loaded = !load_checkpoint ||" + << " !outside_t_" << track_i << "_j;" << endl; + } + } stream << "#ifdef _OPENMP" << endl; stream << indent() << "unsigned int tile_size = 32;" << endl; stream << "#ifdef TILE_SIZE" << endl; @@ -2493,8 +2710,152 @@ void Printer::Cpp::print_cyk_fn(const AST &ast) { stream << endl; } +void Printer::Cpp::print_insideoutside(Symbol::NT *nt) { + std::stringstream list_args; + std::stringstream list_args_print; + std::list &l = nt->code_list(); + std::vector *args = new std::vector(); + std::vector *args_call = new std::vector(); + + // aggregated level (=dim + tracks) of nested loops + unsigned int nesting = 0; + + // opening for loops + for (size_t track = 0; track < nt->tracks(); ++track) { + unsigned int dim = 2; + if (nt->table_dims_inside[track].delete_left_index()) { + dim--; + } + if (nt->table_dims_inside[track].delete_right_index()) { + dim--; + } + if (dim >= 1) { + stream << indent() << "for (unsigned int t_" << track << "_i = t_" + << track << "_left_most; t_" << track << "_i <= t_" << track + << "_right_most; ++t_" << track << "_i) {" << endl; + inc_indent(); + args->push_back("t_" + std::to_string(track) + "_i"); + } + if (dim >= 2) { + stream << indent() << "for (unsigned int t_" << track << "_j = t_" + << track << "_i; t_" << track << "_j <= t_" << track + << "_right_most; ++t_" << track << "_j) {" << endl; + inc_indent(); + args->push_back("t_" + std::to_string(track) + "_j"); + } + nesting += dim; + } + + for (size_t track = 0; track < nt->tracks(); ++track) { + std::string nextLoopVar = "i"; + if (nt->table_dims_inside[track].delete_left_index()) { + if (!nt->tables()[track].delete_left_index()) { + args_call->push_back("t_" + std::to_string(track) + "_left_most"); + } + } else { + args_call->push_back("t_" + std::to_string(track) + "_" + nextLoopVar); + nextLoopVar = "j"; + } + if (nt->table_dims_inside[track].delete_right_index()) { + if (!nt->tables()[track].delete_right_index()) { + args_call->push_back("t_" + std::to_string(track) + "_right_most"); + } + } else { + args_call->push_back("t_" + std::to_string(track) + "_" + nextLoopVar); + } + } + + // loop body + bool first = true; + for (std::vector::const_iterator a = args->begin(); + a != args->end(); ++a) { + if (!first) { + list_args_print << " << \",\""; + } + first = false; + list_args_print << " << " << *a; + } + first = true; + for (std::vector::const_iterator a = args_call->begin(); + a != args_call->end(); ++a) { + if (!first) { + list_args << ", "; + } + first = false; + list_args << *a; + } + stream << indent() << "out << \"start answers " << *nt->name + << "(\"" << list_args_print.str() << " << \"):\\n\";\n"; + for (std::list::iterator i = l.begin(); i != l.end(); ++i) { + std::string res = "res_" + *(nt->name); + stream << indent() << *((*i)->return_type) << " " << res << " = nt_" + << *nt->name << "(" << list_args.str() << ");\n" + << indent() << "print_result(std::cout, " << res << ");\n"; + // only for first return statement + break; + } + stream << indent() << "out << \"//end answers " << *nt->name << "(\"" + << list_args_print.str() << " << \")\\n\";\n"; + + // close loops + for (unsigned int d = 0; d < nesting; ++d) { + dec_indent(); + stream << indent() << "}" << endl; + } +} +void Printer::Cpp::print_insideoutside_report_fn( + std::vector outside_nt_list, const AST &ast) { + stream << indent() << "void report_insideoutside(std::ostream &out) {" + << endl; + inc_indent(); + std::list *reported_nts = new std::list(); + for (std::vector::iterator i = outside_nt_list.begin(); + i != outside_nt_list.end(); ++i) { + if ((*i).compare(std::string("ALL")) == 0) { + reported_nts->clear(); + for (hashtable::iterator + j = (*ast.grammar()).NTs.begin(); + j != (*ast.grammar()).NTs.end(); ++j) { + Symbol::NT *inside_nt = dynamic_cast(j->second); + if (inside_nt) { + if (inside_nt->name->compare(std::string("outside_axioms")) == 0) { + continue; + } + if (!inside_nt->is_partof_outside) { + reported_nts->push_back(inside_nt); + } + } + } + break; + } else { + reported_nts->push_back( + dynamic_cast((*ast.grammar()->NTs.find(*i)).second)); + } + } + + for (std::list::iterator nt_inside = reported_nts->begin(); + nt_inside != reported_nts->end(); ++nt_inside) { + hashtable::iterator outside_ntpair = + ast.grammar()->NTs.find(std::string("outside_") + *((*nt_inside)->name)); + if (outside_ntpair == ast.grammar()->NTs.end()) { + // not all inside NTs will be translated into outside NTs, e.g. + // times = CHAR('*') won't have an outside counterpart. + continue; + } + + print_insideoutside(*nt_inside); + Symbol::NT *nt_outside = + dynamic_cast((*outside_ntpair).second); + print_insideoutside(nt_outside); + } + dec_indent(); + stream << indent() << "}" << endl << endl; +} void Printer::Cpp::print_run_fn(const AST &ast) { + // TODO(sjanssen) can we redesign this function and use Expr::Base + // fn_arg functions?! + stream << indent() << *ast.grammar()->axiom->code()->return_type; stream << " run() {" << endl; inc_indent(); @@ -2561,9 +2922,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_outside()); ast.checkpoint->load_cyk_indices(stream, - ast.grammar()->axiom->tracks()); + ast.grammar()->axiom->tracks(), + ast.grammar()->is_outside()); ast.checkpoint->parse_checkpoint_log(stream, true); } ast.checkpoint->archive_periodically(stream, tabulated); diff --git a/src/cpp.hh b/src/cpp.hh index 9873708be..027769f2a 100644 --- a/src/cpp.hh +++ b/src/cpp.hh @@ -76,27 +76,86 @@ class Cpp : public Base { void print_window_inc_fn(const AST &ast); - void print_openmp_cyk_nt_calls(const AST &ast); - void print_openmp_cyk_all_nt_calls(const AST &ast); - void print_openmp_cyk_helpervars(); + void print_openmp_cyk_nt_calls(const AST &ast, bool for_outsideNTs = false); + void print_openmp_cyk_all_nt_calls(const AST &ast, + bool for_outsideNTs = false); + void print_openmp_cyk_helpervars(bool for_outsideNTs = false); + void print_openmp_cyk_loops_diag(const AST &ast, bool checkpoint, + bool for_outsideNTs = false); + void print_openmp_cyk_loops_middle(const AST &ast, bool checkpoint, + bool for_outsideNTs = false); + void print_openmp_cyk_loops_single(const AST &ast, bool checkpoint, + bool for_outsideNTs = false); void print_openmp_cyk(const AST &ast); std::string multi_index_str(const std::vector
&tables, - const Yield::Multi &mys); + const Yield::Multi &mys, bool is_outside = false); void multi_print_inner_cyk(const std::list &l, const std::list &tord, size_t track, size_t tracks, - size_t track_pos, Type::Base *t, bool checkpoint); + size_t track_pos, Type::Base *t, + bool checkpoint, bool no_mutex_def, + bool for_outsideNTs = false); void multi_partition_nts(const std::list &tord, std::list &all, std::list &inner, std::list &left, std::list &right, size_t track, size_t tracks, size_t track_pos); + void multi_print_cyk_loops_quadratic( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *inner, + std::list *left, + std::string *is, + std::string *js, + std::string *ns, + bool checkpoint, + bool for_outsideNTs = false); + void multi_print_cyk_loops_quadratic_inner( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *left, + std::string *is, + bool checkpoint, + bool for_outsideNTs = false); + void multi_print_cyk_loops_linear( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *inner, + std::list *left, + std::list *right, + std::string *is, + std::string *js, + std::string *ns, + bool checkpoint, + bool for_outsideNTs = false); + void multi_print_cyk_loops_constant( + const std::list &tord, + size_t track, + size_t tracks, + size_t track_pos, + Type::Base *t, + std::list *all, + std::string *is, + bool checkpoint, + bool for_outsideNTs = false); void multi_print_cyk(const std::list &tord, size_t track, size_t tracks, size_t track_pos, Type::Base *t); public: void print_cyk_fn(const AST &ast); + void print_insideoutside_report_fn( + std::vector outside_nt_list, const AST &ast); private: + void print_insideoutside(Symbol::NT *nt); void print_run_fn(const AST &ast); void print_stats_fn(const AST &ast); diff --git a/src/fn_arg.cc b/src/fn_arg.cc index d46cfc542..9178075b6 100644 --- a/src/fn_arg.cc +++ b/src/fn_arg.cc @@ -312,6 +312,28 @@ void Fn_Arg::Const::init_indices(Expr::Base *left, Expr::Base *right, Base::init_indices(left, right, k, track); } +void Fn_Arg::Base::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + Fn_Arg::Base::init_indices(left, right, k, track); +} + +void Fn_Arg::Alt::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + Base::init_indices_outside(left, right, k, track, center_left, + center_right, is_right_of_outside_nt); + alt->init_indices_outside(left, right, k, track, center_left, + center_right, is_right_of_outside_nt); +} + +void Fn_Arg::Const::init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt) { + Base::init_indices_outside(left, right, k, track, center_left, + center_right, is_right_of_outside_nt); +} + void Fn_Arg::Base::init_ret_decl(unsigned int i, const std::string &prefix) { ret_decls_.clear(); var_decls_.clear(); diff --git a/src/fn_arg.hh b/src/fn_arg.hh index a34cebf42..76fb4210e 100644 --- a/src/fn_arg.hh +++ b/src/fn_arg.hh @@ -125,7 +125,10 @@ class Base { virtual void traverse(Visitor &v) = 0; virtual void init_indices(Expr::Base *left, Expr::Base *right, - unsigned int &k, size_t track); + unsigned int &k, size_t track); + virtual void init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt = false); virtual void init_ret_decl(unsigned int i, const std::string &prefix); @@ -180,6 +183,9 @@ class Alt : public Base { void traverse(Visitor &v); void init_indices( Expr::Base *left, Expr::Base *right, unsigned int &k, size_t track); + virtual void init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt = false); void codegen(AST &ast); std::list &statements(); @@ -230,7 +236,10 @@ class Const : public Base { void traverse(Visitor &v); void init_indices(Expr::Base *left, Expr::Base *right, - unsigned int &k, size_t track); + unsigned int &k, size_t track); + virtual void init_indices_outside(Expr::Base *left, Expr::Base *right, + unsigned int &k, size_t track, Expr::Base *center_left, + Expr::Base *center_right, bool is_right_of_outside_nt = false); void codegen(AST &ast); std::list &statements(); diff --git a/src/gapc.cc b/src/gapc.cc index 568f786ce..6dff459a3 100644 --- a/src/gapc.cc +++ b/src/gapc.cc @@ -102,6 +102,11 @@ static void parse_options(int argc, char **argv, Options *rec) { "uses the selected instance and creates a GAP program which creates " "specialized GAP programs that recognize a subset of candidates of the " "original grammar.") + ("outside_grammar", po::value< std::vector >(), + "generate an outside version of the grammar and report outside results " + "for an inside non-terminal. Provide multiple times for lists of " + "non-terminals or type \"ALL\" to report results for all non-" + "terminals.") ("verbose", "show suppressed warnings and messages") ("log-level,l", po::value(), "the log level, valid values are 0 (VERBOSE), 1 (INFO), 2 (NORMAL), 3 " @@ -234,6 +239,9 @@ static void parse_options(int argc, char **argv, Options *rec) { if (vm.count("specialize_grammar")) { rec->specializeGrammar = true; } + if (vm.count("outside_grammar")) + rec->outside_nt_list = vm["outside_grammar"] + .as< std::vector >(); if (vm.count("verbose")) rec->verbose_mode = true; if (vm.count("log-level")) { @@ -361,7 +369,7 @@ class Main { } // simply gets the selected grammar, which is either the - // grammar that occured first in the source code or is 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 @@ -374,6 +382,11 @@ class Main { throw LogError("Seen semantic errors."); } + // inject rules for outside grammar + if (opts.outside_nt_list.size() > 0) { + grammar->inject_outside_nts(opts.outside_nt_list); + } + // configure the window and k-best mode driver.ast.set_window_mode(opts.window_mode); driver.ast.kbest = Bool(opts.kbest); @@ -682,6 +695,9 @@ class Main { hh.footer(driver.ast); hh.end_fwd_decls(); hh.header_footer(driver.ast); + if (grammar->is_outside()) { + hh.print_insideoutside_report_fn(opts.outside_nt_list, driver.ast); + } // Write out the C++ implementation file of the // compile-result. diff --git a/src/grammar.cc b/src/grammar.cc index 0e8f70c64..8cec45732 100644 --- a/src/grammar.cc +++ b/src/grammar.cc @@ -24,6 +24,8 @@ #include #include +#include +#include #include "alt.hh" @@ -101,7 +103,7 @@ void Grammar::move_new_nts() { /* * Annotates each nonterminal that was marked in the source code - * with the "tabultated" keyword internally and adds it to the + * with the "tabulated" keyword internally and adds it to the * table of tabulated non-terminals (Grammar.tabulated). * This method also does some integrity checks on the source data * structures this method iterates through. @@ -340,7 +342,7 @@ void Grammar::multi_propagate_max_filter() { (*i)->update_max_ys(*j); } - // defines the cisitor used a few lines later to set the max size + // defines the visitor used a few lines later to set the max size struct Multi_Max_Visitor : public Visitor { void visit(Alt::Base &b) { b.multi_set_max_size(); @@ -431,7 +433,7 @@ bool Grammar::init_tracks() { /* - * Checks the semantik of the grammar. This includes the following + * Checks the semantic of the grammar. This includes the following * things: * 1) setting the axiom by resolving the axiom name to a pointer * that is of type Symbol::NT* @@ -655,7 +657,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); + } } } } @@ -1002,4 +1008,356 @@ void Grammar::remove(Symbol::NT *x) { tabulated.erase(nt); } +void Grammar::resolve_blocks() { + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + (*i).second->resolve_blocks(); + } +} + + +void Grammar::flag_inside_terminal_ends() { + // defines the visitor used a few lines later + // Traverses grammar and flags non-terminals that NEITHER link to other + // non-terminals NOR apply algebra functions, e.g. times = CHAR('*') + // These NTs cannot translated into outside versions. + struct Find_Inside_Ends : public Visitor { + void visit_end(Alt::Link &alt) { + alt.inside_end = alt.nt == NULL; + } + void visit_end(Alt::Simple &alt) { + for (std::list::iterator i = alt.args.begin(); + i != alt.args.end(); ++i) { + if (dynamic_cast(*i)) { + alt.inside_end = false; + return; + } + } + alt.inside_end = true; + } + void visit_end(Symbol::NT &nt) { + for (std::list::iterator i = nt.alts.begin(); + i != nt.alts.end(); ++i) { + if ((*i)->inside_end == false) { + nt.inside_end = false; + return; + } + } + nt.inside_end = true; + } + }; + + // create a visitor and traverse the + Find_Inside_Ends visitor; + traverse(visitor); +} + +void Grammar::inject_outside_nts() { + std::vector outside_nt_list; + Grammar::inject_outside_nts(outside_nt_list); +} +void Grammar::inject_outside_nts(std::vector outside_nt_list) { + std::string OUTSIDE_NT_PREFIX = "outside_"; + hashtable outside_NTs; + std::set outside_nts = std::set(); + + // 0) check if all user provided NTs for cmd flag are actually in the grammar + std::list *warn_missing_nts = new std::list(); + for (std::vector::iterator i = outside_nt_list.begin(); + i != outside_nt_list.end(); ++i) { + // we don't need to check of non-terminals are in inside grammar, if user + // requests ALL non-terminals + if ((*i).compare(std::string("ALL")) == 0) { + break; + } + if (this->NTs.find(*i) == this->NTs.end()) { + warn_missing_nts->push_back(*i); + } + } + if (warn_missing_nts->size() > 0) { + std::string msg = std::string( + "You requested outside grammar generation and reporting of results for " + "outside versions of non-terminal(s) "); + 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 += ", "; + } + } + msg += ", which do(es) NOT exist in your grammar!"; + throw LogError(msg); + } + + // 0a) semantic check: grammar must be able to parse the empty input in + // order to provide recursion base for outside candidates + Yield::Multi ys = this->axiom->multi_ys(); + for (std::vector::iterator i = ys.begin(); i != ys.end(); ++i) { + if ((*i).low() > 0) { + std::ostringstream msg; + msg << "Minimal yield size of your grammar is "; + (*i).low().put(msg); + msg << ", i.e. it cannot parse the empty input\nstring ''." + << " For outside grammar generation, this means you are lacking a\n" + << "recursion basis which will result in empty results for\n" + << "outside candidates!"; + Log::instance()->warning(msg.str()); + break; + } + } + + // traverse grammar and flag NTs that only use terminals on their rhs + this->flag_inside_terminal_ends(); + + // 1) collect non-terminals used in rhs of productions together with their + // calling lhs non-terminal we thus exclude e.g. non-terminal foo in + // production "foo = BASE;" + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + Symbol::NT *nt = dynamic_cast(i->second); + if ((nt) && (!nt->inside_end)) { + // skip terminals and NTs that only point to terminals + for (std::list::iterator alt = nt->alts.begin(); + alt != nt->alts.end(); ++alt) { + std::list *rhs_nts = new std::list(); + (*alt)->get_nonterminals(rhs_nts); + if (rhs_nts->size() > 0) { + // if rhs uses at least one non-terminal, both (= calling lhs + // non-terminal and all rhs non-terminal(s)) will be added as + // novel outside non-terminals + outside_nts.insert(nt); + for (std::list::const_iterator rhs_nt = rhs_nts->begin(); + rhs_nt != rhs_nts->end(); ++rhs_nt) { + if (!(*rhs_nt)->inside_end) { + outside_nts.insert(*rhs_nt); + } + } + } + } + } + } + + // 2) create a novel outside non-terminal for each collected non-terminal + // in the inside grammar add both (new outside and user provided inside) + // non-terminal **names** as keys to the hash, pointing to the very same + // novel outside non-terminal. + if (outside_nts.size() == 0) { + // the grammar does not have any non-terminals on the rhs of productions. + // Thus, no new NTs have to be injected + return; + } + for (std::set::iterator nt = outside_nts.begin(); + nt != outside_nts.end(); ++nt) { + // use inside NT as template ... + Symbol::NT *inside_nt = dynamic_cast( + this->NTs.find(*(*nt)->name)->second); + + // skip inside NTs that only point to terminals like + // times = CHAR('*') + if (inside_nt->inside_end) { + // inside terminal is NOT transformed into outside NT + continue; + } + + // and clone for outside version + Symbol::NT *outside_nt = inside_nt->clone(inside_nt->track_pos()); + + /* create copies of the current inside table dimensions of the NT + * when reporting inside/outside results, we can thus skip a few + * cells of NTs that are now linear or const but will become + * quadratic due to outside context, e.g. struct of nodangle */ + outside_nt->table_dims_inside = inside_nt->tables(); + inside_nt->table_dims_inside = inside_nt->tables(); + + // remove all existing alternative production rules + outside_nt->alts.clear(); + // and correct NT name, to now point to outside version + outside_nt->name = new std::string(OUTSIDE_NT_PREFIX + (*(*nt)->name)); + + // flag this new non-terminal as being part of the outside rules + outside_nt->is_partof_outside = true; + + outside_NTs[OUTSIDE_NT_PREFIX + (*(*nt)->name)] = outside_nt; + outside_NTs[(*(*nt)->name)] = outside_nt; + } + + // flag inside axiom + this->axiom->is_inside_axiom = true; + + // 3) create copy of inside alternative, replace called non-terminal with + // calling outside version and append to called outside version + std::set *axiom_candidates = new std::set(); + for (hashtable::iterator i = NTs.begin(); + i != NTs.end(); ++i) { + Symbol::NT *nt = dynamic_cast(i->second); + // skip terminals and NTs that end in terminals + if ((nt) && (!nt->inside_end)) { + // don't directly operate on given inside NTs, + // but first resolve Alt::Block use for outside rules + Symbol::NT *nt_resolved = nt->clone(nt->track_pos()); + nt_resolved->resolve_blocks(); + for (std::list::iterator alt = nt_resolved->alts.begin(); + alt != nt_resolved->alts.end(); ++alt) { + std::list *rhs_nts = new std::list(); + (*alt)->get_nonterminals(rhs_nts); + if (rhs_nts->size() > 0) { + hashtable skip_occurences; + for (std::list::iterator it_nt = rhs_nts->begin(); + it_nt != rhs_nts->end(); ++it_nt) { + skip_occurences[*((*it_nt)->name)] = 0; + } + // unsigned int skip_occurences = 0; + for (std::list::iterator it_nt = rhs_nts->begin(); + it_nt != rhs_nts->end(); ++it_nt) { + // skip inside NTs that only point to terminals like + // times = CHAR('*') + if ((*it_nt)->inside_end) { + continue; + } + + // create a copy (=clone) of the inside alternative + Alt::Base *outside_alt = (*alt)->clone(); + // replace one of the inside non-terminals with the outside + // version of the calling non-terminal + outside_alt->replace_nonterminal( + *it_nt, dynamic_cast( + outside_NTs.find(i->first)->second), skip_occurences); + // flag outside_alt as being part of an automatically generated + // outside production rule + outside_alt->set_partof_outside(true); + + outside_alt->m_ys_inside = outside_alt->multi_ys(); + // append copied+replaced alternative to the list of alternatives + // for the outside version of the called non-terminal + (dynamic_cast( + outside_NTs.find(*((*it_nt)->name))->second))->alts.push_back( + outside_alt); + skip_occurences[*((*it_nt)->name)]++; + } + } else { +// // e.g. struct = nil(LOC) has no non-terminal on the rhs, but + // should become an alternative for outside version of struct +// Alt::Base *outside_alt = (*alt)->clone(); +// // flag outside_alt as being part of an automatically generated + // outside production rule +// outside_alt->set_partof_outside(true); +// (dynamic_cast(outside_NTs.find(*(nt->name))->second)) + // ->alts.push_back(outside_alt); + + // if production rule does not have any non-terminals on the right + // hand side, the calling non-terminal is a candidate for being + // called from the axiom for outside + // e.g. hairpin = hl(BASE, REGION, BASE) --> outside_hairin + // get's added + axiom_candidates->insert(dynamic_cast( + outside_NTs.find(*(nt->name))->second)); + } + } + } + } + Alt::Link *link = new Alt::Link(this->axiom_name, this->axiom_loc); + link->nt = dynamic_cast(this->axiom); + Filter *f = new Filter(new std::string("complete_track"), Loc()); + f->type = Filter::WITH; + std::list *comptracks = new std::list(); + for (unsigned int track = 0; track < this->axiom->tracks(); ++track) { + comptracks->push_back(f); + } + link->set_tracks(this->axiom->tracks(), this->axiom->track_pos()); + link->init_multi_ys(); + link->is_outside_inside_transition = true; + if (link->nt->tracks() == 1) { + link->filters.push_back(f); + } else { + link->add_multitrack_filter(*comptracks, f->type, Loc()); + } + link->top_level = Bool(true); + dynamic_cast(outside_NTs.find( + *this->axiom_name)->second)->alts.push_back(link); + + // 4) add novel outside NTs to grammar + for (std::pair nt : outside_NTs) { + // only for NTs that are not already part of the grammar + if (this->NTs.find(nt.first) == this->NTs.end()) { + Symbol::NT *nt_nt = dynamic_cast(nt.second); + /* calling NT might never occur on rhs of productions, e.g. "start" in: + * grammar gra_nodangle uses sig_foldrna(axiom = start) { + * start = incl(struct) # h; + * struct = sadd(BASE, struct) | nil(LOC) # h; } + * the outside version of such non terminals shall point to the inside + * axiom + */ + if (nt_nt->alts.size() == 0) { + Alt::Link *link = new Alt::Link(this->axiom_name, this->axiom_loc); + link->nt = dynamic_cast(this->axiom); + nt_nt->alts.push_back(link); + } + this->NTs.insert(nt); + this->nt_list.push_back(nt_nt); + } + } + + // 5) inside production rules that have NO non-terminals on their right hand + // sides must be those that parse the final sub-words of the input. + // Therefore, they must be the smallest start-points for outside + // construction, i.e. the axiom should point to them. These non-terminals + // have been collected in step 3. + if (axiom_candidates->size() == 1) { + // if there is only one inside non-terminal to be accessed from the axiom + // we can directly define its outside version as the axiom + this->axiom_name = (*axiom_candidates->begin())->name; + this->init_axiom(); + } else { + // otherwise, we need to add another left hand side non-terminal + // which points to multiple non-terminals WITHOUT making a choice + std::string *nt_axiom_name = new std::string("outside_axioms"); + Symbol::NT *nt_axiom = new Symbol::NT(nt_axiom_name, Loc()); + // carry over tracks from original inside axiom + nt_axiom->set_tracks(this->axiom->tracks(), this->axiom->track_pos()); + nt_axiom->setup_multi_ys(); + + for (std::set::iterator i = axiom_candidates->begin(); + i != axiom_candidates->end(); ++i) { + Alt::Link *link = new Alt::Link((*i)->name, Loc()); + link->nt = dynamic_cast( + outside_NTs.find(*(*i)->name)->second); + link->set_tracks((*i)->tracks(), (*i)->track_pos()); + link->init_multi_ys(); + nt_axiom->alts.push_back(link); + } + // add new lhs non-terminal to grammar + this->NTs.insert(std::make_pair( + *nt_axiom_name, dynamic_cast(nt_axiom))); + this->nt_list.push_back(nt_axiom); + + this->axiom_name = nt_axiom_name; + this->init_axiom(); + } + /* 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(); + + // mark the modified grammar as an outside one + this->outside = true; + + Log::instance()->verboseMessage( + "Grammar has been modified into an outside version."); +} diff --git a/src/grammar.hh b/src/grammar.hh index 1ddb4aa12..4e946a7a0 100644 --- a/src/grammar.hh +++ b/src/grammar.hh @@ -64,7 +64,14 @@ class Grammar { void renumber_nts(); void move_new_nts(); + // flag the grammar as being an outside version + // default is false, will be set to true by function inject_outside_nts + bool outside = false; + public: + bool is_outside() { + return this->outside; + } // The name of the grammar as defined in the grammar name of // the gap-source-code file. std::string *name; @@ -206,7 +213,21 @@ class Grammar { void multi_propagate_max_filter(); + // traverse grammar and flag those NTs (and production rules) + // that only use terminal parsers, because these shall not be + // translated into outside NTs, e.g. times = CHAR('*') + void flag_inside_terminal_ends(); + // inject additional non-terminals to grammar, to automatically create + // an outside version for user provided grammar + void inject_outside_nts(std::vector outside_nt_list); + // same as above, without checking user provided NT list + void inject_outside_nts(); unsigned int to_dot(unsigned int *nodeID, std::ostream &out, int plot_level); + + // blocks allow alternatives for sub-productions. This function shell free + // a grammar of Alt::Block by explicitly adding alternatives as top level + // alternative production rules for non-terminals. + void resolve_blocks(); }; diff --git a/src/list_warn.cc b/src/list_warn.cc index 2c0a786ee..24f7d7d54 100644 --- a/src/list_warn.cc +++ b/src/list_warn.cc @@ -62,7 +62,7 @@ void List_Warn::visit_begin(Alt::Block &a) { return; if (a.alts.size() > 1 && a.list_size() == Yield::UP) { Log::instance()->warning(a.location, "Block has an answer list >= n, " - "consider moving this block into an extra NT and" + "consider moving this block into an extra NT and " "applying choice function to it."); } } diff --git a/src/options.hh b/src/options.hh index 6c9c9ad7a..b7f616ef2 100644 --- a/src/options.hh +++ b/src/options.hh @@ -116,6 +116,11 @@ struct Options { // ignore most of the other options (except the instance selector // and output file name). bool specializeGrammar; + // 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; // flag that is used to turn on verbose mode, i.g. all suppressed // warnings and messages will be shown bool verbose_mode; diff --git a/src/symbol.cc b/src/symbol.cc index ca9f52898..2a947f05c 100644 --- a/src/symbol.cc +++ b/src/symbol.cc @@ -46,6 +46,7 @@ #include "type/backtrace.hh" #include "alt.hh" +#include "fn_arg.hh" Symbol::Base::Base(std::string *n, Type t, const Loc &l) @@ -56,7 +57,7 @@ Symbol::Base::Base(std::string *n, Type t, const Loc &l) terminal_type(false), rt_computed(false), name(n), orig_name(n), location(l), tracks_(0), - track_pos_(0) { + track_pos_(0), is_partof_outside(false) { assert(name); } @@ -750,8 +751,21 @@ void Symbol::NT::init_indices(Expr::Vacc *left, Expr::Vacc *right, left_indices[track] = left; right_indices[track] = right; - for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) - (*i)->init_indices(left, right, k, track); + for (std::list::iterator i = alts.begin(); i != alts.end(); ++i) { + if (this->is_partof_outside) { + if ((*i)->get_is_partof_outside() == false) { + // special treatment for a link to the original inside axiom, ensure + // that it has to consume the full input sequence(s) + (*i)->init_indices_outside( + left->plus(right), right->minus(left), k, track, NULL, NULL, false); + dynamic_cast(*i)->init_outside_guards(); + } else { + (*i)->init_indices_outside(left, right, k, track, NULL, NULL, false); + } + } else { + (*i)->init_indices(left, right, k, track); + } + } } Statement::Base *Symbol::NT::build_return_empty(const Code::Mode &mode) { @@ -1193,6 +1207,9 @@ struct SetADPDisabled : public Visitor { }; void Symbol::NT::codegen(AST &ast) { + // moving this uninizialized list to the front of the method to avoid issues with gdb within eclipse: https://www.eclipse.org/forums/index.php/t/1109346/ + 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()); @@ -1223,8 +1240,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()); @@ -1635,4 +1650,138 @@ bool Symbol::Terminal::isPredefinedTerminalParser() { return this->predefinedTerminalParser; } +// a user provided grammar might contain production rules that use blocks +// e.g. NT = sadd(BASE, {hairpin | iloop}) +// this basically is a short hand notation for multiple alternatives, e.g. +// NT = sadd(BASE, hairpin) | sadd(BASE, iloop) +// For outside grammar generation, we first want to make short-hand notations +// explicit by applying this function to the selected grammar. +// This only applies for NTs, not for Base or Terminal +void Symbol::Base::resolve_blocks() { +} +void Symbol::Terminal::resolve_blocks() { +} +void Symbol::NT::resolve_blocks() { + for (std::list::iterator alt = this->alts.begin(); + alt != this->alts.end(); ++alt) { + // check if alternative contains any Alt::Block + Alt::Block *block = dynamic_cast((*alt)->find_block()); + while (block) { + // locate parent of found Alt::Block + Alt::Base *parent = (*alt)->find_block_parent(*block); + if (block->alts.size() == 1) { + // if a Alt::Block holds only one alternative, + // we can simply remove Alt::Block altogether + if (parent == NULL) { + // parent is the non-terminal + Alt::Base *child = block->alts.front(); + child->top_level = Bool(true); + child->filters.insert(child->filters.end(), block->filters.begin(), + block->filters.end()); + child->multi_filter.insert(child->multi_filter.end(), + block->multi_filter.begin(), + block->multi_filter.end()); + // keep original ordering, i.e. delete block and push + // single = last alt to the end + this->alts.push_back(child); + this->alts.erase(alt); + // reset iterator to first element + alt = this->alts.begin(); + } else { + Alt::Simple *p_simple = dynamic_cast(parent); + if (p_simple) { + // if parent is of type Alt::Simple + for (std::list::iterator j = + p_simple->args.begin(); + j != p_simple->args.end(); ++j) { + Fn_Arg::Alt *p_simple_fnarg = dynamic_cast(*j); + if (p_simple_fnarg && (p_simple_fnarg->alt == block)) { + Alt::Base *child = block->alts.front(); + child->filters.insert(child->filters.end(), + block->filters.begin(), + block->filters.end()); + child->multi_filter.insert(child->multi_filter.end(), + block->multi_filter.begin(), + block->multi_filter.end()); + p_simple_fnarg->alt = child; + break; + } + } + } + + // a Link is a leaf and thus cannot contain a block + // Alt::Link *p_link = dynamic_cast(parent); + // parent block should have been removed first! + // Alt::Block *p_block = dynamic_cast(parent); + + // Alternative is not allowed in Multi-Track link. + // Alt::Multi *p_multi = dynamic_cast(parent); + } + } else { + // the Alt::Block holds multiple alternatives. + if (parent == NULL) { + Alt::Base *child = block->alts.front()->clone(); + child->top_level = Bool(true); + child->filters.insert(child->filters.end(), + block->filters.begin(), + block->filters.end()); + child->multi_filter.insert(child->multi_filter.end(), + block->multi_filter.begin(), + block->multi_filter.end()); + this->alts.push_back(child); + block->alts.pop_front(); + } else { + Alt::Simple *p_simple = dynamic_cast(parent); + if (p_simple) { + // if parent is of type Alt::Simple + // 1) clone the full existing alternative + Alt::Base *newalt = (*alt)->clone(); + + // 2) remove first block alternative from original object + Alt::Base *first_block_alt = block->alts.front(); + first_block_alt->filters.insert(first_block_alt->filters.end(), + block->filters.begin(), + block->filters.end()); + first_block_alt->multi_filter.insert( + first_block_alt->multi_filter.end(), + block->multi_filter.begin(), + block->multi_filter.end()); + block->alts.pop_front(); + + // 3) remove Alt::Block and connect first block + // alternative to cloned object + Alt::Base *cloned_block = newalt->find_block(); + // a clone of the alt rule containing block should have this + // block as well! + assert(cloned_block); + Alt::Simple *cloned_p_simple = dynamic_cast( + newalt->find_block_parent(*cloned_block)); + // must exist and be Alt::Simple for above reasons + assert(cloned_p_simple); + for (std::list::iterator j = + cloned_p_simple->args.begin(); + j != cloned_p_simple->args.end(); ++j) { + Fn_Arg::Alt *cloned_p_simple_fnarg = + dynamic_cast(*j); + if (cloned_p_simple_fnarg && + (cloned_p_simple_fnarg->alt == cloned_block)) { + cloned_p_simple_fnarg->alt = first_block_alt; + break; + } + } + + this->alts.insert(alt, newalt); + } + + // as with the single case above, Link, Block, + // Multi cannot be parents + } + } + + // for next iteration: check if production rules might still + // contain other blocks + block = dynamic_cast((*alt)->find_block()); + } + } +} diff --git a/src/symbol.hh b/src/symbol.hh index da0cd65cf..717648e5b 100644 --- a/src/symbol.hh +++ b/src/symbol.hh @@ -249,9 +249,16 @@ class Base { const Yield::Multi &right, Symbol::NT *nt); virtual bool multi_detect_loop(); + // flag to indicate if alternative is for inside (the default) or outside + // production rules. + bool is_partof_outside = false; + // prints grammar rules as GraphViz commands virtual unsigned int to_dot(unsigned int *nodeID, std::ostream &out, - bool is_rhs, Symbol::NT *axiom, - int plot_grammar); + bool is_rhs, Symbol::NT *axiom, + int plot_grammar); + // only for NTs: check if alternatives contain Alt::Block short-cuts + // if so, remove them by making alternatives explicit + virtual void resolve_blocks(); }; @@ -310,7 +317,8 @@ class Terminal : public Base { void setPredefinedTerminalParser(bool isPredefined); bool isPredefinedTerminalParser(); unsigned int to_dot(unsigned int *nodeID, std::ostream &out, - bool is_rhs, Symbol::NT *axiom, int plot_grammar); + bool is_rhs, Symbol::NT *axiom, int plot_grammar); + void resolve_blocks(); }; @@ -338,7 +346,14 @@ class NT : public Base { // rules. There is one pointer stored for each alternative. std::list alts; void set_alts(const std::list &a); + bool inside_end = false; + // 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; @@ -382,6 +397,9 @@ class NT : public Base { private: std::vector
table_dims; + public: + std::vector
table_dims_inside; + public: const std::vector
&tables() const { return table_dims; @@ -515,7 +533,14 @@ class NT : public Base { return ntargs_; } unsigned int to_dot(unsigned int *nodeID, std::ostream &out, - bool is_rhs, Symbol::NT *axiom, int plot_grammar); + bool is_rhs, Symbol::NT *axiom, int plot_grammar); + void resolve_blocks(); + + // in outside grammar generation context: flags the one non-terminal + // that was the axiom for the inside part of the grammar, i.e. user + // defined axiom. Axiom will be re-set to an outside version during + // Grammar::inject_outside_nts() + bool is_inside_axiom = false; }; diff --git a/src/table.cc b/src/table.cc index bb92d9722..49b1a5d30 100644 --- a/src/table.cc +++ b/src/table.cc @@ -70,6 +70,9 @@ bool Table::delete_right_index() const { return (dim == CONSTANT || (dim == LINEAR && sticky_ == RIGHT)) && right_rest_.high() == 0; } +bool Table::is_const_table() const { + return delete_left_index() && delete_right_index(); +} void Table::set_sticky(Sticky s) { if (sticky_ != NO_INDEX && sticky_ != s) { diff --git a/src/table.hh b/src/table.hh index e2a8f174e..80de62982 100644 --- a/src/table.hh +++ b/src/table.hh @@ -95,6 +95,7 @@ class Table { } bool delete_left_index() const; bool delete_right_index() const; + bool is_const_table() const; bool is_cyk_const() const { return dim == CONSTANT && 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/ext_hmm.hh b/testdata/gapc_filter/ext_hmm.hh new file mode 100644 index 000000000..f9afeb5a1 --- /dev/null +++ b/testdata/gapc_filter/ext_hmm.hh @@ -0,0 +1,102 @@ +#ifndef EXT_HMM_HH +#define EXT_HMM_HH + +template +inline +T negexpsum(T t) { + return t; +} + +template +inline +typename std::iterator_traits::value_type negexpsum(Itr begin, Itr end) { + typename std::iterator_traits::value_type n; + if (begin == end) { + empty(n); + return n; + } + assert(!isEmpty(*begin)); + n = exp(-1.0 * *begin); + ++begin; + for (; begin != end; ++begin) { + assert(!isEmpty(*begin)); + n += exp(-1.0 * *begin); + } + assert((n > 0 && "Your algebra produces (partial) candidates with negative " + "score, which cannot be logarithmized. Avoid h=negexpsum or " + "ensure all positive values!")); + return -1.0 * log(n); +} + +template +inline +typename std::iterator_traits::value_type +negexpsum(std::pair &p) { + return negexpsum(p.first, p.second); +} + +const static double THRESHOLD = 0.000000001; +inline List_Ref > filterLowProbLabels(List_Ref > candidates_orig) { + //return candidates_orig; + // do nothing if there is just one candidate at all + if (candidates_orig.ref().size() <= 1) { + return candidates_orig; + } + + List_Ref > candidates; + // obtain most probable candidate up to here + double bestValue = (*candidates_orig.ref().begin()).second; + for (List_Ref >::iterator i = candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { + if (bestValue > (*i).second) { + bestValue = (*i).second; + } + } + + // only keep candidates that are not smaller than the best candidate times THRESHOLD + // a value that should be changable by the user instead of hard coding it here + for (List_Ref >::iterator i = candidates_orig.ref().begin(); i != candidates_orig.ref().end(); ++i) { + if ((*i).second <= (bestValue + log(1/THRESHOLD))) { + candidates.ref().push_back(*i); + } + } + return candidates; +} + +//template +//struct filterLowProbLabels2 { +// double bestValue; +// filterLowProbLabels2() : bestValue(0.0) { +// } +// void update(const T &src) { +// if (src.second > bestValue) { +// bestValue = src.second; +// } +// } +// bool ok(const T &x) const { +// return x.second <= lowProbabilityFilter(); +//// //sum = sum + x.second; +//// //return true; +//// double thresh = pow(22.56 * lowProbabilityFilter(), (x.first.size()-1)); +//// //double thresh = 0.1 * sum; +////// if (sum > 0) { +//// std::cerr << sum << ", " << x.second << "\t" << x.first << "\n"; +////// } +////// if (x.second != 1.0) { +////// std::cerr << (thresh > x.second) << "\t" << thresh << "\t" << x.second << "\n"; +////// } +//// //std::cerr << (pow(0.01, x.first.size())) << " " << x.second << "\n"; // "thresh: " << x.second << ", sum: " << sum << "\n"; +//// //return (sum > 0.01) || (count <= 1); +//// return true; //x.second > 0.3; +//// return (x.second > thresh) || (x.second == 1.0); +//// //return x.second > 0.5; +// } +//}; +// +//template +//inline double getPfuncValue(std::pair x) { +// return sum_elems(x.second.pf); +//} + + + +#endif 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/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/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..85de279c9 --- /dev/null +++ b/testdata/grammar_outside/mini_complexIL.gap @@ -0,0 +1,60 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer comp(Subsequence, Subsequence, Subsequence, Subsequence, answer, Subsequence, answer); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int comp(Subsequence a, Subsequence lr, Subsequence lr2, Subsequence lr3, int x, Subsequence b, int y) { + return x+y; + } +} + +//algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { +// string nil(Subsequence loc) { +// string r; +// return r; +// } +// +// choice [string] h([string] i) { +// return i; +// } +// +// string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { +// string res; +// append(res, '('); +// append(res, '.', size(lregion)); +// append(res, e); +// append(res, '.', size(rregion)); +// append(res, ')'); +// return res; +// } +//} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION, comp(REGION, BASE, BASE, REGION, struct, BASE, struct), REGION, BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/mini_largeIL.gap b/testdata/grammar_outside/mini_largeIL.gap new file mode 100644 index 000000000..fa0be0279 --- /dev/null +++ b/testdata/grammar_outside/mini_largeIL.gap @@ -0,0 +1,56 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, Subsequence, answer, Subsequence, Subsequence, Subsequence); // an internal loop with a closing base-pair +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence a, Subsequence lr, int x, Subsequence rr, Subsequence b, Subsequence rb) { + return x + il_energy(lr, rr); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string nil(Subsequence loc) { + string r; + return r; + } + + choice [string] h([string] i) { + return i; + } + + string il(Subsequence lb,Subsequence a, Subsequence lregion,string e,Subsequence rregion,Subsequence b,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION with maxsize(30), REGION, struct, REGION, REGION with maxsize(30), BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/mini_twoLevelIL.gap b/testdata/grammar_outside/mini_twoLevelIL.gap new file mode 100644 index 000000000..521f668d7 --- /dev/null +++ b/testdata/grammar_outside/mini_twoLevelIL.gap @@ -0,0 +1,39 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer nil(Subsequence); //empty structure + choice [answer] h([answer]); + answer il(Subsequence, Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer comp(Subsequence, Subsequence, Subsequence, answer, Subsequence, answer, Subsequence); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } + int il(Subsequence lb, Subsequence lr, Subsequence r, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int comp(Subsequence a, Subsequence lr, Subsequence lr2, int x, Subsequence b, int y, Subsequence lr3) { + return x+y; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + iloop + # h; + + iloop = il(BASE, REGION, BASE, comp(BASE, BASE, REGION, struct, BASE, struct, REGION), REGION, BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle.gap b/testdata/grammar_outside/nodangle.gap new file mode 100644 index 000000000..c1fa7c6a0 --- /dev/null +++ b/testdata/grammar_outside/nodangle.gap @@ -0,0 +1,236 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(dangle, struct) | + nil(LOC) # h; + + dangle = drem(LOC, strong, LOC) # h; + + strong = weak # h; + + weak = stack | + hairpin | + leftB | + rightB | + iloop | + multiloop # h; + + stack = sr(BASE, weak, BASE) with basepairing # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = bl(BASE, REGION with maxsize(30), strong, BASE) with basepairing # h; + rightB = br(BASE, strong, REGION with maxsize(30), BASE) with basepairing # h; + iloop = il(BASE, REGION with maxsize(30), strong, REGION with maxsize(30), BASE) with basepairing # h; + multiloop = ml(BASE, ml_comps, BASE) with basepairing # h; + + ml_comps = sadd(BASE, ml_comps) | + cadd(incl(dangle), ml_comps1) # h; + + ml_comps1 = sadd(BASE, ml_comps1) | + cadd(incl(dangle), ml_comps1) | + incl(dangle) | + addss(incl(dangle), REGION) # h; +} + +instance mfe = gra_nodangle(alg_mfe); +instance pfunc = gra_nodangle(alg_pfunc); +instance count = gra_nodangle(alg_count); +instance enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_caddinclissue.gap b/testdata/grammar_outside/nodangle_caddinclissue.gap new file mode 100644 index 000000000..2504e63c1 --- /dev/null +++ b/testdata/grammar_outside/nodangle_caddinclissue.gap @@ -0,0 +1,169 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE with unpaired, struct) | + cadd(incl(dangle), struct) | + nil(LOC) # h; + + dangle = drem(LOC, hairpin, LOC) # h; + + hairpin = hl(BASE, REGION with minsize(3) with unpaired, BASE) with basepair # h; +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_emptyanswerissue.gap b/testdata/grammar_outside/nodangle_emptyanswerissue.gap new file mode 100644 index 000000000..27064ec58 --- /dev/null +++ b/testdata/grammar_outside/nodangle_emptyanswerissue.gap @@ -0,0 +1,217 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(weak, struct) | + nil(LOC) # h; + + + weak = hl(BASE, REGION with minsize(3), BASE) with basepairing | + bl(BASE, REGION with maxsize(30), weak, BASE) with basepairing | + il(BASE, REGION with maxsize(30), weak, REGION with maxsize(30), BASE) with basepairing + # h; + +} + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_filterempty.gap b/testdata/grammar_outside/nodangle_filterempty.gap new file mode 100644 index 000000000..4b961e225 --- /dev/null +++ b/testdata/grammar_outside/nodangle_filterempty.gap @@ -0,0 +1,217 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(weak, struct) | + nil(LOC) # h; + + weak = hairpin | + leftB + # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = sr(BASE, bl(BASE, REGION with maxsize(30), weak, BASE) with basepairing, BASE with basepairing) # h; +} + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_issue.gap b/testdata/grammar_outside/nodangle_issue.gap new file mode 100644 index 000000000..0a6f1542e --- /dev/null +++ b/testdata/grammar_outside/nodangle_issue.gap @@ -0,0 +1,167 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + cadd(hairpin, struct) + # h; + + hairpin = hl(BASE, REGION with minsize(3) with maxsize(30), BASE) with basepairing # h; +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_issue2.gap b/testdata/grammar_outside/nodangle_issue2.gap new file mode 100644 index 000000000..b2b3ac86a --- /dev/null +++ b/testdata/grammar_outside/nodangle_issue2.gap @@ -0,0 +1,170 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + incl(hairpin) | + sadd(BASE, struct) | + cadd(struct, sadd(BASE, struct)) + # h; + //dangle = hairpin # h; + + hairpin = hl(BASE, REGION with minsize(3) with maxsize(30), BASE) with basepairing # h; +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_mlIssue.gap b/testdata/grammar_outside/nodangle_mlIssue.gap new file mode 100644 index 000000000..271d7e27e --- /dev/null +++ b/testdata/grammar_outside/nodangle_mlIssue.gap @@ -0,0 +1,169 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = nil(LOC) | + cadd(multiloop, struct) + # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + multiloop = ml(BASE, hairpin, BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_noNTrhs_issue.gap b/testdata/grammar_outside/nodangle_noNTrhs_issue.gap new file mode 100644 index 000000000..b9676bf3c --- /dev/null +++ b/testdata/grammar_outside/nodangle_noNTrhs_issue.gap @@ -0,0 +1,167 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = start) { + start = incl(struct) # h; + struct = sadd(BASE with unpaired, struct) | + nil(LOC) # h; + + +} + +instance mfe = gra_nodangle(alg_mfe); diff --git a/testdata/grammar_outside/nodangle_tooManyLoops.gap b/testdata/grammar_outside/nodangle_tooManyLoops.gap new file mode 100644 index 000000000..da00de210 --- /dev/null +++ b/testdata/grammar_outside/nodangle_tooManyLoops.gap @@ -0,0 +1,212 @@ +import rna + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(hairpin, struct) | + nil(LOC) # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + +} + +instance mfe = gra_nodangle(alg_mfe); +instance pfunc = gra_nodangle(alg_pfunc); +instance count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nodangle_withoverlay.gap b/testdata/grammar_outside/nodangle_withoverlay.gap new file mode 100644 index 000000000..c38ad4539 --- /dev/null +++ b/testdata/grammar_outside/nodangle_withoverlay.gap @@ -0,0 +1,237 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, struct) | + cadd(dangle , struct) | + nil(LOC) # h; + + dangle = drem(LOC, strong, LOC) # h; + + strong = weak # h; + + weak = stack | + hairpin | + leftB | + rightB | + iloop | + multiloop # h; + + stack = sr(BASE, weak, BASE) with basepairing # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = bl(BASE, REGION with maxsize(30), strong, BASE) with basepairing # h; + rightB = br(BASE, strong, REGION with maxsize(30), BASE) with basepairing # h; + iloop = il(BASE, REGION with maxsize(30), strong, REGION with maxsize(30), BASE) with basepairing with_overlay iloopSumMax(30) # h; + multiloop = ml(BASE, ml_comps, BASE) with basepairing # h; + + ml_comps = sadd(BASE, ml_comps) | + cadd(incl(dangle), ml_comps1) # h; + + ml_comps1 = sadd(BASE, ml_comps1) | + cadd(incl(dangle), ml_comps1) | + incl(dangle) | + addss(incl(dangle), REGION) # h; +} + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/nonzero_constsize.gap b/testdata/grammar_outside/nonzero_constsize.gap new file mode 100644 index 000000000..e02eb62db --- /dev/null +++ b/testdata/grammar_outside/nonzero_constsize.gap @@ -0,0 +1,51 @@ +signature sig_cm(alphabet, answer) { + answer silent_transition(float, answer; int); + answer left_transition(float, alphabet, answer; int); + answer right_transition(float, answer, alphabet; int); + answer pair_transition(float, alphabet, answer, alphabet; int); + answer bifurcation_transition(float, float, answer, answer; int); + answer nil(float, void; int); + choice [answer] h([answer]); +} + + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +grammar gra_cm uses sig_cm(axiom = state_B_3) { + state_B_3 = bifurcation_transition(CONST_FLOAT(0.000000), CONST_FLOAT(0.000000), state_S_4, state_S_12; 3) + # h; + + state_S_4 = silent_transition(CONST_FLOAT(-9.761000), state_ML_6; 4) + | silent_transition(CONST_FLOAT(-9.808000), state_D_8; 4) + # h; + + state_ML_6 = left_transition(CONST_FLOAT(-1.000000), CHAR, state_E_11; 6) + # h; + + state_D_8 = silent_transition(CONST_FLOAT(-1.000000), state_E_11; 8) + # h; + + state_E_11 = nil(CONST_FLOAT(0.000000), EMPTY; 11) + # h; + + + state_S_12 = silent_transition(CONST_FLOAT(-10.445000), state_ML_15; 12) + | silent_transition(CONST_FLOAT(-11.549000), state_D_17; 12) + # h; + + state_ML_15 = left_transition(CONST_FLOAT(-1.000000), CHAR, state_E_20; 15) + # h; + + state_D_17 = silent_transition(CONST_FLOAT(-1.000000), state_E_20; 17) + # h; + + state_E_20 = nil(CONST_FLOAT(0.000000), EMPTY; 20) + # h; + +} + +instance count = gra_cm(alg_count); +instance enum = gra_cm(alg_enum); + \ No newline at end of file diff --git a/testdata/grammar_outside/pknotsRG.gap b/testdata/grammar_outside/pknotsRG.gap new file mode 120000 index 000000000..f0c8dfb7c --- /dev/null +++ b/testdata/grammar_outside/pknotsRG.gap @@ -0,0 +1 @@ +../grammar/pknotsRG.gap \ No newline at end of file diff --git a/testdata/grammar_outside/rnashapes2wip.gap b/testdata/grammar_outside/rnashapes2wip.gap new file mode 120000 index 000000000..70c8653ce --- /dev/null +++ b/testdata/grammar_outside/rnashapes2wip.gap @@ -0,0 +1 @@ +../grammar/rnashapes2wip.gap \ No newline at end of file diff --git a/testdata/grammar_outside/rnashapesmfe.gap b/testdata/grammar_outside/rnashapesmfe.gap new file mode 120000 index 000000000..e9c947e7e --- /dev/null +++ b/testdata/grammar_outside/rnashapesmfe.gap @@ -0,0 +1 @@ +../grammar/rnashapesmfe.gap \ No newline at end of file diff --git a/testdata/grammar_outside/rnashapespf.gap b/testdata/grammar_outside/rnashapespf.gap new file mode 120000 index 000000000..98b81292a --- /dev/null +++ b/testdata/grammar_outside/rnashapespf.gap @@ -0,0 +1 @@ +../grammar/rnashapespf.gap \ No newline at end of file diff --git a/testdata/grammar_outside/single_block.gap b/testdata/grammar_outside/single_block.gap new file mode 120000 index 000000000..3df269ae9 --- /dev/null +++ b/testdata/grammar_outside/single_block.gap @@ -0,0 +1 @@ +../grammar/single_block.gap \ No newline at end of file diff --git a/testdata/grammar_outside/stefan3.gap b/testdata/grammar_outside/stefan3.gap new file mode 120000 index 000000000..049192085 --- /dev/null +++ b/testdata/grammar_outside/stefan3.gap @@ -0,0 +1 @@ +../grammar/stefan3.gap \ No newline at end of file diff --git a/testdata/grammar_outside/stefan4.gap b/testdata/grammar_outside/stefan4.gap new file mode 120000 index 000000000..2944f1b55 --- /dev/null +++ b/testdata/grammar_outside/stefan4.gap @@ -0,0 +1 @@ +../grammar/stefan4.gap \ No newline at end of file diff --git a/testdata/grammar_outside/tdm2hp.gap b/testdata/grammar_outside/tdm2hp.gap new file mode 120000 index 000000000..90dd67c24 --- /dev/null +++ b/testdata/grammar_outside/tdm2hp.gap @@ -0,0 +1 @@ +../grammar/tdm2hp.gap \ No newline at end of file diff --git a/testdata/grammar_outside/tdm2hporig.gap b/testdata/grammar_outside/tdm2hporig.gap new file mode 120000 index 000000000..a61558bde --- /dev/null +++ b/testdata/grammar_outside/tdm2hporig.gap @@ -0,0 +1 @@ +../grammar/tdm2hporig.gap \ No newline at end of file diff --git a/testdata/grammar_outside/tmhmm.gap b/testdata/grammar_outside/tmhmm.gap new file mode 100644 index 000000000..655cfdb64 --- /dev/null +++ b/testdata/grammar_outside/tmhmm.gap @@ -0,0 +1,951 @@ +import "ext_hmm.hh" +type Rope = extern + +signature sig_tmhmm(alphabet, answer) { + answer silent_transition(float, answer); + answer transition(char, float, answer, answer); + answer nil(void); + answer emission(float, alphabet); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_viterbi implements sig_tmhmm(alphabet=char, answer=float) { + float silent_transition(float prob, float t) { + return prob * t; + } + float transition(char label, float prob, float e, float t) { + return prob * e * t; + } + float nil(void) { + return 1.0; + } + float emission(float prob, char emission) { + return prob; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_fwd extends alg_viterbi { + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_fwd_scaled extends alg_viterbi { + float emission(float prob, char emission) { + /* 43.38 is a scaling factor against numeric instability, + * as candidate probabilities tend to become very small. + * The value is 1 / median of all emission probabilities + * in the TMHMM2 model; but in principle can be any value > 1. + */ + return 22.56 * prob; + } + float normalize_derivative(float q, float pfunc) { + return q / pfunc; + } + choice [float] h([float] candidates) { + return list(sum(candidates)); + } +} + +algebra alg_viterbi_bit extends alg_viterbi { + float silent_transition(float prob, float t) { + return log(1.0/prob) + t; + } + float transition(char label, float prob, float e, float t) { + return log(1.0/prob) + e + t; + } + float nil(void) { + return 0.0; + } + float emission(float prob, char emission) { + return log(1.0/prob); + } + choice [float] h([float] candidates) { + return list(minimum(candidates)); + } +} + +algebra alg_fwd_bit extends alg_viterbi_bit { + float normalize_derivative(float q, float pfunc) { + return exp(pfunc - q); + } + choice [float] h([float] candidates) { + return list(negexpsum(candidates)); + } +} + +algebra alg_label implements sig_tmhmm(alphabet=char, answer=Rope) { + Rope silent_transition(float prob, Rope x) { + return x; + } + Rope transition(char label, float prob, Rope e, Rope t) { + Rope res; + append(res, label); + append(res, t); + return res; + } + Rope nil(void) { + Rope res; + return res; + } + Rope emission(float prob, char emission) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +grammar gra_tmhmm uses sig_tmhmm(axiom = state_begin) { + state_begin = + silent_transition(CONST_FLOAT(0.549251), state_in10) | + silent_transition(CONST_FLOAT(0.207469), state_outglob10) | + silent_transition(CONST_FLOAT(0.24328), state_out10) | + state_end + # h; + + state_in10 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.995851), emit_in10, state_in11) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00111283), emit_in10, state_in29) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00303586), emit_in10, state_ohelixi1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + emit_in10 = + emission(CONST_FLOAT(0.0713632), CHAR('A')) | + emission(CONST_FLOAT(0.0188491), CHAR('C')) | + emission(CONST_FLOAT(0.043014), CHAR('D')) | + emission(CONST_FLOAT(0.0471663), CHAR('E')) | + emission(CONST_FLOAT(0.0298789), CHAR('F')) | + emission(CONST_FLOAT(0.0564853), CHAR('G')) | + emission(CONST_FLOAT(0.0233906), CHAR('H')) | + emission(CONST_FLOAT(0.038904), CHAR('I')) | + emission(CONST_FLOAT(0.0894525), CHAR('K')) | + emission(CONST_FLOAT(0.0551519), CHAR('L')) | + emission(CONST_FLOAT(0.0427067), CHAR('M')) | + emission(CONST_FLOAT(0.0544149), CHAR('N')) | + emission(CONST_FLOAT(0.0370019), CHAR('P')) | + emission(CONST_FLOAT(0.0524006), CHAR('Q')) | + emission(CONST_FLOAT(0.114758), CHAR('R')) | + emission(CONST_FLOAT(0.0661936), CHAR('S')) | + emission(CONST_FLOAT(0.0689907), CHAR('T')) | + emission(CONST_FLOAT(0.0416332), CHAR('V')) | + emission(CONST_FLOAT(0.0146085), CHAR('W')) | + emission(CONST_FLOAT(0.0336358), CHAR('Y')) + # h; + + state_in11 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.976066), emit_in10, state_in12) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0239339), emit_in10, state_in28) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.08323e-09), emit_in10, state_in29) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in12 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.895077), emit_in10, state_in13) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.104922), emit_in10, state_in27) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.76891e-06), emit_in10, state_in28) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in13 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.979527), emit_in10, state_in14) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0204673), emit_in10, state_in26) | + transition(CONST_CHAR('i'), CONST_FLOAT(5.81809e-06), emit_in10, state_in27) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in14 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.993341), emit_in10, state_in15) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00660812), emit_in10, state_in25) | + transition(CONST_CHAR('i'), CONST_FLOAT(5.08664e-05), emit_in10, state_in26) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in15 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.738969), emit_in10, state_in16) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.159734), emit_in10, state_in24) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.101297), emit_in10, state_in25) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in16 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.999938), emit_in10, state_in17) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.4427e-06), emit_in10, state_in23) | + transition(CONST_CHAR('i'), CONST_FLOAT(6.0424e-05), emit_in10, state_in24) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in17 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.973203), emit_in10, state_in18) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0168132), emit_in10, state_in22) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.00998417), emit_in10, state_in23) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in18 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.977498), emit_in10, state_in19) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.0217216), emit_in10, state_in21) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.000780768), emit_in10, state_in22) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in19 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.16223), emit_in10, state_in20) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.10126), emit_in10, state_in21) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.73651), emit_in10, state_inglob1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in20 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in21) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in21 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in22) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in22 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in23) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in23 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in24) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in24 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in25) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in25 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in26) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in26 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in27) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in27 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in28) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in28 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_in29) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_in29 = + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_ohelixi1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_in10, state_end) + # h; + + state_inglob1 = + transition(CONST_CHAR('i'), CONST_FLOAT(0.0132918), emit_inglob1, state_in20) | + transition(CONST_CHAR('i'), CONST_FLOAT(0.986708), emit_inglob1, state_inglob1) | + transition(CONST_CHAR('i'), CONST_FLOAT(1.0), emit_inglob1, state_end) + # h; + emit_inglob1 = + emission(CONST_FLOAT(0.0773341), CHAR('A')) | + emission(CONST_FLOAT(0.0212026), CHAR('C')) | + emission(CONST_FLOAT(0.0556231), CHAR('D')) | + emission(CONST_FLOAT(0.0789783), CHAR('E')) | + emission(CONST_FLOAT(0.0291466), CHAR('F')) | + emission(CONST_FLOAT(0.0821038), CHAR('G')) | + emission(CONST_FLOAT(0.02529), CHAR('H')) | + emission(CONST_FLOAT(0.0392883), CHAR('I')) | + emission(CONST_FLOAT(0.0466567), CHAR('K')) | + emission(CONST_FLOAT(0.0718204), CHAR('L')) | + emission(CONST_FLOAT(0.0191835), CHAR('M')) | + emission(CONST_FLOAT(0.0490524), CHAR('N')) | + emission(CONST_FLOAT(0.0671432), CHAR('P')) | + emission(CONST_FLOAT(0.0472671), CHAR('Q')) | + emission(CONST_FLOAT(0.0492684), CHAR('R')) | + emission(CONST_FLOAT(0.0852997), CHAR('S')) | + emission(CONST_FLOAT(0.0610192), CHAR('T')) | + emission(CONST_FLOAT(0.0528717), CHAR('V')) | + emission(CONST_FLOAT(0.0166592), CHAR('W')) | + emission(CONST_FLOAT(0.0247916), CHAR('Y')) + # h; + + state_outglob10 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob11) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + emit_outglob10 = + emission(CONST_FLOAT(0.0693743), CHAR('A')) | + emission(CONST_FLOAT(0.0149605), CHAR('C')) | + emission(CONST_FLOAT(0.0406956), CHAR('D')) | + emission(CONST_FLOAT(0.0538397), CHAR('E')) | + emission(CONST_FLOAT(0.0531778), CHAR('F')) | + emission(CONST_FLOAT(0.0792746), CHAR('G')) | + emission(CONST_FLOAT(0.0221055), CHAR('H')) | + emission(CONST_FLOAT(0.0440866), CHAR('I')) | + emission(CONST_FLOAT(0.0565779), CHAR('K')) | + emission(CONST_FLOAT(0.0988165), CHAR('L')) | + emission(CONST_FLOAT(0.0432829), CHAR('M')) | + emission(CONST_FLOAT(0.0414346), CHAR('N')) | + emission(CONST_FLOAT(0.0615562), CHAR('P')) | + emission(CONST_FLOAT(0.0412212), CHAR('Q')) | + emission(CONST_FLOAT(0.0677628), CHAR('R')) | + emission(CONST_FLOAT(0.0732544), CHAR('S')) | + emission(CONST_FLOAT(0.0524824), CHAR('T')) | + emission(CONST_FLOAT(0.0445653), CHAR('V')) | + emission(CONST_FLOAT(0.0140309), CHAR('W')) | + emission(CONST_FLOAT(0.0275), CHAR('Y')) + # h; + + state_outglob11 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob12) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob12 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob13) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob13 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob14) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob14 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob15) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob15 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob16) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob16 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob17) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob17 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob18) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob18 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob19) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob19 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglobLong) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglobLong = + transition(CONST_CHAR('O'), CONST_FLOAT(0.999093), emit_inglob1, state_outglobLong) | + transition(CONST_CHAR('O'), CONST_FLOAT(0.000906913), emit_inglob1, state_outglob20) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_inglob1, state_end) + # h; + + state_outglob20 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob21) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob21 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob22) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob22 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob23) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob23 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob24) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob24 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob25) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob25 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob26) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob26 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob27) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob27 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob28) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob28 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_outglob29) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_outglob29 = + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_ihelixo1) | + transition(CONST_CHAR('O'), CONST_FLOAT(1.0), emit_outglob10, state_end) + # h; + + state_out10 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out11) | + transition(CONST_CHAR('o'), CONST_FLOAT(3.54571e-14), emit_out10, state_out29) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + emit_out10 = + emission(CONST_FLOAT(0.0690346), CHAR('A')) | + emission(CONST_FLOAT(0.0129673), CHAR('C')) | + emission(CONST_FLOAT(0.0627756), CHAR('D')) | + emission(CONST_FLOAT(0.0541851), CHAR('E')) | + emission(CONST_FLOAT(0.0425402), CHAR('F')) | + emission(CONST_FLOAT(0.0835626), CHAR('G')) | + emission(CONST_FLOAT(0.0271581), CHAR('H')) | + emission(CONST_FLOAT(0.0292546), CHAR('I')) | + emission(CONST_FLOAT(0.0530401), CHAR('K')) | + emission(CONST_FLOAT(0.0822093), CHAR('L')) | + emission(CONST_FLOAT(0.0334625), CHAR('M')) | + emission(CONST_FLOAT(0.0506017), CHAR('N')) | + emission(CONST_FLOAT(0.0693889), CHAR('P')) | + emission(CONST_FLOAT(0.0389539), CHAR('Q')) | + emission(CONST_FLOAT(0.0432109), CHAR('R')) | + emission(CONST_FLOAT(0.0863749), CHAR('S')) | + emission(CONST_FLOAT(0.0587278), CHAR('T')) | + emission(CONST_FLOAT(0.0480586), CHAR('V')) | + emission(CONST_FLOAT(0.0198473), CHAR('W')) | + emission(CONST_FLOAT(0.0346461), CHAR('Y')) + # h; + + state_out11 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.910217), emit_out10, state_out12) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0495866), emit_out10, state_out28) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0401965), emit_out10, state_out29) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out12 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.984498), emit_out10, state_out13) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00440955), emit_out10, state_out27) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0110921), emit_out10, state_out28) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out13 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.997286), emit_out10, state_out14) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00258189), emit_out10, state_out26) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.000132519), emit_out10, state_out27) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out14 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.812906), emit_out10, state_out15) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0130127), emit_out10, state_out25) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.174082), emit_out10, state_out26) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out15 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.951951), emit_out10, state_out16) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0400992), emit_out10, state_out24) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00795001), emit_out10, state_out25) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out16 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.660205), emit_out10, state_out17) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.33979), emit_out10, state_out23) | + transition(CONST_CHAR('o'), CONST_FLOAT(4.76867e-06), emit_out10, state_out24) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out17 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.992733), emit_out10, state_out18) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0072618), emit_out10, state_out22) | + transition(CONST_CHAR('o'), CONST_FLOAT(5.34599e-06), emit_out10, state_out23) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out18 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.971165), emit_out10, state_out19) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0119931), emit_out10, state_out21) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0168416), emit_out10, state_out22) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out19 = + transition(CONST_CHAR('o'), CONST_FLOAT(0.770716), emit_out10, state_outglobShort) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.00133523), emit_out10, state_out20) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.227948), emit_out10, state_out21) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_outglobShort = + transition(CONST_CHAR('o'), CONST_FLOAT(0.960334), emit_inglob1, state_outglobShort) | + transition(CONST_CHAR('o'), CONST_FLOAT(0.0396664), emit_inglob1, state_out20) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_inglob1, state_end) + # h; + + state_out20 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out21) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out21 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out22) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out22 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out23) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out23 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out24) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out24 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out25) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out25 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out26) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out26 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out27) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out27 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out28) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out28 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_out29) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_out29 = + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_ihelixo1) | + transition(CONST_CHAR('o'), CONST_FLOAT(1.0), emit_out10, state_end) + # h; + + state_ohelixi1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi2) + # h; + emit_ohelixi1 = + emission(CONST_FLOAT(0.0890049), CHAR('A')) | + emission(CONST_FLOAT(0.0170933), CHAR('C')) | + emission(CONST_FLOAT(0.00159548), CHAR('D')) | + emission(CONST_FLOAT(0.00489647), CHAR('E')) | + emission(CONST_FLOAT(0.108081), CHAR('F')) | + emission(CONST_FLOAT(0.0692068), CHAR('G')) | + emission(CONST_FLOAT(0.00923517), CHAR('H')) | + emission(CONST_FLOAT(0.113471), CHAR('I')) | + emission(CONST_FLOAT(0.00466208), CHAR('K')) | + emission(CONST_FLOAT(0.19417), CHAR('L')) | + emission(CONST_FLOAT(0.0239901), CHAR('M')) | + emission(CONST_FLOAT(0.0233656), CHAR('N')) | + emission(CONST_FLOAT(0.0145168), CHAR('P')) | + emission(CONST_FLOAT(0.00487025), CHAR('Q')) | + emission(CONST_FLOAT(0.0127643), CHAR('R')) | + emission(CONST_FLOAT(0.0455139), CHAR('S')) | + emission(CONST_FLOAT(0.0292949), CHAR('T')) | + emission(CONST_FLOAT(0.128208), CHAR('V')) | + emission(CONST_FLOAT(0.0399529), CHAR('W')) | + emission(CONST_FLOAT(0.0661077), CHAR('Y')) + # h; + + state_ohelixi2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi3) + # h; + + state_ohelixi3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi4) + # h; + + state_ohelixi4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi5) + # h; + + state_ohelixi5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ohelixi6) + # h; + + state_ohelixi6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixi7) + # h; + + state_ohelixi7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixm) + # h; + + state_ohelixm = + transition(CONST_CHAR('M'), CONST_FLOAT(0.000534023), emit_ohelixm, state_ohelix2) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000567583), emit_ohelixm, state_ohelix3) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00064457), emit_ohelixm, state_ohelix4) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00159544), emit_ohelixm, state_ohelix5) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000669433), emit_ohelixm, state_ohelix6) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00161008), emit_ohelixm, state_ohelix7) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000762887), emit_ohelixm, state_ohelix8) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000789084), emit_ohelixm, state_ohelix9) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000868204), emit_ohelixm, state_ohelix10) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00519996), emit_ohelixm, state_ohelix11) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00774891), emit_ohelixm, state_ohelix12) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0108947), emit_ohelixm, state_ohelix13) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.697722), emit_ohelixm, state_ohelix14) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0444777), emit_ohelixm, state_ohelix15) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0328707), emit_ohelixm, state_ohelix16) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.111827), emit_ohelixm, state_ohelix17) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0324248), emit_ohelixm, state_ohelix18) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0448694), emit_ohelixm, state_ohelix19) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00212234), emit_ohelixm, state_ohelix20) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00107586), emit_ohelixm, state_ohelix21) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00072618), emit_ohelixm, state_ohelixo1) + # h; + emit_ohelixm = + emission(CONST_FLOAT(0.110896), CHAR('A')) | + emission(CONST_FLOAT(0.0254931), CHAR('C')) | + emission(CONST_FLOAT(0.00235724), CHAR('D')) | + emission(CONST_FLOAT(0.00383965), CHAR('E')) | + emission(CONST_FLOAT(0.0942003), CHAR('F')) | + emission(CONST_FLOAT(0.0818095), CHAR('G')) | + emission(CONST_FLOAT(0.00408389), CHAR('H')) | + emission(CONST_FLOAT(0.144377), CHAR('I')) | + emission(CONST_FLOAT(0.00236432), CHAR('K')) | + emission(CONST_FLOAT(0.182902), CHAR('L')) | + emission(CONST_FLOAT(0.0385107), CHAR('M')) | + emission(CONST_FLOAT(0.00978815), CHAR('N')) | + emission(CONST_FLOAT(0.0201094), CHAR('P')) | + emission(CONST_FLOAT(0.00437833), CHAR('Q')) | + emission(CONST_FLOAT(0.00115335), CHAR('R')) | + emission(CONST_FLOAT(0.0421756), CHAR('S')) | + emission(CONST_FLOAT(0.0514071), CHAR('T')) | + emission(CONST_FLOAT(0.132167), CHAR('V')) | + emission(CONST_FLOAT(0.0158643), CHAR('W')) | + emission(CONST_FLOAT(0.0321232), CHAR('Y')) + # h; + + state_ohelix2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix3) + # h; + + state_ohelix3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix4) + # h; + + state_ohelix4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix5) + # h; + + state_ohelix5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix6) + # h; + + state_ohelix6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix7) + # h; + + state_ohelix7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix8) + # h; + + state_ohelix8 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix9) + # h; + + state_ohelix9 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix10) + # h; + + state_ohelix10 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix11) + # h; + + state_ohelix11 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix12) + # h; + + state_ohelix12 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix13) + # h; + + state_ohelix13 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix14) + # h; + + state_ohelix14 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix15) + # h; + + state_ohelix15 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix16) + # h; + + state_ohelix16 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix17) + # h; + + state_ohelix17 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix18) + # h; + + state_ohelix18 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix19) + # h; + + state_ohelix19 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix20) + # h; + + state_ohelix20 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelix21) + # h; + + state_ohelix21 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixo1) + # h; + + state_ohelixo1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixo2) + # h; + + state_ohelixo2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ohelixo3) + # h; + + state_ohelixo3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo4) + # h; + + state_ohelixo4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo5) + # h; + + state_ohelixo5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo6) + # h; + + state_ohelixo6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ohelixo7) + # h; + + state_ohelixo7 = + transition(CONST_CHAR('M'), CONST_FLOAT(0.0757404), emit_ohelixo7, state_outglob10) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.92426), emit_ohelixo7, state_out10) + # h; + emit_ohelixo7 = + emission(CONST_FLOAT(0.110353), CHAR('A')) | + emission(CONST_FLOAT(0.00498206), CHAR('C')) | + emission(CONST_FLOAT(0.00469973), CHAR('D')) | + emission(CONST_FLOAT(0.00649427), CHAR('E')) | + emission(CONST_FLOAT(0.0973043), CHAR('F')) | + emission(CONST_FLOAT(0.0737631), CHAR('G')) | + emission(CONST_FLOAT(0.0119931), CHAR('H')) | + emission(CONST_FLOAT(0.12167), CHAR('I')) | + emission(CONST_FLOAT(0.00180854), CHAR('K')) | + emission(CONST_FLOAT(0.157124), CHAR('L')) | + emission(CONST_FLOAT(0.044721), CHAR('M')) | + emission(CONST_FLOAT(0.0107496), CHAR('N')) | + emission(CONST_FLOAT(0.0283821), CHAR('P')) | + emission(CONST_FLOAT(0.0143416), CHAR('Q')) | + emission(CONST_FLOAT(0.00857182), CHAR('R')) | + emission(CONST_FLOAT(0.0402204), CHAR('S')) | + emission(CONST_FLOAT(0.0501039), CHAR('T')) | + emission(CONST_FLOAT(0.107462), CHAR('V')) | + emission(CONST_FLOAT(0.0501891), CHAR('W')) | + emission(CONST_FLOAT(0.0550665), CHAR('Y')) + # h; + + state_ihelixo1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo2) + # h; + + state_ihelixo2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo3) + # h; + + state_ihelixo3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo4) + # h; + + state_ihelixo4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo5) + # h; + + state_ihelixo5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixo7, state_ihelixo6) + # h; + + state_ihelixo6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixo7) + # h; + + state_ihelixo7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixm) + # h; + + state_ihelixm = + transition(CONST_CHAR('M'), CONST_FLOAT(0.000534023), emit_ohelixm, state_ihelix2) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000567583), emit_ohelixm, state_ihelix3) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00064457), emit_ohelixm, state_ihelix4) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00159544), emit_ohelixm, state_ihelix5) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000669433), emit_ohelixm, state_ihelix6) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00161008), emit_ohelixm, state_ihelix7) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000762887), emit_ohelixm, state_ihelix8) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000789084), emit_ohelixm, state_ihelix9) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.000868204), emit_ohelixm, state_ihelix10) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00519996), emit_ohelixm, state_ihelix11) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00774891), emit_ohelixm, state_ihelix12) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0108947), emit_ohelixm, state_ihelix13) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.697722), emit_ohelixm, state_ihelix14) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0444777), emit_ohelixm, state_ihelix15) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0328707), emit_ohelixm, state_ihelix16) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.111827), emit_ohelixm, state_ihelix17) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0324248), emit_ohelixm, state_ihelix18) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.0448694), emit_ohelixm, state_ihelix19) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00212234), emit_ohelixm, state_ihelix20) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00107586), emit_ohelixm, state_ihelix21) | + transition(CONST_CHAR('M'), CONST_FLOAT(0.00072618), emit_ohelixm, state_ihelixi1) + # h; + + state_ihelix2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix3) + # h; + + state_ihelix3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix4) + # h; + + state_ihelix4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix5) + # h; + + state_ihelix5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix6) + # h; + + state_ihelix6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix7) + # h; + + state_ihelix7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix8) + # h; + + state_ihelix8 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix9) + # h; + + state_ihelix9 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix10) + # h; + + state_ihelix10 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix11) + # h; + + state_ihelix11 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix12) + # h; + + state_ihelix12 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix13) + # h; + + state_ihelix13 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix14) + # h; + + state_ihelix14 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix15) + # h; + + state_ihelix15 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix16) + # h; + + state_ihelix16 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix17) + # h; + + state_ihelix17 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix18) + # h; + + state_ihelix18 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix19) + # h; + + state_ihelix19 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix20) + # h; + + state_ihelix20 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelix21) + # h; + + state_ihelix21 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixi1) + # h; + + state_ihelixi1 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixi2) + # h; + + state_ihelixi2 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixm, state_ihelixi3) + # h; + + state_ihelixi3 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi4) + # h; + + state_ihelixi4 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi5) + # h; + + state_ihelixi5 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi6) + # h; + + state_ihelixi6 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_ihelixi7) + # h; + + state_ihelixi7 = + transition(CONST_CHAR('M'), CONST_FLOAT(1.0), emit_ohelixi1, state_in10) + # h; + + state_end = nil(EMPTY) # h; +} + +instance dummy = gra_tmhmm(alg_enum); +instance fwd_scaled = gra_tmhmm(alg_fwd_scaled); \ No newline at end of file diff --git a/testdata/grammar_outside/tmhmm_debug.gap b/testdata/grammar_outside/tmhmm_debug.gap new file mode 100644 index 000000000..ace396b17 --- /dev/null +++ b/testdata/grammar_outside/tmhmm_debug.gap @@ -0,0 +1,160 @@ +type Rope = extern + +signature sig_tmhmm(alphabet, answer) { + answer silent_step(answer); + answer step(char, answer, answer); + answer nil(void); + answer trans(float, answer); + answer only(float, alphabet); + choice [answer] h([answer]); +} + +algebra alg_enum auto enum; + +algebra alg_count auto count; + +algebra alg_viterbi implements sig_tmhmm(alphabet=char, answer=float) { + float silent_step(float x) { + return x; + } + float step(char label, float e, float t) { + return e*t; + } + float nil(void) { + return 1; + } + float trans(float prob, float x) { + return prob * x; + } + float only(float prob, char emission) { + return prob; + } + choice [float] h([float] candidates) { + return list(maximum(candidates)); + } +} + +algebra alg_viterbi_bit extends alg_viterbi { + float step(char label, float e, float t) { + return log(1.0/e) + t; + } + float nil(void) { + return 0.0; + } + float trans(float prob, float x) { + return log(1.0/prob) + x; + } + choice [float] h([float] candidates) { + return list(minimum(candidates)); + } +} + +algebra alg_label implements sig_tmhmm(alphabet=char, answer=Rope) { + Rope silent_step(Rope x) { + return x; + } + Rope step(char label, Rope e, Rope t) { + Rope res; + append(res, label); + append(res, t); + return res; + } + Rope nil(void) { + Rope res; + return res; + } + Rope trans(float prob, Rope x) { + return x; + } + Rope only(float prob, char emission) { + Rope res; + return res; + } + choice [Rope] h([Rope] candidates) { + return unique(candidates); + } +} + +grammar gra_tmhmm uses sig_tmhmm(axiom = state_begin) { + state_begin = silent_step(transitions_begin) # h; + transitions_begin = + trans(CONST_FLOAT(0.549251), state_in10) | + trans(CONST_FLOAT(0.207469), state_outglob10) | + trans(CONST_FLOAT(0.24328), state_out10) + # h; + state_in10 = step(CONST_CHAR('i'), emissions_in10, { transitions_in10 | nil(EMPTY) }) # h; + emissions_in10 = + only(CONST_FLOAT(0.0713632), CHAR('A')) | + only(CONST_FLOAT(0.0336358), CHAR('Y')) + # h; + transitions_in10 = + trans(CONST_FLOAT(0.995851), state_in11) | + trans(CONST_FLOAT(0.00111283), state_in29) | + trans(CONST_FLOAT(0.00303586), state_ohelixi1) + # h; + state_in11 = step(CONST_CHAR('i'), emissions_in10, { transitions_in11 | nil(EMPTY) }) # h; + transitions_in11 = + trans(CONST_FLOAT(0.976066), nil(EMPTY)) | + trans(CONST_FLOAT(0.0239339), nil(EMPTY)) | + trans(CONST_FLOAT(1.08323e-09), state_in29) + # h; + state_in29 = step(CONST_CHAR('i'), emissions_in10, { transitions_in29 | nil(EMPTY) }) # h; + transitions_in29 = + trans(CONST_FLOAT(1.0), state_ohelixi1) + # h; + state_ohelixi1 = step(CONST_CHAR('M'), emissions_ohelixi1, transitions_ohelixi1) # h; + emissions_ohelixi1 = + only(CONST_FLOAT(0.0890049), CHAR('A')) | + only(CONST_FLOAT(0.0661077), CHAR('Y')) + # h; + transitions_ohelixi1 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) + # h; + state_outglob10 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob10 | nil(EMPTY) }) # h; + emissions_outglob10 = + only(CONST_FLOAT(0.0693743), CHAR('A')) | + only(CONST_FLOAT(0.0275), CHAR('Y')) + # h; + transitions_outglob10 = + trans(CONST_FLOAT(1.0), state_outglob11) | + trans(CONST_FLOAT(0.0), state_outglob29) | + trans(CONST_FLOAT(0.0), state_ihelixo1) + # h; + state_outglob11 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob11 | nil(EMPTY) }) # h; + transitions_outglob11 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) | + trans(CONST_FLOAT(0.0), nil(EMPTY)) | + trans(CONST_FLOAT(0.0), state_outglob29) + # h; + state_outglob29 = step(CONST_CHAR('O'), emissions_outglob10, { transitions_outglob29 | nil(EMPTY) }) # h; + transitions_outglob29 = + trans(CONST_FLOAT(1.0), state_ihelixo1) + # h; + state_ihelixo1 = step(CONST_CHAR('M'), emissions_out10, transitions_ihelixo1) # h; + transitions_ihelixo1 = + trans(CONST_FLOAT(1.0), nil(EMPTY)) + # h; + state_out10 = step(CONST_CHAR('o'), emissions_out10, { transitions_out10 | nil(EMPTY) }) # h; + emissions_out10 = + only(CONST_FLOAT(0.0690346), CHAR('A')) | + only(CONST_FLOAT(0.0346461), CHAR('Y')) + # h; + transitions_out10 = + trans(CONST_FLOAT(1.0), state_out11) | + trans(CONST_FLOAT(3.54571e-14), state_out29) | + trans(CONST_FLOAT(0.0), state_ihelixo1) + # h; + state_out11 = step(CONST_CHAR('o'), emissions_out10, { transitions_out11 | nil(EMPTY) }) # h; + transitions_out11 = + trans(CONST_FLOAT(0.910217), nil(EMPTY)) | + trans(CONST_FLOAT(0.0495866), nil(EMPTY)) | + trans(CONST_FLOAT(0.0401965), state_out29) + # h; + state_out29 = step(CONST_CHAR('o'), emissions_out10, { transitions_out29 | nil(EMPTY) }) # h; + transitions_out29 = + trans(CONST_FLOAT(1.0), state_ihelixo1) + # h; +} + +instance dummy = gra_tmhmm(alg_enum); +instance count = gra_tmhmm(alg_count); diff --git a/testdata/grammar_outside/unblock_alot.gap b/testdata/grammar_outside/unblock_alot.gap new file mode 100644 index 000000000..74fdb37b8 --- /dev/null +++ b/testdata/grammar_outside/unblock_alot.gap @@ -0,0 +1,239 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + +algebra alg_mfe implements sig_foldrna(alphabet = char, answer = int) { + int sadd(Subsequence lb, int x) { + return x + sbase_energy(); + } + int cadd(int x, int y) { + return x + y; + } + int drem(Subsequence lb, int x, Subsequence rb) { + return x + termau_energy(lb, rb); + } + int sr(Subsequence lb, int x, Subsequence rb) { + return x + sr_energy(lb, rb); + } + int hl(Subsequence lb, Subsequence r, Subsequence rb) { + return hl_energy(r); + } + int bl(Subsequence lb, Subsequence lr, int x, Subsequence rb) { + return x + bl_energy(lr, rb); + } + int br(Subsequence lb, int x, Subsequence rr, Subsequence rb) { + return x + br_energy(lb, rr); + } + int il(Subsequence lb, Subsequence lr, int x, Subsequence rr, Subsequence rb) { + return x + il_energy(lr, rr); + } + int ml(Subsequence lb, int x, Subsequence rb) { + return x + ml_energy() + ul_energy() + termau_energy(lb, rb); + } + int incl(int x) { + return x + ul_energy(); + } + int addss(int x, Subsequence r) { + return x + ss_energy(r); + } + int nil(Subsequence n) { + return 0; + } + choice [int] h([int] i) { + return list(minimum(i)); + } +} + +algebra alg_pfunc implements sig_foldrna(alphabet = char, answer = double) { + double sadd(Subsequence lb, double x) { + return scale(1) * x * mk_pf(sbase_energy()); + } + double cadd(double x, double y) { + return x * y; + } + double drem(Subsequence lb, double x, Subsequence rb) { + return x * mk_pf(termau_energy(lb, rb)); + } + double sr(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(sr_energy(lb, rb)); + } + double hl(Subsequence lb, Subsequence r, Subsequence rb) { + return scale(2+r.j-r.i) * mk_pf(hl_energy(r)); + } + double bl(Subsequence lb, Subsequence lr, double x, Subsequence rb) { + return scale(2+lr.j-lr.i) * x * mk_pf(bl_energy(lr, rb)); + } + double br(Subsequence lb, double x, Subsequence rr, Subsequence rb) { + return scale(2+rr.j-rr.i) * x * mk_pf(br_energy(lb, rr)); + } + double il(Subsequence lb, Subsequence lr, double x, Subsequence rr, Subsequence rb) { + return scale(2+lr.j-lr.i+rr.j-rr.i) * x * mk_pf(il_energy(lr, rr)); + } + double ml(Subsequence lb, double x, Subsequence rb) { + return scale(2) * x * mk_pf(ml_energy() + ul_energy() + termau_energy(lb, rb)); + } + double incl(double x) { + return x * mk_pf(ul_energy()); + } + double addss(double x, Subsequence r) { + return scale(r.j-r.i) * x * mk_pf(ss_energy(r)); + } + double nil(Subsequence n) { + return 1; + } + choice [double] h([double] i) { + return list(sum(i)); + } +} + +algebra alg_dotBracket implements sig_foldrna(alphabet = char, answer = string) { + string sadd(Subsequence lb,string e) { + string res; + append(res, '.'); + append(res, e); + return res; + } + + string cadd(string le,string re) { + string res; + append(res, le); + append(res, re); + return res; + } + + string nil(Subsequence loc) { + string r; + return r; + } + + string drem(Subsequence lloc, string e, Subsequence rloc) { + return e; + } + + string sr(Subsequence lb,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string hl(Subsequence lb,Subsequence region,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(region)); + append(res, ')'); + return res; + } + + + string bl(Subsequence lb,Subsequence lregion,string e,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, ')'); + return res; + } + + string br(Subsequence lb,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string il(Subsequence lb,Subsequence lregion,string e,Subsequence rregion,Subsequence rb) { + string res; + append(res, '('); + append(res, '.', size(lregion)); + append(res, e); + append(res, '.', size(rregion)); + append(res, ')'); + return res; + } + + string ml(Subsequence lb, string e, Subsequence rb) { + string res; + append(res, '('); + append(res, e); + append(res, ')'); + return res; + } + + string addss(string e,Subsequence rb) { + string res; + append(res, e); + append(res, '.', size(rb)); + return res; + } + + string incl(string e) { + return e; + } + + choice [string] h([string] i) { + return i; + } +} + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, {{{struct}}}) | + cadd({dangle | sadd(BASE, {dangle | incl(hairpin) | incl(strong)})}, struct) | + nil(LOC) # h; + + dangle = drem(LOC, strong, LOC) # h; + + strong = weak # h; + + weak = stack | + hairpin | + leftB | + rightB | + iloop | + multiloop # h; + + stack = sr(BASE, weak, BASE) with basepairing # h; + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; + leftB = bl(BASE, REGION with maxsize(30), strong, BASE) with basepairing # h; + rightB = br(BASE, strong, REGION with maxsize(30), BASE) with basepairing # h; + iloop = il(BASE, REGION with maxsize(30), strong, REGION with maxsize(30), BASE) with basepairing with_overlay iloopSumMax(30) # h; + multiloop = ml(BASE, ml_comps, BASE) with basepairing # h; + + ml_comps = sadd(BASE, ml_comps) | + cadd(incl(dangle), ml_comps1) # h; + + ml_comps1 = sadd(BASE, ml_comps1) | + cadd(incl(dangle), ml_comps1) | + incl(dangle) | + addss(incl(dangle), REGION) # h; +} + + + +instance ins_mfe = gra_nodangle(alg_mfe); +instance ins_pfunc = gra_nodangle(alg_pfunc); +instance ins_count = gra_nodangle(alg_count); +instance ins_enum = gra_nodangle(alg_enum); diff --git a/testdata/grammar_outside/unblock_multialt_parentNT.gap b/testdata/grammar_outside/unblock_multialt_parentNT.gap new file mode 100644 index 000000000..92f51d29f --- /dev/null +++ b/testdata/grammar_outside/unblock_multialt_parentNT.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = {sadd(BASE, struct) | sadd(BASE, hairpin) | weak} + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = {hairpin} # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/grammar_outside/unblock_multialt_parentSimple.gap b/testdata/grammar_outside/unblock_multialt_parentSimple.gap new file mode 100644 index 000000000..3d57191c0 --- /dev/null +++ b/testdata/grammar_outside/unblock_multialt_parentSimple.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, {struct | weak | incl(dangle)}) + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = hairpin # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/grammar_outside/unblock_onealt_parentNT.gap b/testdata/grammar_outside/unblock_onealt_parentNT.gap new file mode 100644 index 000000000..caff68a6b --- /dev/null +++ b/testdata/grammar_outside/unblock_onealt_parentNT.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = {sadd(BASE, struct)} + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = {hairpin} # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/grammar_outside/unblock_onealt_parentSimple.gap b/testdata/grammar_outside/unblock_onealt_parentSimple.gap new file mode 100644 index 000000000..9711b86da --- /dev/null +++ b/testdata/grammar_outside/unblock_onealt_parentSimple.gap @@ -0,0 +1,39 @@ +import rna +import "singlefold.hh" + +input rna + +signature sig_foldrna(alphabet,answer) { + answer sadd(Subsequence,answer); //add one unpaired base + answer cadd(answer,answer); //adds one component, which has dangling bases from both sides, next component has a dangling base from left + answer nil(Subsequence); //empty structure + answer drem(Subsequence,answer,Subsequence); //no dangle, just the component + answer sr(Subsequence,answer,Subsequence); //elongate a stack by one base-pair + answer hl(Subsequence,Subsequence,Subsequence); //a hairpin loop with a closing base-pair + answer bl(Subsequence, Subsequence, answer, Subsequence); // a bulge loop to the left with a closing base-pair + answer br(Subsequence, answer, Subsequence, Subsequence); // a bulge loop to the right with a closing base-pair + answer il(Subsequence, Subsequence, answer, Subsequence, Subsequence); // an internal loop with a closing base-pair + answer ml(Subsequence,answer,Subsequence); // a multi-loop with a closing base-pair and no dangling bases + answer addss(answer,Subsequence); // append a region of unpaired bases + answer incl(answer); // add penalty for one more multi-loop component + choice [answer] h([answer]); +} + +algebra alg_count auto count; +algebra alg_enum auto enum; + + +grammar gra_nodangle uses sig_foldrna(axiom = struct) { + struct = sadd(BASE, {struct}) + | nil(LOC) + # h; + + dangle = drem(LOC, weak, LOC) # h; + + weak = {hairpin} # h; + + hairpin = hl(BASE, REGION with minsize(3), BASE) with basepairing # h; +} + + +instance ins_count = gra_nodangle(alg_count); diff --git a/testdata/modtest/outside_indices.cc b/testdata/modtest/outside_indices.cc new file mode 100644 index 000000000..351c9cd52 --- /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->inject_outside_nts(); + + // set approx table design + grammar->approx_table_conf(); + + // find what type of input is read + // chars, sequence of ints etc. + driver.ast.derive_temp_alphabet(); + + r = driver.ast.check_signature(); + if (!r) { + return 4; + } + + // apply this to identify standard functions like Min, Max, Exp etc. + driver.ast.derive_roles(); + + + // ------------- back ------------ + grammar->init_list_sizes(); + + grammar->init_indices(); + grammar->init_decls(); + // for cyk (ordering of NT for parsing, see page 101 of the thesis) + grammar->dep_analysis(); + + unsigned int nodeID = 1; + grammar->to_dot(&nodeID, std::cout, 3); +} diff --git a/testdata/modtest/outside_resolve_blocks.cc b/testdata/modtest/outside_resolve_blocks.cc new file mode 100644 index 000000000..f00bc5e38 --- /dev/null +++ b/testdata/modtest/outside_resolve_blocks.cc @@ -0,0 +1,88 @@ +// Copyright 2022 stefan.m.janssen@gmail.com + +#include +#include +#include +#include + +#include "../../src/driver.hh" +#include "../../src/log.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) { + (*i).second->resolve_blocks(); + } + + // 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 (LogThreshException) { + 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 63321e5da..4615c263f 100644 --- a/testdata/regresstest/config +++ b/testdata/regresstest/config @@ -481,3 +481,84 @@ check_new_old_eq eraseanswers.gap unused ins_count_failing "AC" eraseanswer check_new_old_eq eraseanswers.gap unused ins_count_working "AC" eraseanswer check_new_old_eq eraseanswers_product.gap unused ins "CaaG" eraseanswer_one check_new_old_eq eraseanswers_product.gap unused ins "CaaaG" eraseanswer_four + +# results have been verified against "RNAfold -p -d0 --bppmThreshold=0" v2.4.17 and Stefan's manual python outside version of nodangle +GRAMMAR=../../grammar_outside +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +check_new_old_eq nodangle.gap unused mfe "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside +check_new_old_eq nodangle.gap unused count "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside + +# check that fn_arg (with alt) instead of only alt gets initialized +check_new_old_eq nodangle_withoverlay.gap unused ins_pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside_overlay + +# same as above, but with CYK code generation +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside + +# same as above, but with activated checkpointing +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk --checkpoint" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside + +# same as above, but with CYK code generation AND openMP parallelization +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk" +CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA -fopenmp" +LDLIBS_EXTRA="$DEFAULT_LDLIBS_EXTRA -fopenmp" +if [ $(uname) = "Darwin" ]; then + CPPFLAGS_EXTRA="$DEFAULT_CPPFLAGS_EXTRA -Xpreprocessor -fopenmp -lomp " + LDLIBS_EXTRA="$DEFAULT_LDLIBS_EXTRA -Xpreprocessor -fopenmp -lomp -I\"$(brew --prefix libomp)/include\" -L\"$(brew --prefix libomp)/lib\"" +fi +OMP_NUM_THREADS=2 +export OMP_NUM_THREADS +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside + +# same as above, but with activated checkpointing +GAPC="../../../gapc --outside_grammar weak --outside_grammar struct --cyk --checkpoint" +check_new_old_eq nodangle.gap unused pfunc "CCaCCaaaGGaCCaaaGGaCCaaaGGaGG" outside + +GAPC="../../../gapc --outside_grammar ALL" +CPPFLAGS_EXTRA="" +LDLIBS_EXTRA="" +check_new_old_eq hmm_sonneregen.gap unused count "SS" outside +check_new_old_eq hmm_sonneregen.gap unused fwd "SS" outside +check_new_old_eq hmm_sonneregen.gap unused fwd "SSRR" outside_ssrr + +# example in which inside and outside NTs have different dimensions +check_new_old_eq tmhmm_debug.gap unused count "AA" outside_report + +# example with multiple tracks for outside report function +check_new_old_eq_twotrack alignments.gap unused count "AAAA" outside_2track "BBB" +check_new_old_eq_twotrack alignments.gap unused sim_enum "AA" outside_undefvar "B" + +# example with parameterized terminals e.g. ROPE("manfred") +check_new_old_eq elmamun.gap unused count "1+2*3" outside_elm + +# check correct indices for multiple CONST_FLOAT args for outside generation; caused by incorrectly set yield size when replacing NTs +check_new_old_eq nonzero_constsize.gap unused count "G" outside_constissue + +# test if outside to inside transitions works also for constant non-terminal tables, i.e. those missing t_0_i t_0_j parameters which should be replaced via dummies in this one and only situation +check_new_old_eq constAxiom.gap unused enum "G" outside_out2in + +# check TMHMM outside with real sequence which previously revealed < 1.0 prob sums +CPPFLAGS_EXTRA=$DEFAULT_CPPFLAGS_EXTRA +check_new_old_eq tmhmm.gap unused fwd_scaled "MENLNMDLLYMAAAVMMGLAAIGAAIGIGILGGKFLEGAARQPDLIPLLRTQFFIVMGLVDAIPMIAVGLGLYVMFAVA" outside_tmhmm + +check_new_old_eq RFmini.gap unused enum "G" outside_cm +check_new_old_eq RFmini.gap unused count "G" outside_cm + +# Results can be converted into probabilities via nt_inside(i,j) + nt_outside(i,j) - axiom(0,n) - axiom(0,0) +# where axiom(0,0) is the pfunc value of the empty word. This words because we are in log2-space. +# Converted to probabilities: 2^nt_inside(i,j) * 2^nt_outside(i,j) / 2^axiom(0,n) / 2^axiom(0,0) +# The important aspect is that we have to also normalize by axiom(0,0) since the inside result of +# the empty word "" != 0 <-- log2-space but will be integrated in each and every outside candidate +check_new_old_eq RFmini.gap unused inside "G" outside_cm + +# more extensive example as before, also checked against cm_OutsideAlign of Infernal +GAPC="../../../gapc --outside_grammar state_MR_3 --outside_grammar state_MP_6 --outside_grammar state_S_0 --outside_grammar state_E_120" +check_new_old_eq RF00005.gap unused inside "GACGGUAU" outside_cm5 + +GAPC="../../../gapc --outside_grammar a_1 --outside_grammar a_47 --outside_grammar a_82" +# not yet explored +#check_new_old_eq acmsearch_RF00005.gap unused inside "GACGGUAU" outside_acm + +CPPFLAGS_EXTRA="" diff --git a/testdata/regresstest/run.sh b/testdata/regresstest/run.sh index a41e0c7eb..18300ddab 100755 --- a/testdata/regresstest/run.sh +++ b/testdata/regresstest/run.sh @@ -166,6 +166,35 @@ check_new_old_eq() rm -f string.o } +check_new_old_eq_twotrack() +{ + if [[ `echo $1$3$5 | grep $FILTER` != $1$3$5 ]]; then + return + fi + + # work around 1 sec timestamp filesystems ... WTF?!? + sleep 1 + + echo +------------------------------------------------------------------------------+ + failed=0 + temp=$failed + + cpp_base=${1%%.*} + build_cpp $GRAMMAR/$1 $cpp_base $3 + run_cpp_two_track $cpp_base $3 $4 $5 $6 + cmp_new_old_output $cpp_base $REF $3 $5 $6 + + if [ $temp != $failed ]; then + echo --++--FAIL--++-- + err_count=$((err_count+1)) + else + echo OK + succ_count=$((succ_count+1)) + fi + echo +------------------------------------------------------------------------------+ + rm -f string.o +} + run_check_feature() { out=$1.$2.$3.$4