Skip to content

Commit

Permalink
Added linear expressions. To be tested
Browse files Browse the repository at this point in the history
  • Loading branch information
Kalashnikovni committed Jul 19, 2023
1 parent dc02536 commit 3a34d15
Show file tree
Hide file tree
Showing 30 changed files with 525 additions and 136 deletions.
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This new approach was used in the flatter and causalization stage of the Modelic

These are generic installation instructions.

## Dependences
## Dependencies

In order to be able to install and compile SBG Library,
the following dependencies must be installed:
Expand Down Expand Up @@ -79,9 +79,28 @@ The makefile script accepts the following targets:

* doc: Builds the documentation.

## SBG library

The SBG library is composed by four main modules:

* ast

* parser

* eval

* sbg

The first three were developed to allow for more user-friendly input. The first
three were developed to allow for more user-friendly input, and the last one
contains all the logical implementation of structures and operations.

## Examples:

The current version of the library counts with a parser for SBG programs. The syntax can be derived from the .cpp files of the /parser directory. In the /test folder several examples are presented, and they can be parsed or evaluated with the corresponding binary from the /bin directory. The `make test` command will evaluate all of the files and compare their results with the desired value stored in the /test/gt_data folder.
Examples of SBG programs are presented in the /test folder with the '.test'
extension. The bin/sbg-parser and bin/sbg-eval binaries accept these files as
their input. Also, the `make test` command in the root directory will execute
all of the existing tests.

## Licensing

Expand Down
20 changes: 20 additions & 0 deletions ast/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,26 @@ std::ostream &operator<<(std::ostream &out, const SetBinOp &i)
return out;
}

// Linear expression -----------------------------------------------------------

LinearExp::LinearExp() : slope_(), offset_() {}
LinearExp::LinearExp(Expr slope, Expr offset) : slope_(slope), offset_(offset) {}

member_imp(LinearExp, Expr, slope);
member_imp(LinearExp, Expr, offset);

bool LinearExp::operator==(const LinearExp &other) const
{
return slope() == other.slope() && offset() == other.offset();
}

std::ostream &operator<<(std::ostream &out, const LinearExp &le)
{
out << "(" << le.slope() << ")x+" << le.offset();

return out;
}

} // namespace AST

} // namespace SBG
18 changes: 16 additions & 2 deletions ast/expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#define PARSER_EXPR_AST_HPP

#include <boost/foreach.hpp>
#include <boost/optional.hpp>
#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>

Expand All @@ -48,6 +47,7 @@ struct Set;
struct SetUnaryOp;
struct SetBinOp;
struct BinOp;
struct LinearExp;
struct Call;

typedef boost::variant<Integer, Rational, Boolean, Util::VariableName,
Expand All @@ -58,7 +58,8 @@ typedef boost::variant<Integer, Rational, Boolean, Util::VariableName,
boost::recursive_wrapper<InterBinOp>,
boost::recursive_wrapper<Set>,
boost::recursive_wrapper<SetUnaryOp>,
boost::recursive_wrapper<SetBinOp>> Expr;
boost::recursive_wrapper<SetBinOp>,
boost::recursive_wrapper<LinearExp>> Expr;
typedef std::vector<Expr> ExprList;
std::ostream &operator<<(std::ostream &out, const ExprList &el);

Expand Down Expand Up @@ -175,6 +176,19 @@ struct SetBinOp {
};
std::ostream &operator<<(std::ostream &out, const SetBinOp &s);

// Linear expression -----------------------------------------------------------

struct LinearExp {
member_class(Expr, slope);
member_class(Expr, offset);

LinearExp();
LinearExp(Expr slope, Expr offset);

eq_class(LinearExp);
};
std::ostream &operator<<(std::ostream &out, const LinearExp &le);

} // namespace AST

} // namespace SBG
Expand Down
3 changes: 2 additions & 1 deletion eval/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ EVAL_SRC := \
$(VISIT_DIR)/stm_visitor.cpp \
$(VISIT_DIR)/program_visitor.cpp \
$(SBG_DIR)/interval.cpp \
$(SBG_DIR)/pw_inter.cpp
$(SBG_DIR)/pw_inter.cpp \
$(SBG_DIR)/lexp.cpp

# Objects
EVAL_OBJ=$(addprefix $(BUILD_DIR)/, $(EVAL_SRC:.cpp=.o))
Expand Down
8 changes: 4 additions & 4 deletions eval/defs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ void VarEnv::insert(VKey k, VValue v)
mapping_.insert(std::pair<VKey, VValue>(k, v));
}

Util::Option<VValue> VarEnv::operator[](VKey k) const
MaybeVValue VarEnv::operator[](VKey k) const
{
if (mapping_.find(k) == mapping_.end()) return Util::Option<VValue>();
if (mapping_.find(k) == mapping_.end()) return std::nullopt;
return mapping_.at(k);
}

FuncEnv::FuncEnv() {}
FuncEnvType FuncEnv::mapping_ = {{"isEmpty", 0}, {"isMember", 1}, {"minElem", 2}, {"maxElem", 3}, {"lt", 4}};

Util::Option<FValue> FuncEnv::operator[](FKey k) const
MaybeFValue FuncEnv::operator[](FKey k) const
{
if (mapping_.find(k) == mapping_.end()) return Util::Option<FValue>();
if (mapping_.find(k) == mapping_.end()) return std::nullopt;
return mapping_.at(k);
}

Expand Down
11 changes: 8 additions & 3 deletions eval/defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
#ifndef EVAL_DEFS_HPP
#define EVAL_DEFS_HPP

#include <map>
#include <tuple>
#include <variant>

#include <ast/expr.hpp>
#include <ast/statement.hpp>
#include <sbg/pw_inter.hpp>
#include <sbg/lexp.hpp>
#include <util/debug.hpp>
#include <util/defs.hpp>

Expand All @@ -41,7 +43,8 @@ namespace Eval {

// Type definitions ------------------------------------------------------------

typedef std::variant<Util::INT, Util::RATIONAL, SBG::Interval, SBG::Set> ExprBaseType;
typedef std::variant<Util::INT, Util::RATIONAL, SBG::Interval, SBG::Set, SBG::LExp> ExprBaseType;
typedef std::optional<ExprBaseType> MaybeEBT;

template <class T>
struct streamer {
Expand Down Expand Up @@ -80,12 +83,13 @@ Util::INT toInt(ExprBaseType t);
*/
typedef Util::VariableName VKey;
typedef ExprBaseType VValue;
typedef std::optional<VValue> MaybeVValue;
typedef std::map<VKey, VValue> VarEnvType;
struct VarEnv{
VarEnv();

void insert(VKey k, VValue v);
Util::Option<VValue> operator[](VKey k) const;
MaybeVValue operator[](VKey k) const;

private:
mutable VarEnvType mapping_;
Expand All @@ -101,11 +105,12 @@ struct VarEnv{
*/
typedef AST::Name FKey;
typedef int FValue;
typedef std::optional<FValue> MaybeFValue;
typedef std::map<FKey, FValue> FuncEnvType;
struct FuncEnv{
FuncEnv();

Util::Option<int> operator[](AST::Name) const;
MaybeFValue operator[](AST::Name) const;

private:
static FuncEnvType mapping_;
Expand Down
53 changes: 30 additions & 23 deletions eval/visitors/eval_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ ExprBaseType EvalExpression::operator()(AST::Boolean v) const { return v; }

ExprBaseType EvalExpression::operator()(Util::VariableName v) const
{
Util::Option<ExprBaseType> v_opt = env_[v];
MaybeEBT v_opt = env_[v];
if (v_opt)
return *v_opt;

Expand Down Expand Up @@ -151,35 +151,35 @@ ExprBaseType EvalExpression::operator()(AST::Call v) const
return 0;
}

ExprBaseType EvalExpression::operator()(AST::Interval i) const
ExprBaseType EvalExpression::operator()(AST::Interval v) const
{
EvalInt int_visit(env_);
Util::INT b = Apply(int_visit, i.begin());
Util::INT s = Apply(int_visit, i.step());
Util::INT e = Apply(int_visit, i.end());
Util::INT b = Apply(int_visit, v.begin());
Util::INT s = Apply(int_visit, v.step());
Util::INT e = Apply(int_visit, v.end());

return Interval(b, s, e);
}

ExprBaseType EvalExpression::operator()(AST::InterUnaryOp i) const
ExprBaseType EvalExpression::operator()(AST::InterUnaryOp v) const
{
AST::Expr exp = i.e();
AST::Expr exp = v.e();
EvalInterval eval_interval(env_);
switch (i.op()) {
switch (v.op()) {
case AST::ContainerUOp::card:
return cardinal(Apply(eval_interval, exp));

default:
Util::ERROR("EvalExpression: InterUnaryOp %s not supported.", AST::ContUOpNames[i.op()]);
Util::ERROR("EvalExpression: InterUnaryOp %s not supported.", AST::ContUOpNames[v.op()]);
return 0;
}
}

ExprBaseType EvalExpression::operator()(AST::InterBinOp i) const
ExprBaseType EvalExpression::operator()(AST::InterBinOp v) const
{
AST::Expr l = i.left(), r = i.right();
AST::Expr l = v.left(), r = v.right();
EvalInterval eval_interval(env_);
switch (i.op()) {
switch (v.op()) {
case AST::ContainerOp::cap:
return intersection(Apply(eval_interval, l), Apply(eval_interval, r));

Expand All @@ -190,44 +190,44 @@ ExprBaseType EvalExpression::operator()(AST::InterBinOp i) const
return Apply(eval_interval, l) == Apply(eval_interval, r);

default:
Util::ERROR("EvalExpression: InterBinOp %s not supported.", AST::ContOpNames[i.op()]);
Util::ERROR("EvalExpression: InterBinOp %s not supported.", AST::ContOpNames[v.op()]);
return 0;
}
}

ExprBaseType EvalExpression::operator()(AST::Set s) const
ExprBaseType EvalExpression::operator()(AST::Set v) const
{
SBG::InterSet res;
EvalInterval inter_visit(env_);

BOOST_FOREACH (auto i, s.pieces())
BOOST_FOREACH (auto i, v.pieces())
res.emplace(Apply(inter_visit, i));

return SBG::Set(res);
}

ExprBaseType EvalExpression::operator()(AST::SetUnaryOp s) const
ExprBaseType EvalExpression::operator()(AST::SetUnaryOp v) const
{
AST::Expr exp = s.e();
AST::Expr exp = v.e();
EvalSet eval_set(env_);
switch (s.op()) {
switch (v.op()) {
case AST::ContainerUOp::card:
return cardinal(Apply(eval_set, exp));

case AST::ContainerUOp::comp:
return complement(Apply(eval_set, exp));

default:
Util::ERROR("EvalExpression: SetUnaryOp %s not supported.", AST::ContUOpNames[s.op()]);
Util::ERROR("EvalExpression: SetUnaryOp %s not supported.", AST::ContUOpNames[v.op()]);
return 0;
}
}

ExprBaseType EvalExpression::operator()(AST::SetBinOp s) const
ExprBaseType EvalExpression::operator()(AST::SetBinOp v) const
{
AST::Expr l = s.left(), r = s.right();
AST::Expr l = v.left(), r = v.right();
EvalSet eval_set(env_);
switch (s.op()) {
switch (v.op()) {
case AST::ContainerOp::cap:
return intersection(Apply(eval_set, l), Apply(eval_set, r));

Expand All @@ -241,11 +241,18 @@ ExprBaseType EvalExpression::operator()(AST::SetBinOp s) const
return cup(Apply(eval_set, l), Apply(eval_set, r));

default:
Util::ERROR("EvalExpression: SetBinOp %s not supported.", AST::ContOpNames[s.op()]);
Util::ERROR("EvalExpression: SetBinOp %s not supported.", AST::ContOpNames[v.op()]);
return 0;
}
}

ExprBaseType EvalExpression::operator()(AST::LinearExp v) const
{
EvalRat visit_rat(env_);

return SBG::LExp(Apply(visit_rat, v.slope()), Apply(visit_rat, v.offset()));
}

} // namespace Eval

} // namespace SBG
13 changes: 7 additions & 6 deletions eval/visitors/eval_expr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ struct EvalExpression : public boost::static_visitor<ExprBaseType> {
ExprBaseType operator()(Util::VariableName v) const;
ExprBaseType operator()(AST::BinOp v) const;
ExprBaseType operator()(AST::Call v) const;
ExprBaseType operator()(AST::Interval i) const;
ExprBaseType operator()(AST::InterUnaryOp i) const;
ExprBaseType operator()(AST::InterBinOp i) const;
ExprBaseType operator()(AST::Set s) const;
ExprBaseType operator()(AST::SetUnaryOp s) const;
ExprBaseType operator()(AST::SetBinOp s) const;
ExprBaseType operator()(AST::Interval v) const;
ExprBaseType operator()(AST::InterUnaryOp v) const;
ExprBaseType operator()(AST::InterBinOp v) const;
ExprBaseType operator()(AST::Set v) const;
ExprBaseType operator()(AST::SetUnaryOp v) const;
ExprBaseType operator()(AST::SetBinOp v) const;
ExprBaseType operator()(AST::LinearExp v) const;

private:
mutable VarEnv env_;
Expand Down
Loading

0 comments on commit 3a34d15

Please sign in to comment.