From 900bc5926d1d0fea4670e501284b2c0f35b6802e Mon Sep 17 00:00:00 2001 From: kalashnikovni Date: Fri, 26 Jul 2024 15:05:19 -0300 Subject: [PATCH 1/2] Support for variables for lexp slopes --- parser/expr.cpp | 274 +++++++++++++++++++++++++++++------------ parser/sbg_program.cpp | 14 ++- parser/statement.cpp | 7 +- 3 files changed, 210 insertions(+), 85 deletions(-) diff --git a/parser/expr.cpp b/parser/expr.cpp index f2f7aea..ea653ae 100755 --- a/parser/expr.cpp +++ b/parser/expr.cpp @@ -23,47 +23,94 @@ BOOST_FUSION_ADAPT_STRUCT(SBG::Util::MD_NAT, (SBG::Util::VNAT, value_)) -BOOST_FUSION_ADAPT_STRUCT(SBG::Util::RATIONAL, (boost::rational, value_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::UnaryOp, (SBG::AST::UnOp, op_)(SBG::AST::Expr, expr_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::BinOp, (SBG::AST::Expr, left_)(SBG::AST::Op, op_)(SBG::AST::Expr, right_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::Call, (SBG::AST::Name, name_)(SBG::AST::ExprList, args_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::Interval, (SBG::AST::Expr, begin_)(SBG::AST::Expr, step_)(SBG::AST::Expr, end_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::InterUnaryOp, (SBG::AST::ContainerUOp, op_)(SBG::AST::Expr, e_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::InterBinOp, (SBG::AST::Expr, left_)(SBG::AST::ContainerOp, op_)(SBG::AST::Expr, right_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::MultiDimInter, (SBG::AST::ExprList, intervals_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::MDInterUnaryOp, (SBG::AST::ContainerUOp, op_)(SBG::AST::Expr, e_)) - -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::MDInterBinOp, (SBG::AST::Expr, left_)(SBG::AST::ContainerOp, op_)(SBG::AST::Expr, right_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::Util::RATIONAL, (boost::rational, value_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::UnaryOp, (SBG::AST::UnOp, op_)(SBG::AST::Expr, expr_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::BinOp + , (SBG::AST::Expr, left_)(SBG::AST::Op, op_)(SBG::AST::Expr, right_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::Call, (SBG::AST::Name, name_)(SBG::AST::ExprList, args_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::Interval + , (SBG::AST::Expr, begin_)(SBG::AST::Expr, step_)(SBG::AST::Expr, end_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::InterUnaryOp, (SBG::AST::ContainerUOp, op_)(SBG::AST::Expr, e_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::InterBinOp + , (SBG::AST::Expr, left_)(SBG::AST::ContainerOp, op_)(SBG::AST::Expr, right_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::MultiDimInter, (SBG::AST::ExprList, intervals_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::MDInterUnaryOp, (SBG::AST::ContainerUOp, op_)(SBG::AST::Expr, e_) +) + +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::MDInterBinOp + , (SBG::AST::Expr, left_)(SBG::AST::ContainerOp, op_)(SBG::AST::Expr, right_) +) BOOST_FUSION_ADAPT_STRUCT(SBG::AST::Set, (SBG::AST::ExprList, pieces_)) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::SetUnaryOp, (SBG::AST::ContainerUOp, op_)(SBG::AST::Expr, e_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::SetUnaryOp, (SBG::AST::ContainerUOp, op_)(SBG::AST::Expr, e_) +) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::SetBinOp, (SBG::AST::Expr, left_)(SBG::AST::ContainerOp, op_)(SBG::AST::Expr, right_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::SetBinOp + , (SBG::AST::Expr, left_)(SBG::AST::ContainerOp, op_)(SBG::AST::Expr, right_) +) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::LinearExp, (SBG::AST::Expr, slope_)(SBG::AST::Expr, offset_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::LinearExp, (SBG::AST::Expr, slope_)(SBG::AST::Expr, offset_) +) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::LExpBinOp, (SBG::AST::Expr, left_)(SBG::AST::ExpOp, op_)(SBG::AST::Expr, right_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::LExpBinOp + , (SBG::AST::Expr, left_)(SBG::AST::ExpOp, op_)(SBG::AST::Expr, right_) +) BOOST_FUSION_ADAPT_STRUCT(SBG::AST::MDLExp, (SBG::AST::ExprList, exps_)) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::MDLExpBinOp, (SBG::AST::Expr, left_)(SBG::AST::ExpOp, op_)(SBG::AST::Expr, right_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::MDLExpBinOp + , (SBG::AST::Expr, left_)(SBG::AST::ExpOp, op_)(SBG::AST::Expr, right_) +) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::LinearMap, (SBG::AST::Expr, dom_)(SBG::AST::Expr, lexp_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::LinearMap, (SBG::AST::Expr, dom_)(SBG::AST::Expr, lexp_) +) BOOST_FUSION_ADAPT_STRUCT(SBG::AST::PWLMap, (SBG::AST::ExprList, maps_)) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::SBG, (SBG::AST::Expr, V_)(SBG::AST::Expr, Vmap_)(SBG::AST::Expr, map1_)(SBG::AST::Expr, map2_)(SBG::AST::Expr, Emap_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::SBG + , (SBG::AST::Expr, V_)(SBG::AST::Expr, Vmap_) + (SBG::AST::Expr, map1_)(SBG::AST::Expr, map2_)(SBG::AST::Expr, Emap_) +) -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::DSBG, (SBG::AST::Expr, V_)(SBG::AST::Expr, Vmap_)(SBG::AST::Expr, mapB_)(SBG::AST::Expr, mapD_)(SBG::AST::Expr, Emap_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::DSBG + , (SBG::AST::Expr, V_)(SBG::AST::Expr, Vmap_) + (SBG::AST::Expr, mapB_)(SBG::AST::Expr, mapD_)(SBG::AST::Expr, Emap_) +) // Expression parser ----------------------------------------------------------- @@ -105,7 +152,9 @@ struct inter_unary_struct : qi::symbols { struct inter_bin_struct : qi::symbols { inter_bin_struct(){ - add("/\\", AST::ContainerOp::cap)("<", AST::ContainerOp::less)("==", AST::ContainerOp::eq); + add("/\\", AST::ContainerOp::cap) + ("<", AST::ContainerOp::less) + ("==", AST::ContainerOp::eq); } } inter_bin; @@ -133,7 +182,10 @@ struct set_unary_struct : qi::symbols { struct set_bin_struct : qi::symbols { set_bin_struct(){ - add("/\\", AST::ContainerOp::cap)("\\", AST::ContainerOp::diff)("==", AST::ContainerOp::eq)("\\/", AST::ContainerOp::cup); + add("/\\", AST::ContainerOp::cap) + ("\\", AST::ContainerOp::diff) + ("==", AST::ContainerOp::eq) + ("\\/", AST::ContainerOp::cup); } } set_bin; @@ -182,18 +234,27 @@ ExprRule::ExprRule(Iterator &it) : MAPB("mapB %="), MAPD("mapD %=") { - ident = qi::lexeme[(qi::char_('_') | qi::alpha) >> *(qi::alnum | qi::char_('_'))] - | qi::lexeme[qi::char_('\'') >> *(qi::alnum | qi::char_('_')) > qi::char_('\'')]; + ident = qi::lexeme[(qi::char_('_') + | qi::char_("a-zA-Z0-9")) >> *(qi::char_("a-zA-Z0-9") | qi::char_('_'))] + | qi::lexeme[qi::char_('\'') + >> *(qi::alnum | qi::char_('_')) > qi::char_('\'')]; boolean = TRUE[qi::_val = true] | FALSE[qi::_val = false]; - md_nat = OPAREN >> qi::lexeme[qi::ulong_long][phx::push_back(qi::_val, qi::_1)] - >> *(COMA >> qi::lexeme[qi::ulong_long])[phx::push_back(qi::_val, qi::_1)] >> CPAREN; + md_nat = OPAREN + >> qi::lexeme[qi::ulong_long][phx::push_back(qi::_val, qi::_1)] + >> *(COMA >> qi::lexeme[qi::ulong_long])[phx::push_back(qi::_val, qi::_1)] + >> CPAREN; - rational = (RAT >> OPAREN >> primary - >> COMA >> primary >> CPAREN)[qi::_val = phx::construct(qi::_1, qi::_2)]; + rational = (RAT + >> OPAREN + >> primary + >> COMA + >> primary + >> CPAREN)[qi::_val = phx::construct(qi::_1, qi::_2)]; - call_exp = (ident >> function_call_args)[qi::_val = phx::construct(qi::_1, qi::_2)]; + call_exp = (ident + >> function_call_args)[qi::_val = phx::construct(qi::_1, qi::_2)]; function_call_args = OPAREN >> expr_list >> CPAREN; @@ -204,61 +265,83 @@ ExprRule::ExprRule(Iterator &it) : | call_exp[qi::_val = qi::_1] | ident[qi::_val = qi::_1]; - factor = primary[qi::_val = qi::_1] >> -(expo_symbol > primary)[qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; + factor = primary[qi::_val = qi::_1] + >> -(expo_symbol > primary) + [qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; - term = factor[qi::_val = qi::_1] >> *(mult_symbol >> factor)[qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; + term = factor[qi::_val = qi::_1] + >> *(mult_symbol >> factor) + [qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; - arithmetic_expr = (term[qi::_val = qi::_1] >> *(add_symbols > term)[qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]) + arithmetic_expr = + (term[qi::_val = qi::_1] >> *(add_symbols > term) + [qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]) | (unary_symbol >> term)[qi::_val = phx::construct(qi::_1, qi::_2)]; // ------------ // interval = (OBRACKET - >> arithmetic_expr >> COLON - >> arithmetic_expr >> COLON - >> arithmetic_expr >> CBRACKET)[qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)] + >> arithmetic_expr >> COLON + >> arithmetic_expr >> COLON + >> arithmetic_expr >> CBRACKET) + [qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)] | ident[qi::_val = qi::_1]; - interval_unary = (inter_un >> interval_expr)[qi::_val = phx::construct(qi::_1, qi::_2)]; + interval_unary = (inter_un >> interval_expr) + [qi::_val = phx::construct(qi::_1, qi::_2)]; - interval_binary = (OPAREN >> interval_expr - >> inter_bin >> interval_expr - > CPAREN)[qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)]; + interval_binary = (OPAREN + >> interval_expr + >> inter_bin + >> interval_expr + > CPAREN) + [qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)]; interval_expr = interval_unary[qi::_val = qi::_1] | interval_binary[qi::_val = qi::_1] | interval[qi::_val = qi::_1]; - inter_list = interval[phx::push_back(qi::_val, qi::_1)] >> *(COMA >> interval)[phx::push_back(qi::_val, qi::_1)]; + inter_list = interval[phx::push_back(qi::_val, qi::_1)] + >> *(COMA >> interval)[phx::push_back(qi::_val, qi::_1)]; // ------------ // - inter_times = interval[phx::push_back(qi::_val, qi::_1)] >> *(DIMS >> interval)[phx::push_back(qi::_val, qi::_1)]; + inter_times = interval[phx::push_back(qi::_val, qi::_1)] + >> *(DIMS >> interval)[phx::push_back(qi::_val, qi::_1)]; md_inter = inter_times[qi::_val = phx::construct(qi::_1)]; - mdi_unary = (mdi_un >> mdi_expr)[qi::_val = phx::construct(qi::_1, qi::_2)]; + mdi_unary = (mdi_un >> mdi_expr) + [qi::_val = phx::construct(qi::_1, qi::_2)]; - mdi_binary = (OPAREN >> mdi_expr - >> mdi_bin >> mdi_expr - > CPAREN)[qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)]; + mdi_binary = (OPAREN + >> mdi_expr + >> mdi_bin + >> mdi_expr + > CPAREN) + [qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)]; mdi_expr = mdi_unary[qi::_val = qi::_1] | mdi_binary[qi::_val = qi::_1] | md_inter[qi::_val = qi::_1]; - mdi_list = md_inter[phx::push_back(qi::_val, qi::_1)] >> *(COMA >> md_inter)[phx::push_back(qi::_val, qi::_1)]; + mdi_list = md_inter[phx::push_back(qi::_val, qi::_1)] + >> *(COMA >> md_inter)[phx::push_back(qi::_val, qi::_1)]; // ------------ // - set = (OBRACE >> mdi_list >> CBRACE)[qi::_val = phx::construct(qi::_1)] + set = (OBRACE >> mdi_list >> CBRACE) + [qi::_val = phx::construct(qi::_1)] | (OBRACE >> CBRACE)[qi::_val = phx::construct()] | ident[qi::_val = qi::_1]; - set_unary = (set_un >> set_expr)[qi::_val = phx::construct(qi::_1, qi::_2)]; + set_unary = (set_un >> set_expr) + [qi::_val = phx::construct(qi::_1, qi::_2)]; - set_binary = (OPAREN >> set_expr - >> set_bin >> set_expr + set_binary = (OPAREN + >> set_expr + >> set_bin + >> set_expr > CPAREN)[qi::_val = phx::construct(qi::_1, qi::_2, qi::_3)]; set_expr = set_unary[qi::_val = qi::_1] @@ -267,27 +350,43 @@ ExprRule::ExprRule(Iterator &it) : // ------------ // - numeric = rational[qi::_val = qi::_1] | qi::lexeme[qi::ulong_long][qi::_val = phx::construct(qi::_1)]; - - lexp = (numeric >> qi::char_('*') >> qi::char_('x') - >> qi::char_('+') >> arithmetic_expr)[qi::_val = phx::construct(qi::_1, qi::_5)] - | (numeric >> qi::char_('*') >> qi::char_('x') - >> arithmetic_expr)[qi::_val = phx::construct(qi::_1, qi::_4)]; + numeric = rational[qi::_val = qi::_1] + | qi::lexeme[qi::ulong_long][qi::_val = phx::construct(qi::_1)] + | ident[qi::_val = qi::_1]; - lexp_binary = OPAREN >> lexp[qi::_val = qi::_1] >> CPAREN - >> *(lexp_bin > OPAREN >> lexp >> CPAREN)[qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; + lexp = (numeric + >> qi::char_('*') + >> qi::char_('x') + >> qi::char_('+') + >> arithmetic_expr) + [qi::_val = phx::construct(qi::_1, qi::_5)] + | (numeric + >> qi::char_('*') + >> qi::char_('x') + >> arithmetic_expr) + [qi::_val = phx::construct(qi::_1, qi::_4)]; + + lexp_binary = OPAREN + >> lexp[qi::_val = qi::_1] + >> CPAREN + >> *(lexp_bin > OPAREN >> lexp >> CPAREN) + [qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; lexp_expr = lexp[qi::_val = qi::_1] | lexp_binary[qi::_val = qi::_1]; // ------------ // - lexp_pipe = lexp[phx::push_back(qi::_val, qi::_1)] >> *(PIPE >> lexp)[phx::push_back(qi::_val, qi::_1)]; + lexp_pipe = lexp[phx::push_back(qi::_val, qi::_1)] + >> *(PIPE >> lexp)[phx::push_back(qi::_val, qi::_1)]; mdlexp = lexp_pipe[qi::_val = phx::construct(qi::_1)]; - mdlexp_binary = OPAREN >> mdlexp[qi::_val = qi::_1] >> CPAREN - >> *(mdlexp_bin > OPAREN >> mdlexp >> CPAREN)[qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; + mdlexp_binary = OPAREN + >> mdlexp[qi::_val = qi::_1] + >> CPAREN + >> *(mdlexp_bin > OPAREN >> mdlexp >> CPAREN) + [qi::_val = phx::construct(qi::_val, qi::_1, qi::_2)]; mdlexp_expr = mdlexp[qi::_val = qi::_1] | mdlexp_binary[qi::_val = qi::_1]; @@ -295,15 +394,18 @@ ExprRule::ExprRule(Iterator &it) : // ------------ // - sbgmap = (set_expr >> ARROW >> mdlexp_expr)[qi::_val = phx::construct(qi::_1, qi::_2)]; + sbgmap = (set_expr >> ARROW >> mdlexp_expr) + [qi::_val = phx::construct(qi::_1, qi::_2)]; map_expr = sbgmap; - map_list = sbgmap[phx::push_back(qi::_val, qi::_1)] >> *(COMA >> sbgmap)[phx::push_back(qi::_val, qi::_1)]; + map_list = sbgmap[phx::push_back(qi::_val, qi::_1)] + >> *(COMA >> sbgmap)[phx::push_back(qi::_val, qi::_1)]; // ------------ // - pwl = (OANGLE >> map_list >> CANGLE)[qi::_val = phx::construct(qi::_1)] + pwl = (OANGLE >> map_list >> CANGLE) + [qi::_val = phx::construct(qi::_1)] | (OANGLE >> CANGLE)[qi::_val = phx::construct()]; pwl_expr = pwl; @@ -311,10 +413,13 @@ ExprRule::ExprRule(Iterator &it) : // ------------ // sbg = (V >> set >> SEMI - >> VMAP >> pwl >> SEMI - >> MAP1 >> pwl >> SEMI - >> MAP2 >> pwl >> SEMI - >> EMAP >> pwl >> SEMI)[qi::_val = phx::construct(qi::_1, qi::_2, qi::_3, qi::_4, qi::_5)]; + >> VMAP >> pwl >> SEMI + >> MAP1 >> pwl >> SEMI + >> MAP2 >> pwl >> SEMI + >> EMAP >> pwl >> SEMI) + [qi::_val = phx::construct( + qi::_1, qi::_2, qi::_3, qi::_4, qi::_5 + )]; // ------------ // @@ -322,13 +427,26 @@ ExprRule::ExprRule(Iterator &it) : >> VMAP >> pwl >> SEMI >> MAPB >> pwl >> SEMI >> MAPD >> pwl >> SEMI - >> EMAP >> pwl >> SEMI)[qi::_val = phx::construct(qi::_1, qi::_2, qi::_3, qi::_4, qi::_5)]; + >> EMAP >> pwl >> SEMI) + [qi::_val = phx::construct( + qi::_1, qi::_2, qi::_3, qi::_4, qi::_5 + )]; // ------------ // - expr = dsbg | sbg | pwl_expr | map_expr | mdlexp_expr | lexp_expr | arithmetic_expr | set_expr | interval_expr | mdi_expr; + expr = dsbg + | sbg + | pwl_expr + | map_expr + | mdlexp_expr + | lexp_expr + | arithmetic_expr + | set_expr + | interval_expr + | mdi_expr; - expr_list = expr[phx::push_back(qi::_val, qi::_1)] >> *(COMA >> expr)[phx::push_back(qi::_val, qi::_1)]; + expr_list = expr[phx::push_back(qi::_val, qi::_1)] + >> *(COMA >> expr)[phx::push_back(qi::_val, qi::_1)]; exprs_comments = *(comment | expr); }; diff --git a/parser/sbg_program.cpp b/parser/sbg_program.cpp index 20a6f50..e463904 100755 --- a/parser/sbg_program.cpp +++ b/parser/sbg_program.cpp @@ -21,7 +21,12 @@ // Adapt structures ------------------------------------------------------------ - BOOST_FUSION_ADAPT_STRUCT(SBG::AST::Program, (SBG::Util::NAT, nmbr_dims_)(SBG::AST::StatementList, stms_)(SBG::AST::ExprList, exprs_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::Program + , (SBG::Util::NAT, nmbr_dims_) + (SBG::AST::StatementList, stms_) + (SBG::AST::ExprList, exprs_) +) // SBG program parser ---------------------------------------------------------- @@ -37,8 +42,11 @@ SBGProgramRule::SBGProgramRule(Iterator &it) : stm(it) { program_comments = (stm.stms_comments - >> expr.exprs_comments)[qi::_val = phx::construct(phx::construct(qi::_1), - phx::construct(qi::_2))]; + >> expr.exprs_comments) + [qi::_val = phx::construct( + phx::construct(qi::_1) + , phx::construct(qi::_2) + )]; }; template struct SBGProgramRule; diff --git a/parser/statement.cpp b/parser/statement.cpp index f70f7d1..51cf9f2 100755 --- a/parser/statement.cpp +++ b/parser/statement.cpp @@ -21,7 +21,9 @@ // Adapt structures ------------------------------------------------------------ -BOOST_FUSION_ADAPT_STRUCT(SBG::AST::Assign, (SBG::Util::VariableName, l_)(SBG::AST::Expr, r_)) +BOOST_FUSION_ADAPT_STRUCT( + SBG::AST::Assign, (SBG::Util::VariableName, l_)(SBG::AST::Expr, r_) +) BOOST_FUSION_ADAPT_STRUCT(SBG::AST::ConfigDims, (SBG::Util::NAT, nmbr_dims_)) @@ -39,9 +41,6 @@ StmRule::StmRule(Iterator &it) : ASSIGN("="), NMBR_DIMS("dims =") { - ident = qi::lexeme[(qi::char_('_') | qi::alpha) >> *(qi::alnum | qi::char_('_'))] - | qi::lexeme[qi::char_('\'') >> *(qi::alnum | qi::char_('_')) > qi::char_('\'')]; - cfg_dims = (NMBR_DIMS >> qi::uint_)[qi::_val = phx::construct(qi::_1)]; assign = (expr.ident >> ASSIGN >> expr.expr)[qi::_val = phx::construct(qi::_1, qi::_2)]; From 96c8b3858afe6ad061071f870f25eb32f0829aa6 Mon Sep 17 00:00:00 2001 From: kalashnikovni Date: Fri, 26 Jul 2024 17:33:05 -0300 Subject: [PATCH 2/2] Updated JSON output --- sbg/sbg_algorithms.cpp | 289 ++++++++++++++++++++++------------------- 1 file changed, 158 insertions(+), 131 deletions(-) diff --git a/sbg/sbg_algorithms.cpp b/sbg/sbg_algorithms.cpp index 117e8bb..dcd62c6 100644 --- a/sbg/sbg_algorithms.cpp +++ b/sbg/sbg_algorithms.cpp @@ -31,9 +31,7 @@ template PWMap connectedComponents(SBGraph g) { if (!g.V().isEmpty()) { - unsigned int dims = g.V().begin()->size(); - SBGMap id(g.V(), Exp(dims)); - PWMap rmap(id), old_rmap; + PWMap rmap(g.V()), old_rmap; if (g.E().isEmpty()) return rmap; @@ -197,7 +195,7 @@ void SBGMatching::directedMinReach(const PW &dir_map) dsbg.set_subE_map(subE_map); PWMap Vmap; - unsigned int j = 1, dims = dir_omap.nmbrDims(); + unsigned int j = 1, dims = dir_omap.arity(); for (SetPiece mdi : V) { Util::MD_NAT v(dims, j); Vmap.emplaceBack(SBGMap(mdi, Exp(v))); @@ -461,14 +459,14 @@ MatchInfo SBGMatching::calculate() if (debug()) Util::SBG_LOG << "minReachable: " << matched_E() << "\n\n"; - Util::SBG_LOG << MatchInfo(matched_E(), fullyMatchedU()) << "\n\n"; + Util::SBG_LOG << MatchInfo(matched_E().compact(), fullyMatchedU()) << "\n\n"; auto total = std::chrono::duration_cast( end - begin ); Util::SBG_LOG << "Total match exec time: " << total.count() << " [μs]\n"; - return MatchInfo(matched_E(), fullyMatchedU()); + return MatchInfo(matched_E().compact(), fullyMatchedU()); } // ----------------------------------------------------------------------------- @@ -518,6 +516,7 @@ PWMap SBGSCC::sccMinReach(DSBGraph dg) const Set V = dg.V(), E = dg.E(); PWMap mapB = dg.mapB(), mapD = dg.mapD(), subE_map = dg.subE_map(); + unsigned int copies = mapB.arity(); if (!V.isEmpty()) { PWMap rmap(V), old_rmap; @@ -535,6 +534,7 @@ PWMap SBGSCC::sccMinReach(DSBGraph dg) const if (debug()) Util::SBG_LOG << "scc rmap before rec: " << rmap << "\n"; + Set positive(SetPiece(copies, Interval(1, 1, Util::Inf))); PW rec_rmap; Set Vc = V.difference(old_rmap.equalImage(rmap)); for (const Map &subv : dg.Vmap()) { @@ -554,7 +554,6 @@ PWMap SBGSCC::sccMinReach(DSBGraph dg) const PW dmap; Set ith = rmap.image(VR), dom_VR; //Set visited, dom_vs; - unsigned int copies = mapB.nmbrDims(); Util::NAT dist = 0; // Calculate distance for vertices in same_rep that reach reps for (; dg.Vmap().restrict(dom_VR).sharedImage().isEmpty();) { @@ -569,7 +568,8 @@ PWMap SBGSCC::sccMinReach(DSBGraph dg) const dmap = dmap.restrict(VR); PW dmapB = dmap.composition(mapB), dmapD = dmap.composition(mapD); // Get edges where the end is closer to the rep that the beginning - Set not_cycle_edges = dmapB.gtImage(dmapD); + //Set not_cycle_edges = dmapB.gtImage(dmapD); + Set not_cycle_edges = (dmapB - dmapD).preImage(positive); ER = ER.intersection(not_cycle_edges); // Extend to subset-edge @@ -625,7 +625,7 @@ PWMap SBGSCC::sccStep() } PWMap auxVmap; - unsigned int j = 1, dims = id_V.nmbrDims(); + unsigned int j = 1, dims = id_V.arity(); for (SetPiece mdi : auxV) { Util::MD_NAT v(dims, j); auxVmap.emplaceBack(SBGMap(mdi, Exp(v))); @@ -689,115 +689,28 @@ PWMap SBGSCC::calculate() // ----------------------------------------------------------------------------- template -SBGTopSort::SBGTopSort() - : dsbg_(), smap_(), E_(), mapB_(), mapD_(), unordered_(), not_dependent_() - , visitedV_(), curr_(), debug_(false) {} +SBGTopSort::SBGTopSort() : dsbg_(), debug_(false) {} template -SBGTopSort::SBGTopSort(DSBGraph dsbg, bool debug) - : dsbg_(dsbg), smap_(), E_(dsbg.E()), mapB_(dsbg.mapB()), mapD_(dsbg.mapD()) - , unordered_(dsbg.V()), not_dependent_(), visitedV_(), curr_() - , debug_(debug) { - not_dependent_ = dsbg.V().difference(mapB().image()); - curr_ = not_dependent_.minElem(); -} +SBGTopSort::SBGTopSort(DSBGraph dsbg, bool debug) + : dsbg_(dsbg), debug_(debug) {} member_imp_temp(template, SBGTopSort, DSBGraph, dsbg); -member_imp_temp(template, SBGTopSort, PWMap, smap); -member_imp_temp(template, SBGTopSort, Set, E); -member_imp_temp(template, SBGTopSort, PWMap, mapB); -member_imp_temp(template, SBGTopSort, PWMap, mapD); -member_imp_temp(template, SBGTopSort, Set, unordered); -member_imp_temp(template, SBGTopSort, Set, not_dependent); -member_imp_temp(template, SBGTopSort, Set, visitedV); -member_imp_temp(template, SBGTopSort, Util::MD_NAT, curr); member_imp_temp(template, SBGTopSort, bool, debug); template -Exp SBGTopSort::calculateExp(Util::MD_NAT n1, Util::MD_NAT n2) +Exp SBGTopSort::calculateExp(Util::MD_NAT from, Util::MD_NAT to) { Exp res; Util::RATIONAL one(1, 1); - for (unsigned int j = 0; j < n1.size(); ++j) { - Util::RATIONAL x1(n1[j]), x2(n2[j]); - res.emplaceBack(LExp(1, x1 - x2)); + for (unsigned int j = 0; j < from.arity(); ++j) { + Util::RATIONAL r_from(from[j]), r_to(to[j]); + res.emplaceBack(LExp(1, r_to - r_from)); } return res; } -template -void SBGTopSort::topSortStep() -{ - Set nd = not_dependent(); - Util::MD_NAT next = nd.minElem(); - Set next_set(next), dom = next_set; - Exp exp = calculateExp(curr(), next); - set_curr(next); - - if (debug()) { - Util::SBG_LOG << "curr: " << curr() << "\n"; - Util::SBG_LOG << "dom: " << dom << "\n"; - Util::SBG_LOG << "exp: " << exp << "\n\n"; - } - - Set ingoing = mapD().preImage(dom); - updateStatus(dom, exp, ingoing); - - return; -} - -template -void SBGTopSort::updateStatus(Set dom, Exp exp, Set ingoing) -{ - PW Vmap = dsbg().Vmap(); - - Set newE = E(); - Set ith_dom = dom, new_unord = unordered(); - if (!dom.intersection(visitedV()).isEmpty()) { - Set dom_sv = Vmap.preImage(Vmap.image(dom)); - ith_dom = dom_sv.difference(smap().dom()); - - smap_ref().emplaceBack(SBGMap(ith_dom, exp)); - - // Take out vertices whose succ now also has a succ - Set no_succ = unordered().difference(smap().dom()); - Set whole_ord = smap().dom().difference(smap().preImage(no_succ)); - new_unord = new_unord.difference(whole_ord); - newE = newE.difference(mapD().preImage(whole_ord)); - } - else { - smap_ref().emplaceBack(SBGMap(dom, exp)); - } - new_unord = new_unord.difference(dom); - newE = newE.difference(mapD().preImage(dom)); - - Set SV = Vmap.preImage(Vmap.image(ith_dom)); - set_visitedV(visitedV().cup(SV)); - - set_E(newE); - set_mapB(mapB().restrict(E())); - set_mapD(mapD().restrict(E())); - - set_unordered(new_unord); - set_not_dependent(unordered().difference(mapB().image())); - - Set start = smap().dom().difference(smap().image()); - if (start.cardinal() == 1) - set_curr(start.minElem()); - - if (debug()) { - Util::SBG_LOG << "curr: " << curr() << "\n"; - Util::SBG_LOG << "smap: " << smap() << "\n"; - Util::SBG_LOG << "E: " << E() << "\n"; - Util::SBG_LOG << "unord: " << unordered() << "\n"; - Util::SBG_LOG << "nd: " << not_dependent() << "\n"; - Util::SBG_LOG << "visitedV: " << visitedV() << "\n\n"; - } - - return; -} - template PWMap SBGTopSort::calculate() { @@ -805,13 +718,56 @@ PWMap SBGTopSort::calculate() Util::SBG_LOG << "Topological sort dsbg:\n" << dsbg() << "\n\n"; auto begin = std::chrono::high_resolution_clock::now(); - Util::MD_NAT aux_curr = curr(); - Set curr_set(curr()); - Exp exp = calculateExp(curr(), curr()); - updateStatus(curr_set, exp, mapD().preImage(curr_set)); - set_curr(aux_curr); - while (!unordered().isEmpty()) - topSortStep(); + PW mapB = dsbg().mapB(), mapD = dsbg().mapD(), Vmap = dsbg().Vmap(), smap; + Set U = dsbg().V(), Nd = U.difference(mapB.image()); + Util::MD_NAT vsucc = Nd.minElem(); + Set SV, E = dsbg().E(); + do { + Set Nd_vsucc = Nd.intersection(Vmap.preImage(Vmap.image(vsucc))); + Util::MD_NAT v = Nd.minElem(); + if (!Nd_vsucc.isEmpty()) + v = Nd_vsucc.minElem(); + Set d(v); + Exp e = calculateExp(v, vsucc); + vsucc = v; + + Set SVd = Vmap.image(d); + bool cond = SVd.intersection(SV).isEmpty(); + if (!cond) { + Set dvs = Vmap.preImage(SVd); + for (const Map &map : smap.restrict(dvs)) { + if (e == map.exp()) { + d = dvs.difference(smap.dom()); + break; + } + } + } + smap.emplaceBack(Map(d, e)); + + Set Nsucc = U.difference(smap.dom()); + Set S = smap.dom().difference(smap.preImage(Nsucc)); + + E = E.difference(mapD.preImage(S)); + mapB = mapB.restrict(E); + mapD = mapD.restrict(E); + + U = U.difference(S); + Nd = U.difference(mapB.image()); + SV = SV.cup(Vmap.image(d)); + if (S == smap.dom()) { + Set start = smap.dom().difference(smap.image()); + if (!start.isEmpty()) + vsucc = start.minElem(); + } + + if (debug()) { + Util::SBG_LOG << "S: " << S << "\n"; + Util::SBG_LOG << "U: " << U << "\n"; + Util::SBG_LOG << "E: " << E << "\n"; + Util::SBG_LOG << "Nd: " << Nd << "\n"; + Util::SBG_LOG << "smap: " << smap << "\n\n"; + } + } while (!U.isEmpty()); auto end = std::chrono::high_resolution_clock::now(); auto total = std::chrono::duration_cast( @@ -820,9 +776,9 @@ PWMap SBGTopSort::calculate() Util::SBG_LOG << "Total topological sort exec time: " << total.count() << " [μs]\n\n"; if (debug()) - Util::SBG_LOG << "Topological sort result:\n" << smap().compact() << "\n\n"; + Util::SBG_LOG << "Topological sort result:\n" << smap.compact() << "\n\n"; - return smap().compact(); + return smap.compact(); } // Template instantiations ----------------------------------------------------- @@ -870,7 +826,7 @@ DSBGraph buildSCCFromMatching(const SBGMatching &match) PWMap mapD = matchedU_inv.composition(unmatchedU); mapD = mapD.compact(); - unsigned int j = 1, dims = Vmap.nmbrDims(); + unsigned int j = 1, dims = Vmap.arity(); PWMap Emap; for (const SBGMap &map1 : Vmap) { Set edges1 = mapB.preImage(map1.dom()); @@ -940,7 +896,7 @@ DSBGraph buildSortFromSCC( } PWMap Vmap; - unsigned int j = 1, dims = rmap.nmbrDims(); + unsigned int j = 1, dims = rmap.arity(); for (SetPiece mdi : V) { Util::MD_NAT v(dims, j); Vmap.emplaceBack(SBGMap(mdi, Exp(v))); @@ -969,37 +925,108 @@ DSBGraph buildSortFromSCC( template BaseDSBG buildSortFromSCC(const BaseSCC &scc, const BasePWMap &rmap); template CanonDSBG buildSortFromSCC(const CanonSCC &scc, const CanonPWMap &rmap); +template +rapidjson::Value setJson(const Set &s, rapidjson::Document::AllocatorType &alloc) +{ + rapidjson::Value res(rapidjson::kArrayType); + + for (const SetPiece &mdi : s) { + rapidjson::Value inter_array(rapidjson::kArrayType); + for (const Interval &i : mdi) { + rapidjson::Value inter(rapidjson::kArrayType); + + rapidjson::Value beg; + beg.SetInt(i.begin()); + inter.PushBack(beg, alloc); + rapidjson::Value st; + st.SetInt(i.step()); + inter.PushBack(st, alloc); + rapidjson::Value end; + end.SetInt(i.end()); + inter.PushBack(end, alloc); + + inter_array.PushBack(inter, alloc); + } + rapidjson::Value mdi_obj(rapidjson::kObjectType); + mdi_obj.AddMember("interval", inter_array, alloc); + res.PushBack(mdi_obj, alloc); + } + + return res; +} + +rapidjson::Value expJson(Exp exp, rapidjson::Document::AllocatorType &alloc) +{ + rapidjson::Value res(rapidjson::kArrayType); + + for (const LExp &le : exp) { + rapidjson::Value le_array(rapidjson::kArrayType); + + std::stringstream ssm; + ssm << le.slope(); + rapidjson::Value m; + m.SetString(ssm.str().c_str(), strlen(ssm.str().c_str()), alloc); + le_array.PushBack(m, alloc); + + std::stringstream ssh; + ssh << le.offset(); + rapidjson::Value h; + h.SetString(ssh.str().c_str(), strlen(ssh.str().c_str()), alloc); + le_array.PushBack(h, alloc); + + res.PushBack(le_array, alloc); + } + + return res; +} + +template +rapidjson::Value mapJson( + const PWMap &pw, rapidjson::Document::AllocatorType &alloc +) +{ + rapidjson::Value res(rapidjson::kArrayType); + + for (const SBGMap &map : pw) { + rapidjson::Value ith(rapidjson::kObjectType); + + ith.AddMember("dom", setJson(map.dom(), alloc), alloc); + ith.AddMember("exp", expJson(map.exp(), alloc), alloc); + + res.PushBack(ith, alloc); + } + + return res; +} + template void buildJson( const Set &matching, const PWMap &scc, const PWMap &order ) { - // 1. Parse a JSON string into DOM. - const char* json = "{\"matching\":\"\",\"scc\":\"\",\"order\":\"\"}"; + //const char* json = "{\"matching\":\"\",\"scc\":\"\",\"order\":\"\"}"; rapidjson::Document d; - d.Parse(json); + d.SetObject(); + rapidjson::Document::AllocatorType& alloc = d.GetAllocator(); - // 2. Modify it by DOM. - rapidjson::Value &m = d["matching"]; - std::stringstream ss1; - ss1 << matching; - m.SetString(ss1.str().c_str(), strlen(ss1.str().c_str()), d.GetAllocator()); + // Create matching information + rapidjson::Value edges = setJson(matching, alloc); + d.AddMember("matching", edges, alloc); - rapidjson::Value &s = d["scc"]; - std::stringstream ss2; - ss2 << scc; - s.SetString(ss2.str().c_str(), strlen(ss2.str().c_str()), d.GetAllocator()); + // Create SCC information + rapidjson::Value scc_rmap = mapJson(scc, alloc); + d.AddMember("scc", scc_rmap, alloc); - rapidjson::Value &o = d["order"]; - std::stringstream ss3; - ss3 << order; - o.SetString(ss3.str().c_str(), strlen(ss3.str().c_str()), d.GetAllocator()); + // Create sort information + rapidjson::Value order_rmap = mapJson(order, alloc); + d.AddMember("sort", order_rmap, alloc); - // 3. Stringify the DOM FILE *fp = fopen("output.json", "w"); char write_buffer[65536]; rapidjson::FileWriteStream os(fp, write_buffer, sizeof(write_buffer)); rapidjson::PrettyWriter writer(os); + rapidjson::PrettyFormatOptions opt = rapidjson::kFormatSingleLineArray; + writer.SetFormatOptions(opt); d.Accept(writer); fclose(fp);