From 55d7aeac9660c14479d0326248d2c698289ef998 Mon Sep 17 00:00:00 2001 From: Bardhyl Miftari <bmiftari@MacBook-Pro-de-Bardhyl.local> Date: Sun, 26 Mar 2023 20:00:04 +0200 Subject: [PATCH] version 0.1.7, rename deep, expr redef --- src/gboml/compiler/classes/condition.py | 8 ++++ src/gboml/compiler/classes/constraint.py | 8 ++++ src/gboml/compiler/classes/expression.py | 18 ++++++++ src/gboml/compiler/classes/link.py | 15 +++++-- src/gboml/compiler/classes/node.py | 31 +++++++++++++- src/gboml/compiler/classes/objective.py | 7 ++++ src/gboml/compiler/classes/time_obj.py | 6 +++ src/gboml/compiler/classes/variable.py | 12 ++++++ src/gboml/compiler/gboml_semantic.py | 12 ------ src/gboml/gboml_graph.py | 52 +++++++++++++++++++----- src/gboml/version.py | 2 +- test/test31_rename.txt | 30 ++++++++++++++ test/test_32_rename.txt | 8 ++++ 13 files changed, 180 insertions(+), 29 deletions(-) create mode 100644 test/test31_rename.txt create mode 100644 test/test_32_rename.txt diff --git a/src/gboml/compiler/classes/condition.py b/src/gboml/compiler/classes/condition.py index 9fb20f5..771ed66 100644 --- a/src/gboml/compiler/classes/condition.py +++ b/src/gboml/compiler/classes/condition.py @@ -79,6 +79,14 @@ class Condition(Type): return predicate + def rename_inside_expressions(self, new_name, old_name): + children = self.children + for child in children: + if isinstance(child, Expression): + child.rename_node_inside(new_name, old_name) + elif isinstance(child, Condition): + child.rename_inside_expressions(new_name, old_name) + def to_python_ast(self): import ast diff --git a/src/gboml/compiler/classes/constraint.py b/src/gboml/compiler/classes/constraint.py index d8ecf38..7613aef 100644 --- a/src/gboml/compiler/classes/constraint.py +++ b/src/gboml/compiler/classes/constraint.py @@ -114,3 +114,11 @@ class Constraint(Type): predicate = self.condition.check(definitions) return predicate + + def rename_inside_expressions(self, new_name, old_name): + self.rhs.rename_node_inside(new_name, old_name) + self.lhs.rename_node_inside(new_name, old_name) + if self.condition is not None: + self.condition.rename_inside_expressions(new_name, old_name) + if self.time_interval is not None: + self.time_interval.rename_inside_expressions(new_name, old_name) \ No newline at end of file diff --git a/src/gboml/compiler/classes/expression.py b/src/gboml/compiler/classes/expression.py index 877e55a..13ffa3c 100644 --- a/src/gboml/compiler/classes/expression.py +++ b/src/gboml/compiler/classes/expression.py @@ -523,6 +523,24 @@ class Expression(Symbol): return value + def rename_node_inside(self, new_name, old_name): + leafs = self.get_leafs() + for leaf in leafs: + type_id = leaf.get_type() + if type_id == "literal": + term = leaf.get_name() + if isinstance(term, Identifier): + node_name = term.get_node_name() + if node_name == old_name: + term.set_node_name(new_name) + if type_id == "sum": + expr_sum = leaf + expr_sum.get_time_interval().rename_inside_expressions(new_name, old_name) + if expr_sum.get_condition() is not None: + expr_sum.get_condition().rename_inside_expressions(new_name, old_name) + expr_sub_sum = expr_sum.get_children()[0] + expr_sub_sum.rename_node_inside(new_name, old_name) + def evaluate_python_string(self, definitions: dict): # Discard precedence information before returning prec, value = self.evaluate_python_string_impl(definitions) diff --git a/src/gboml/compiler/classes/link.py b/src/gboml/compiler/classes/link.py index 39b93ac..5f998c4 100644 --- a/src/gboml/compiler/classes/link.py +++ b/src/gboml/compiler/classes/link.py @@ -36,9 +36,18 @@ class Hyperedge: return self.name - def rename(self, new_name): - - self.name = new_name + def rename(self, new_name, old_name=""): + if old_name == "": + old_name = self.name + self.name = new_name + + for param in self.parameters: + expr = param.get_expression() + if expr is not None: + expr.rename_node_inside(new_name, old_name) + + for constraints in self.constraints: + constraints.rename_inside_expressions(new_name, old_name) def get_number_parameters(self): diff --git a/src/gboml/compiler/classes/node.py b/src/gboml/compiler/classes/node.py index 2c24a2d..6a6c521 100644 --- a/src/gboml/compiler/classes/node.py +++ b/src/gboml/compiler/classes/node.py @@ -191,8 +191,35 @@ class Node: return self.name - def rename(self, new_name): - self.name = new_name + def rename(self, new_name, old_name=""): + if old_name == "": + old_name = self.name + self.name = new_name + + for param in self.parameters_changes: + expr = param.get_expression() + if expr is not None: + expr.rename_node_inside(new_name, old_name) + + for param in self.parameters: + expr = param.get_expression() + if expr is not None: + expr.rename_node_inside(new_name, old_name) + + for var in self.variables: + var.rename_inside_expressions(new_name, old_name) + + for constraints in self.constraints: + constraints.rename_inside_expressions(new_name, old_name) + + for obj in self.objectives: + obj.rename_inside_expressions(new_name, old_name) + + for subnode in self.get_sub_nodes(): + subnode.rename(new_name, old_name) + + for subedge in self.get_sub_hyperedges(): + subedge.rename(new_name, old_name) def get_constraints(self): diff --git a/src/gboml/compiler/classes/objective.py b/src/gboml/compiler/classes/objective.py index e5f85ae..608d104 100644 --- a/src/gboml/compiler/classes/objective.py +++ b/src/gboml/compiler/classes/objective.py @@ -73,3 +73,10 @@ class Objective(Type): def get_time_interval(self): return self.time_interval + + def rename_inside_expressions(self, new_name, old_name): + self.expression.rename_node_inside(new_name, old_name) + if self.condition is not None: + self.condition.rename_inside_expressions(new_name, old_name) + if self.time_interval is not None: + self.time_interval.rename_inside_expressions(new_name, old_name) diff --git a/src/gboml/compiler/classes/time_obj.py b/src/gboml/compiler/classes/time_obj.py index 9d3ac2d..b163b80 100644 --- a/src/gboml/compiler/classes/time_obj.py +++ b/src/gboml/compiler/classes/time_obj.py @@ -296,6 +296,12 @@ class TimeInterval: return value + def rename_inside_expressions(self, new_name, old_name): + self.begin.rename_node_inside(new_name, old_name) + self.end.rename_node_inside(new_name, old_name) + if self.step is not None: + self.step.rename_node_inside(new_name, old_name) + def turn_name_to_python_expression(self): import ast name = ast.Name(id=self.name, ctx=ast.Store()) diff --git a/src/gboml/compiler/classes/variable.py b/src/gboml/compiler/classes/variable.py index 7c3b566..0be2bf1 100644 --- a/src/gboml/compiler/classes/variable.py +++ b/src/gboml/compiler/classes/variable.py @@ -107,3 +107,15 @@ class Variable(Symbol): assert vtype == "internal" or vtype == "external", \ "Internal error: unknown variable type" self.type = vtype + + def rename_inside_expressions(self, new_name, old_name): + identifier = self.get_identifier() + expr = identifier.get_expression() + if expr is not None: + expr.rename_node_inside(new_name, old_name) + + identifier_child = self.get_child_assignment() + if identifier_child is not None: + expr = identifier_child.get_expression() + if expr is not None: + expr.rename_node_inside(new_name, old_name) \ No newline at end of file diff --git a/src/gboml/compiler/gboml_semantic.py b/src/gboml/compiler/gboml_semantic.py index 532b129..11d44a4 100644 --- a/src/gboml/compiler/gboml_semantic.py +++ b/src/gboml/compiler/gboml_semantic.py @@ -121,18 +121,6 @@ def apply_changes_parameters(dictionary_of_parameters, parameters_changes): + str(new_parameter.get_line())) else: previous_parameter = dictionary_of_parameters[parameter_name] - new_parameter_type = new_parameter.get_type() - previous_parameter_type = previous_parameter.get_type() - if previous_parameter_type != new_parameter_type: - error_("ERROR : the redefinition of " + str(parameter_name) - + " does not match its previous type at lien: " - + str(new_parameter.get_line())) - - if new_parameter.get_number_of_values() != \ - previous_parameter.get_number_of_values(): - print("WARNING : unmatching length in redefinition" - " of parameter at line: " - + str(new_parameter.get_line())) dictionary_of_parameters[parameter_name] = new_parameter diff --git a/src/gboml/gboml_graph.py b/src/gboml/gboml_graph.py index 29f9b9f..f267c4e 100644 --- a/src/gboml/gboml_graph.py +++ b/src/gboml/gboml_graph.py @@ -497,26 +497,37 @@ class GbomlGraph: Returns: """ - parameter = None - if isinstance(value, Parameter): - parameter = value - elif isinstance(value, str): - parameter = Parameter(identifier, value) - elif isinstance(value, float) or isinstance(value, int): + parameter = self.create_parameter(identifier, value) + self.global_parameters.append(parameter) + + @staticmethod + def modify_parameter_value(parameter, value): + """ + Modify the value of parameter + + Args: + parameter (Parameter) : parameter to modify + value (int|float|list<float/int>) : value associated to the parameter + Returns: + + """ + if isinstance(value, float) or isinstance(value, int): expr = Expression('literal', value) - parameter = Parameter(identifier, expr) + parameter.expression = expr + parameter.type = "expression" + parameter.vector = None elif isinstance(value, list): expression_values = [] expr = None + parameter.expression = expr for val in value: expr = Expression('literal', val) expression_values.append(expr) - parameter = Parameter(identifier, None) + parameter.type = "table" parameter.set_vector(expression_values) else: error_("Unaccepted type value for global parameter " + str(type(value))) - self.global_parameters.append(parameter) @staticmethod def import_all_nodes_and_edges(filename): @@ -646,13 +657,32 @@ class GbomlGraph: Args: parameter_name (str) : parameter name - value (float/int) : value of parameter + value (float/int/list<int/float>) : value of parameter Returns: param (Parameter): parameter created """ - return Parameter(parameter_name, Expression("literal", value)) + parameter = None + if isinstance(value, Parameter): + parameter = value + elif isinstance(value, str): + parameter = Parameter(parameter_name, value) + elif isinstance(value, float) or isinstance(value, int): + expr = Expression('literal', value) + parameter = Parameter(parameter_name, expr) + elif isinstance(value, list): + expression_values = [] + expr = None + for val in value: + expr = Expression('literal', val) + expression_values.append(expr) + parameter = Parameter(parameter_name, None) + parameter.set_vector(expression_values) + else: + error_("Unaccepted type value for global parameter " + + str(type(value))) + return parameter @staticmethod def rename(node_or_hyperedge, new_name): diff --git a/src/gboml/version.py b/src/gboml/version.py index db8b3de..d428d30 100644 --- a/src/gboml/version.py +++ b/src/gboml/version.py @@ -8,4 +8,4 @@ The graph-based optimization modeling language (GBOML) version of the language. """ -__version__ = "0.1.6" +__version__ = "0.1.7" diff --git a/test/test31_rename.txt b/test/test31_rename.txt new file mode 100644 index 0000000..b951320 --- /dev/null +++ b/test/test31_rename.txt @@ -0,0 +1,30 @@ +#TIMEHORIZON T=10; + +#NODE SUPER +#PARAMETERS +capacity_factor = import "../examples/microgrid/pv_gen.csv"; + +#NODE SOLAR_PV_1 = import SOLAR_PV from "../examples/microgrid/microgrid.txt" with +capacity_factor = SUPER.capacity_factor; + +#NODE SOLAR_PV_2 = import SOLAR_PV from "../examples/microgrid/microgrid.txt" with +capacity_factor = SUPER.capacity_factor; + +#VARIABLES +internal: entity; + +#NODE Other +#PARAMETERS +a = 2; + + #NODE Inside + #PARAMETERS + b = 13; + #VARIABLES + internal: y[T]; + #CONSTRAINTS + y[i] == b for i in [0:Other.a]; + sum(y[i] for i in [Other.a:T-1-Other.a]) == b; + +#VARIABLES +internal: b; \ No newline at end of file diff --git a/test/test_32_rename.txt b/test/test_32_rename.txt new file mode 100644 index 0000000..949dfca --- /dev/null +++ b/test/test_32_rename.txt @@ -0,0 +1,8 @@ +#TIMEHORIZON T = 10; + +#NODE SUPER2 = import SUPER from "test31_rename.txt"; + +#NODE SUPER1 = import SUPER from "test31_rename.txt"; + +#NODE Other = import Other from "test31_rename.txt" with +a = 3; \ No newline at end of file -- GitLab