scipplan 0.1.0a1__py2.py3-none-any.whl → 0.2.0a2__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
scipplan/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = "0.1.0alpha1"
1
+ __version__ = "0.2.0alpha2"
2
2
  print(f"SCIPPlan Version: {__version__}")
3
- __release__ = "v0.1.0"
3
+ __release__ = "v0.2.0a2"
4
4
  __author__ = "Ari Gestetner, Buser Say"
5
- __email__ = "ages0001@student.monash.edu, buser.say@monash.edu"
5
+ __email__ = "ari.gestetner@monash.edu, buser.say@monash.edu"
scipplan/config.py CHANGED
@@ -16,6 +16,7 @@ class Config:
16
16
  horizon: int = field(default=None)
17
17
  epsilon: float = field(default=None)
18
18
  gap: float = field(default=None)
19
+ provide_sols: bool = field(default=False)
19
20
  show_output: bool = False
20
21
  save_sols: bool = False
21
22
  bigM: float = 1000.0
@@ -32,17 +33,17 @@ class Config:
32
33
  "gap": False
33
34
  }
34
35
  if self.horizon is None:
35
- print("Horizon is not provided, and is set to 1")
36
+ print("Horizon is not provided, and is set to 1. ")
36
37
  self.horizon = 1
37
38
  self._defaults["horizon"] = True
38
39
 
39
40
  if self.epsilon is None:
40
- print("Epsilon is not provided, and is set to 0.1")
41
+ print("Epsilon is not provided, and is set to 0.1. ")
41
42
  self.epsilon = 0.1
42
43
  self._defaults["epsilon"] = True
43
44
 
44
45
  if self.gap is None:
45
- print("Gap is not provided, and is set to 10.0%")
46
+ print("Gap is not provided, and is set to 10.0%. ")
46
47
  self.gap = 0.1
47
48
  self._defaults["gap"] = True
48
49
 
@@ -50,6 +51,7 @@ class Config:
50
51
  text = f"""
51
52
  Configuration:
52
53
 
54
+ Use System of ODE's: {not self.provide_sols}
53
55
  Display SCIP Output: {self.show_output}
54
56
  Save Solutions: {self.show_output}
55
57
  Dt Variable Name: {self.dt_var}
@@ -64,9 +66,11 @@ class Config:
64
66
  return dedent(text)
65
67
 
66
68
  def increment_horizon(self, value: int = 1):
67
- self._defaults["horizon"] = False
69
+ # self._defaults["horizon"] = False
68
70
  self.horizon += value
69
71
 
72
+ def get_defaults(self) -> dict[str, bool]:
73
+ return self._defaults
70
74
 
71
75
  @classmethod
72
76
  def get_config(cls) -> Config:
@@ -78,14 +82,14 @@ class Config:
78
82
  "--domain",
79
83
  required=True,
80
84
  type=str,
81
- help="This variable is the name of the domain (e.g. pandemic or navigation)"
85
+ help="This variable is the name of the domain (e.g. pandemic or navigation)."
82
86
  )
83
87
  parser.add_argument(
84
88
  "-I",
85
89
  "--instance",
86
90
  required=True,
87
91
  type=str,
88
- help="This is the instance number of the domain (e.g. navigation has instances 1, 2 and 3)"
92
+ help="This is the instance number of the domain (e.g. navigation has instances 1, 2 and 3)."
89
93
  )
90
94
  parser.add_argument(
91
95
  "-H",
@@ -93,7 +97,7 @@ class Config:
93
97
  required=False,
94
98
  # default=1,
95
99
  type=int,
96
- help="The initial horizon. The solve method will initially begin with this horizon until it finds a feasible solution"
100
+ help="The initial horizon. The solve method will initially begin with this horizon until it finds a feasible solution."
97
101
  )
98
102
  parser.add_argument(
99
103
  "-E",
@@ -101,7 +105,7 @@ class Config:
101
105
  required=False,
102
106
  # default=0.1,
103
107
  type=float,
104
- help="SCIPPlan iteratively checks solution for violations at each epsilon value"
108
+ help="SCIPPlan iteratively checks solution for violations at each epsilon value."
105
109
  )
106
110
  parser.add_argument(
107
111
  "-G",
@@ -109,7 +113,7 @@ class Config:
109
113
  required=False,
110
114
  # default=0.1,
111
115
  type=float,
112
- help="SCIP will search for solution with an optimality gap by at least this value"
116
+ help="SCIP will search for solution with an optimality gap by at least this value."
113
117
  )
114
118
 
115
119
  parser.add_argument(
@@ -117,7 +121,7 @@ class Config:
117
121
  required=False,
118
122
  default=1000.0,
119
123
  type=float,
120
- help="A large value which is used for some constraint encoding formulations, defaults to 1000.0 and can be changed as needed"
124
+ help="A large value which is used for some constraint encoding formulations, defaults to 1000.0 and can be changed as needed."
121
125
  )
122
126
 
123
127
  parser.add_argument(
@@ -125,21 +129,28 @@ class Config:
125
129
  required=False,
126
130
  default="Dt",
127
131
  type=str,
128
- help="When writing the constraints, dt_var is the variable name for Dt, defaults to 'Dt' and can be changed based on users preference (e.g. 'dt')"
132
+ help="When writing the constraints, dt_var is the variable name for Dt, defaults to 'Dt' and can be changed based on users preference (e.g. 'dt')."
129
133
  )
130
134
 
135
+ parser.add_argument(
136
+ "--provide-sols",
137
+ action="store_true",
138
+ default=False,
139
+ help="This flag determines whether the user would like to provide a system of odes or solution equations, odes must be provided by default."
140
+ )
141
+
131
142
  parser.add_argument(
132
143
  "--show-output",
133
144
  action="store_true",
134
145
  default=False,
135
- help="Include this flag to show output from SCIP"
146
+ help="Include this flag to show output from SCIP."
136
147
  )
137
148
 
138
149
  parser.add_argument(
139
150
  "--save-sols",
140
151
  action="store_true",
141
152
  default=False,
142
- help="Include this flag to save the solutions from each of the scipplan iterations as well as constraints generated (note, only saves for horizon which has been solved)"
153
+ help="Include this flag to save the solutions from each of the scipplan iterations as well as constraints generated (note, only saves for horizon which has been solved)."
143
154
  )
144
155
 
145
156
  args = parser.parse_args()
scipplan/helpers.py CHANGED
@@ -2,6 +2,7 @@ import os
2
2
  import csv
3
3
 
4
4
  from typing import Generator
5
+
5
6
  from .config import Config
6
7
 
7
8
  class InfeasibilityError(Exception):
scipplan/plan_model.py CHANGED
@@ -5,10 +5,14 @@ from .helpers import list_accessible_files
5
5
 
6
6
  import math
7
7
  import os
8
+ import re
8
9
 
9
10
  from pyscipopt.scip import Model
10
11
  from pkg_resources import parse_version
11
12
  from importlib.metadata import version
13
+ from sympy import Eq, Function, Derivative as dd, Symbol, parse_expr
14
+ from sympy.solvers.ode.systems import dsolve_system
15
+
12
16
 
13
17
  if parse_version(version("pyscipopt")) >= parse_version("4.3.0"):
14
18
  from pyscipopt import quicksum, exp, log, sqrt, sin, cos
@@ -27,6 +31,8 @@ class PlanModel:
27
31
  # Translation -> line_num -> horizon -> aux
28
32
  self.aux_vars: dict[str, list[list[list]]] = {}
29
33
 
34
+ self.file_translations = self.read_translations()
35
+
30
36
  self.constants = self.encode_constants()
31
37
  self.variables = self.encode_pvariables()
32
38
  self.translations = self.encode_constraints()
@@ -39,8 +45,27 @@ class PlanModel:
39
45
  self.model.addCons(dt_var >= 0.0, f"dt_{h}_lower_bound")
40
46
  self.model.addCons(dt_var <= self.config.bigM, f"dt_{h}_upper_bound")
41
47
 
42
-
48
+ def read_translations(self) -> dict[str, list[str]]:
49
+ with open(self.get_file_path("solutions" if self.config.provide_sols else "odes")) as f:
50
+ translations = {}
51
+ new_sec = True
52
+ for line in f:
53
+ line = line.strip()
54
+ if line == "":
55
+ pass
56
+ elif line == "---":
57
+ new_sec = True
58
+ elif new_sec is True:
59
+ translation = line.removesuffix(":")
60
+ translations[translation] = []
61
+ new_sec = False
62
+ else:
63
+ translations[translation].append(line)
43
64
 
65
+ return translations
66
+
67
+
68
+
44
69
  def encode_constants(self) -> dict[str, float]:
45
70
  constants = {}
46
71
  translation = "constants"
@@ -53,23 +78,20 @@ class PlanModel:
53
78
  }
54
79
 
55
80
 
56
- with open(self.get_file_path(translation)) as f:
57
- for line in f.readlines():
58
- if line.strip() == "":
59
- continue
60
-
61
- var, val = line.strip().split("=")
62
- var, val = var.strip(), val.strip()
63
-
64
- val = val if val not in config_vals else config_vals[val]
65
-
66
- try:
67
- val = float(val)
68
- except ValueError:
69
- raise ValueError("Constants can only be floats, please reconfigure: ")
70
-
71
- constants[var] = val
72
- self.var_names.add(var)
81
+ for line in self.file_translations[translation]:
82
+
83
+ var, val = line.split("=")
84
+ var, val = var.strip(), val.strip()
85
+
86
+ val = val if val not in config_vals else config_vals[val]
87
+
88
+ try:
89
+ val = float(val)
90
+ except ValueError:
91
+ raise ValueError("Constants can only be floats, please reconfigure: ")
92
+
93
+ constants[var] = val
94
+ self.var_names.add(var)
73
95
 
74
96
  constants["bigM"] = self.config.bigM
75
97
  self.var_names.add("bigM")
@@ -84,22 +106,21 @@ class PlanModel:
84
106
  var_type = variables[(constant, t)].var_type
85
107
 
86
108
  translation = "pvariables"
87
- with open(self.get_file_path(translation)) as f:
88
- for line in f.readlines():
89
-
90
- var = line.rstrip("\n").strip()
91
- if var == "":
92
- continue
93
- vtype, name = var.split(": ")
94
- vtype, name = vtype.strip(), name.strip()
95
-
96
- self.var_names.add(name)
97
-
98
- for t in range(self.config.horizon):
99
- variables[(name, t)] = Variable.create_var(self.model, name, vtype, t, self.constants)
100
- var_type = variables[(name, t)].var_type
101
- if var_type is VarType.STATE:
102
- variables[(name, self.config.horizon)] = Variable.create_var(self.model, name, vtype, self.config.horizon, self.constants)
109
+ for line in self.file_translations[translation]:
110
+
111
+ var = line.rstrip("\n").strip()
112
+ if var == "":
113
+ continue
114
+ vtype, name = var.split(": ")
115
+ vtype, name = vtype.strip(), name.strip()
116
+
117
+ self.var_names.add(name)
118
+
119
+ for t in range(self.config.horizon):
120
+ variables[(name, t)] = Variable.create_var(self.model, name, vtype, t, self.constants)
121
+ var_type = variables[(name, t)].var_type
122
+ if var_type is VarType.STATE:
123
+ variables[(name, self.config.horizon)] = Variable.create_var(self.model, name, vtype, self.config.horizon, self.constants)
103
124
 
104
125
  return variables
105
126
 
@@ -111,24 +132,40 @@ class PlanModel:
111
132
  "instantaneous_constraints",
112
133
  "temporal_constraints",
113
134
  "goals",
114
- "transitions"
135
+ "odes" if self.config.provide_sols is False else "transitions"
115
136
  ]
116
137
  translations: dict[str, list[str]] = {}
117
138
  for translation in translation_names:
118
139
  translations[translation] = []
119
140
 
120
- with open(self.get_file_path(translation)) as f:
121
- for line in f.readlines():
122
- expr = line.rstrip("\n").strip()
123
- # If line is empty don't append
124
- if expr == "":
125
- continue
126
-
127
- translations[translation].append(expr)
141
+ for line in self.file_translations[translation]:
142
+ expr = line.rstrip("\n").strip()
143
+ # If line is empty don't append
144
+ if expr == "":
145
+ continue
146
+
147
+ translations[translation].append(expr)
148
+
149
+ if self.config.provide_sols is False:
150
+ self.ode_functions = self.solve_odes(translations["odes"])
151
+
152
+ translations["transitions"] = []
153
+ for func_name, func in self.ode_functions.items():
154
+ translations["transitions"].append((func_name + "_dash" + " == " + func))
128
155
 
156
+ del translations["odes"]
157
+
158
+
129
159
  # Encode constraints into model
130
160
  for cons_idx, (translation, constraints) in enumerate(translations.items()):
131
161
  for idx, constraint in enumerate(constraints):
162
+ if (self.config.provide_sols is False) and (translation == "temporal_constraints"):
163
+ # for func_name, func in self.ode_functions.items():
164
+ # constraint = constraint.replace(func_name, func)
165
+ pattern = r"|".join(f"({func_name})" for func_name, func in self.ode_functions.items())
166
+ constraint = re.sub(pattern, lambda x: self.ode_functions[x.group(0)], constraint)
167
+ constraints[idx] = constraint
168
+
132
169
  if translation == "initials":
133
170
  exprs = PM(self.get_parser_params(horizon=0, add_aux_vars=True)).evaluate(constraint, horizon=0, expr_name=f"{translation}_{idx}_0")
134
171
 
@@ -165,16 +202,15 @@ class PlanModel:
165
202
  def encode_reward(self):
166
203
  objectives = [None] * self.config.horizon
167
204
  translation = "reward"
168
- with open(self.get_file_path(translation)) as f:
169
- reward = f.readline().rstrip("\n")
170
- for t in range(self.config.horizon):
171
- objectives[t] = self.model.addVar(f"Obj_{t}", vtype="C", lb=None, ub=None)
172
- # For the sake of similarity the reward is similar to constraint parsing, however, only one reward function is allowed
173
- exprs = PM(self.get_parser_params(t)).evaluate(reward)
174
- for expr_idx, expr in enumerate(exprs):
175
- self.model.addCons(objectives[t] == expr, f"Obj_{t}_{expr_idx}")
176
-
177
- self.model.setObjective(quicksum(objectives), "maximize")
205
+ reward = self.file_translations[translation][0]
206
+ for t in range(self.config.horizon):
207
+ objectives[t] = self.model.addVar(f"Obj_{t}", vtype="C", lb=None, ub=None)
208
+ # For the sake of similarity the reward is similar to constraint parsing, however, only one reward function is allowed
209
+ exprs = PM(self.get_parser_params(t)).evaluate(reward)
210
+ for expr_idx, expr in enumerate(exprs):
211
+ self.model.addCons(objectives[t] == expr, f"Obj_{t}_{expr_idx}")
212
+
213
+ self.model.setObjective(quicksum(objectives), "maximize")
178
214
 
179
215
  return objectives
180
216
 
@@ -254,4 +290,47 @@ class PlanModel:
254
290
  return os.path.join(pkg_files_path, path)
255
291
  else:
256
292
  raise Exception("Unkown file name, please enter a configuration for a valid domain instance in translation: ")
257
-
293
+
294
+
295
+ def solve_odes(self, ode_system: list[str]) -> dict[str, str]:
296
+ dt_var = self.config.dt_var
297
+
298
+ dt = Symbol(dt_var)
299
+ # Used to represent constant variables
300
+ temp_var = Symbol("TEMP_VAR")
301
+
302
+ variables = {}
303
+ states = []
304
+
305
+ for var_name in self.var_names:
306
+ var = self.variables[(var_name, 0)]
307
+ if var.var_type is VarType.STATE:
308
+ states.append(var.name)
309
+ variables[var.name] = Function(var.name)(dt)
310
+ elif var.var_type is VarType.CONSTANT:
311
+ variables[var.name] = self.constants[var.name]
312
+ else: # the variable is an action or aux variable which is encoded as a function of some unused variable as workaround to not being able to use symbols for constants
313
+ variables[var.name] = Function(var.name)(temp_var)
314
+
315
+ variables[dt_var] = dt
316
+
317
+ system = []
318
+ for eqtn in ode_system:
319
+ lhs, rhs = eqtn.split("==")
320
+ lhs = parse_expr(lhs.strip(), local_dict=variables | {"dd": dd})
321
+ rhs = parse_expr(rhs.strip(), local_dict=variables | {"dd": dd})
322
+ system.append(Eq(lhs, rhs))
323
+ results = dsolve_system(system, ics={variables[state].subs(dt, 0): state for state in states})
324
+
325
+
326
+
327
+ functions: dict[str, str] = {}
328
+ for eqtn in results[0]:
329
+ new_eqtn = eqtn.doit()
330
+ func_name = new_eqtn.lhs.name.replace(f"({temp_var.name})", "").replace(f"({self.config.dt_var})", "_dash")
331
+ functions[func_name] = str(new_eqtn.rhs).replace(f"({temp_var.name})", "").replace(f"({self.config.dt_var})", "_dash")
332
+
333
+
334
+ return functions
335
+
336
+
scipplan/scipplan.py CHANGED
@@ -46,6 +46,8 @@ class SCIPPlan:
46
46
  def optimize(self):
47
47
  iteration = 0
48
48
 
49
+ const_gen_aux_vars = [[None] * self.config.horizon for _ in range(len(self.plan.translations["temporal_constraints"]))]
50
+
49
51
  while True:
50
52
  self.scip_model.optimize()
51
53
 
@@ -80,10 +82,15 @@ class SCIPPlan:
80
82
 
81
83
  for idx, constraint in enumerate(self.plan.translations["temporal_constraints"]):
82
84
  t = zero_cross.horizon
83
- aux_vars = self.plan.aux_vars["temporal_constraints"][idx][t]
84
- params = self.plan.get_parser_params(horizon=t)
85
+ # aux_vars = self.plan.aux_vars["temporal_constraints"][idx][t]
86
+ aux_vars = const_gen_aux_vars[idx][t]
87
+ # Only add aux vars if there are no aux vars added for the secific constraint
88
+ params = self.plan.get_parser_params(horizon=t, add_aux_vars=aux_vars is None)
85
89
  params.variables[self.config.dt_var] *= zero_cross.coef
86
90
  exprs = PM(params).evaluate(constraint, aux_vars=aux_vars)
91
+ if const_gen_aux_vars[idx][t] is None:
92
+ const_gen_aux_vars[idx][t] = exprs.aux_vars
93
+
87
94
  for eqtn_idx, eqtn in enumerate(exprs):
88
95
  self.plan.model.addCons(eqtn, f"{constraint}_{idx}_{eqtn_idx}")
89
96
 
@@ -130,9 +137,10 @@ class SCIPPlan:
130
137
 
131
138
  @classmethod
132
139
  def solve(cls, config: Config) -> tuple[SCIPPlan, float]:
140
+ # Time total solve time including incrementing horizon
141
+ start_time = time.time()
133
142
  while True:
134
143
  model = SCIPPlan(config)
135
- start_time = time.time()
136
144
  try:
137
145
  print(f"Encoding the problem over horizon h={config.horizon}.")
138
146
  print("Solving the problem.")
@@ -144,12 +152,21 @@ class SCIPPlan:
144
152
  return model, solve_time
145
153
 
146
154
 
147
- except InfeasibilityError:
155
+ except InfeasibilityError:
156
+ if config.get_defaults().get("horizon") is False:
157
+ print(f"Horizon of h={model.config.horizon} is infeasible.")
158
+
159
+ solve_time = (time.time() - start_time)
160
+ print(f"Total time: {solve_time:.3f}")
161
+
162
+ raise InfeasibilityError
163
+
164
+
148
165
  # print("Problem is infeasible for the given horizon.")
149
- print(f"Horizon of h={model.config.horizon} is infeasible, incrementing to h={model.config.horizon + 1}")
166
+ print(f"Horizon of h={model.config.horizon} is infeasible, incrementing to h={model.config.horizon + 1}.")
150
167
  config.increment_horizon()
151
168
  if config.show_output is True:
152
- print(f"Horizon Time: {(time.time() - start_time): .3f} seconds")
169
+ print(f"Horizon Time: {(time.time() - start_time): .3f} seconds.")
153
170
 
154
171
 
155
172
  def save_values(self, iteration: int):
@@ -162,8 +179,11 @@ def main():
162
179
  print(f"PySCIPOpt Version: {version('pyscipopt')}\n")
163
180
  config = Config.get_config()
164
181
  print(config)
165
-
166
- plan, solve_time = SCIPPlan.solve(config)
182
+
183
+ try:
184
+ plan, solve_time = SCIPPlan.solve(config)
185
+ except InfeasibilityError:
186
+ return None
167
187
 
168
188
  if config.save_sols is True:
169
189
  write_to_csv("new_constraints", plan.new_constraints, config)
@@ -185,9 +205,9 @@ def main():
185
205
  for action_name in action_names:
186
206
  if action_name == config.dt_var:
187
207
  continue
188
- print(f"{action_name} at step {step} by value {plan.scip_model.getVal(plan.plan.variables[(action_name, step)].model_var):.3f}")
208
+ print(f"{action_name} at step {step} by value {plan.scip_model.getVal(plan.plan.variables[(action_name, step)].model_var):.3f}.")
189
209
 
190
- print(f"Dt at step {step} by value {plan.scip_model.getVal(plan.plan.variables[('Dt', step)].model_var):.3f} \n")
210
+ print(f"Dt at step {step} by value {plan.scip_model.getVal(plan.plan.variables[('Dt', step)].model_var):.3f}. \n")
191
211
 
192
212
  print(f"Total reward: {(plan.scip_model.getObjVal()):.3f}")
193
213
  print(f"Total time: {solve_time:.3f}")
@@ -0,0 +1,50 @@
1
+ constants:
2
+ Epsilon = config_epsilon
3
+ bigM = config_bigM
4
+ ---
5
+ pvariables:
6
+ action_continuous: Accelerate_x
7
+ action_continuous: Accelerate_y
8
+ action_continuous: Dt
9
+ state_continuous: Location_x
10
+ state_continuous: Location_y
11
+ state_continuous: Speed_x
12
+ state_continuous: Speed_y
13
+ ---
14
+ odes:
15
+ dd(Location_x, Dt) == Speed_x
16
+ dd(Location_y, Dt) == Speed_y
17
+ dd(Speed_x, Dt) == Accelerate_x
18
+ dd(Speed_y, Dt) == Accelerate_y
19
+ ---
20
+ initials:
21
+ Location_x == 0.0
22
+ Location_y == 0.0
23
+ Speed_x == 0.0
24
+ Speed_y == 0.0
25
+ ---
26
+ instantaneous_constraints:
27
+ Location_x <= 10.0
28
+ Location_y <= 10.0
29
+ Location_x >= 0.0
30
+ Location_y >= 0.0
31
+ Accelerate_x <= 0.5
32
+ Accelerate_y <= 0.5
33
+ Accelerate_x >= -0.5
34
+ Accelerate_y >= -0.5
35
+ (Location_x <= 4.0) or (Location_x >= 6.0) or (Location_y <= 4.0) or (Location_y >= 6.0)
36
+ ---
37
+ temporal_constraints:
38
+ Location_x <= 10.0
39
+ Location_y <= 10.0
40
+ Location_x >= 0.0
41
+ Location_y >= 0.0
42
+
43
+ (Location_x <= 4.0) or (Location_x >= 6.0) or (Location_y <= 4.0) or (Location_y >= 6.0)
44
+ ---
45
+ goals:
46
+ Location_x == 8.0
47
+ Location_y == 8.0
48
+ ---
49
+ reward:
50
+ -1.0*(Dt)
@@ -0,0 +1,51 @@
1
+ constants:
2
+ Epsilon = config_epsilon
3
+ bigM = config_bigM
4
+ ---
5
+ pvariables:
6
+ action_continuous: Accelerate_x
7
+ action_continuous: Accelerate_y
8
+ action_continuous: Dt
9
+ state_continuous: Location_x
10
+ state_continuous: Location_y
11
+ state_continuous: Speed_x
12
+ state_continuous: Speed_y
13
+ ---
14
+ odes:
15
+ dd(Location_x, Dt) == Speed_x
16
+ dd(Location_y, Dt) == Speed_y
17
+ dd(Speed_x, Dt) == Accelerate_x
18
+ dd(Speed_y, Dt) == Accelerate_y
19
+ ---
20
+ initials:
21
+ Location_x == 0.0
22
+ Location_y == 0.0
23
+ Speed_x == 0.0
24
+ Speed_y == 0.0
25
+ ---
26
+ instantaneous_constraints:
27
+ Location_x <= 10.0
28
+ Location_y <= 10.0
29
+ Location_x >= 0.0
30
+ Location_y >= 0.0
31
+ Accelerate_x <= 0.5
32
+ Accelerate_y <= 0.5
33
+ Accelerate_x >= -0.5
34
+ Accelerate_y >= -0.5
35
+ (Location_x <= 2.0) or (Location_x >= 4.0) or (Location_y <= 1.0) or (Location_y >= 5.0)
36
+ (Location_x <= 5.0) or (Location_x >= 7.0) or (Location_y <= 5.0) or (Location_y >= 9.0)
37
+ ---
38
+ temporal_constraints:
39
+ Location_x <= 10.0
40
+ Location_y <= 10.0
41
+ Location_x >= 0.0
42
+ Location_y >= 0.0
43
+ (Location_x <= 2.0) or (Location_x >= 4.0) or (Location_y <= 1.0) or (Location_y >= 5.0)
44
+ (Location_x <= 5.0) or (Location_x >= 7.0) or (Location_y <= 5.0) or (Location_y >= 9.0)
45
+ ---
46
+ goals:
47
+ Location_x == 8.0
48
+ Location_y == 8.0
49
+ ---
50
+ reward:
51
+ -1.0*(Dt)
@@ -0,0 +1,53 @@
1
+ constants:
2
+ Epsilon = config_epsilon
3
+ bigM = config_bigM
4
+ ---
5
+ pvariables:
6
+ action_continuous: Accelerate_x
7
+ action_continuous: Accelerate_y
8
+ action_continuous: Dt
9
+ state_continuous: Location_x
10
+ state_continuous: Location_y
11
+ state_continuous: Speed_x
12
+ state_continuous: Speed_y
13
+ ---
14
+ odes:
15
+ dd(Location_x, Dt) == Speed_x
16
+ dd(Location_y, Dt) == Speed_y
17
+ dd(Speed_x, Dt) == Accelerate_x
18
+ dd(Speed_y, Dt) == Accelerate_y
19
+ ---
20
+ initials:
21
+ Location_x == 0.0
22
+ Location_y == 0.0
23
+ Speed_x == 0.0
24
+ Speed_y == 0.0
25
+ ---
26
+ instantaneous_constraints:
27
+ Location_x <= 10.0
28
+ Location_y <= 10.0
29
+ Location_x >= 0.0
30
+ Location_y >= 0.0
31
+ Accelerate_x <= 0.5
32
+ Accelerate_y <= 0.5
33
+ Accelerate_x >= -0.5
34
+ Accelerate_y >= -0.5
35
+ (Location_x <= 2.0) or (Location_x >= 4.0) or (Location_y <= 1.0) or (Location_y >= 9.0)
36
+ (Location_x <= 4.0) or (Location_x >= 7.0) or (Location_y <= 7.0) or (Location_y >= 9.0)
37
+ (Location_x <= 4.0) or (Location_x >= 9.0) or (Location_y <= 2.0) or (Location_y >= 6.0)
38
+ ---
39
+ temporal_constraints:
40
+ Location_x <= 10.0
41
+ Location_y <= 10.0
42
+ Location_x >= 0.0
43
+ Location_y >= 0.0
44
+ (Location_x <= 2.0) or (Location_x >= 4.0) or (Location_y <= 1.0) or (Location_y >= 9.0)
45
+ (Location_x <= 4.0) or (Location_x >= 7.0) or (Location_y <= 7.0) or (Location_y >= 9.0)
46
+ (Location_x <= 4.0) or (Location_x >= 9.0) or (Location_y <= 2.0) or (Location_y >= 6.0)
47
+ ---
48
+ goals:
49
+ Location_x == 8.0
50
+ Location_y == 8.0
51
+ ---
52
+ reward:
53
+ -1.0*(Dt)
@@ -0,0 +1,50 @@
1
+ constants:
2
+ Epsilon = config_epsilon
3
+ bigM = config_bigM
4
+ ---
5
+ pvariables:
6
+ action_continuous: Accelerate_x
7
+ action_continuous: Accelerate_y
8
+ action_continuous: Dt
9
+ state_continuous: Location_x
10
+ state_continuous: Location_y
11
+ state_continuous: Speed_x
12
+ state_continuous: Speed_y
13
+ ---
14
+ transitions:
15
+ Location_x_dash - 1.0*Location_x - 1.0*Speed_x*(Dt) - 0.5*Accelerate_x*(Dt)*(Dt) == 0.0
16
+ Location_y_dash - 1.0*Location_y - 1.0*Speed_y*(Dt) - 0.5*Accelerate_y*(Dt)*(Dt) == 0.0
17
+ Speed_x_dash - 1.0*Speed_x - 1.0*Accelerate_x*(Dt) == 0.0
18
+ Speed_y_dash - 1.0*Speed_y - 1.0*Accelerate_y*(Dt) == 0.0
19
+ ---
20
+ initials:
21
+ Location_x == 0.0
22
+ Location_y == 0.0
23
+ Speed_x == 0.0
24
+ Speed_y == 0.0
25
+ ---
26
+ instantaneous_constraints:
27
+ Location_x <= 10.0
28
+ Location_y <= 10.0
29
+ Location_x >= 0.0
30
+ Location_y >= 0.0
31
+ Accelerate_x <= 0.5
32
+ Accelerate_y <= 0.5
33
+ Accelerate_x >= -0.5
34
+ Accelerate_y >= -0.5
35
+ (Location_x <= 4.0) or (Location_x >= 6.0) or (Location_y <= 4.0) or (Location_y >= 6.0)
36
+ ---
37
+ temporal_constraints:
38
+ Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 10.0
39
+ Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 10.0
40
+ Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 0.0
41
+ Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 0.0
42
+
43
+ (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 4.0) or (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 6.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 4.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 6.0)
44
+ ---
45
+ goals:
46
+ Location_x == 8.0
47
+ Location_y == 8.0
48
+ ---
49
+ reward:
50
+ -1.0*(Dt)
@@ -0,0 +1,51 @@
1
+ constants:
2
+ Epsilon = config_epsilon
3
+ bigM = config_bigM
4
+ ---
5
+ pvariables:
6
+ action_continuous: Accelerate_x
7
+ action_continuous: Accelerate_y
8
+ action_continuous: Dt
9
+ state_continuous: Location_x
10
+ state_continuous: Location_y
11
+ state_continuous: Speed_x
12
+ state_continuous: Speed_y
13
+ ---
14
+ transitions:
15
+ Location_x_dash - 1.0*Location_x - 1.0*Speed_x*(Dt) - 0.5*Accelerate_x*(Dt)*(Dt) == 0.0
16
+ Location_y_dash - 1.0*Location_y - 1.0*Speed_y*(Dt) - 0.5*Accelerate_y*(Dt)*(Dt) == 0.0
17
+ Speed_x_dash - 1.0*Speed_x - 1.0*Accelerate_x*(Dt) == 0.0
18
+ Speed_y_dash - 1.0*Speed_y - 1.0*Accelerate_y*(Dt) == 0.0
19
+ ---
20
+ initials:
21
+ Location_x == 0.0
22
+ Location_y == 0.0
23
+ Speed_x == 0.0
24
+ Speed_y == 0.0
25
+ ---
26
+ instantaneous_constraints:
27
+ Location_x <= 10.0
28
+ Location_y <= 10.0
29
+ Location_x >= 0.0
30
+ Location_y >= 0.0
31
+ Accelerate_x <= 0.5
32
+ Accelerate_y <= 0.5
33
+ Accelerate_x >= -0.5
34
+ Accelerate_y >= -0.5
35
+ (Location_x <= 2.0) or (Location_x >= 4.0) or (Location_y <= 1.0) or (Location_y >= 5.0)
36
+ (Location_x <= 5.0) or (Location_x >= 7.0) or (Location_y <= 5.0) or (Location_y >= 9.0)
37
+ ---
38
+ temporal_constraints:
39
+ Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 10.0
40
+ Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 10.0
41
+ Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 0.0
42
+ Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 0.0
43
+ (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 2.0) or (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 4.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 1.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 5.0)
44
+ (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 5.0) or (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 7.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 5.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 9.0)
45
+ ---
46
+ goals:
47
+ Location_x == 8.0
48
+ Location_y == 8.0
49
+ ---
50
+ reward:
51
+ -1.0*(Dt)
@@ -0,0 +1,53 @@
1
+ constants:
2
+ Epsilon = config_epsilon
3
+ bigM = config_bigM
4
+ ---
5
+ pvariables:
6
+ action_continuous: Accelerate_x
7
+ action_continuous: Accelerate_y
8
+ action_continuous: Dt
9
+ state_continuous: Location_x
10
+ state_continuous: Location_y
11
+ state_continuous: Speed_x
12
+ state_continuous: Speed_y
13
+ ---
14
+ transitions:
15
+ Location_x_dash - 1.0*Location_x - 1.0*Speed_x*(Dt) - 0.5*Accelerate_x*(Dt)*(Dt) == 0.0
16
+ Location_y_dash - 1.0*Location_y - 1.0*Speed_y*(Dt) - 0.5*Accelerate_y*(Dt)*(Dt) == 0.0
17
+ Speed_x_dash - 1.0*Speed_x - 1.0*Accelerate_x*(Dt) == 0.0
18
+ Speed_y_dash - 1.0*Speed_y - 1.0*Accelerate_y*(Dt) == 0.0
19
+ ---
20
+ initials:
21
+ Location_x == 0.0
22
+ Location_y == 0.0
23
+ Speed_x == 0.0
24
+ Speed_y == 0.0
25
+ ---
26
+ instantaneous_constraints:
27
+ Location_x <= 10.0
28
+ Location_y <= 10.0
29
+ Location_x >= 0.0
30
+ Location_y >= 0.0
31
+ Accelerate_x <= 0.5
32
+ Accelerate_y <= 0.5
33
+ Accelerate_x >= -0.5
34
+ Accelerate_y >= -0.5
35
+ (Location_x <= 2.0) or (Location_x >= 4.0) or (Location_y <= 1.0) or (Location_y >= 9.0)
36
+ (Location_x <= 4.0) or (Location_x >= 7.0) or (Location_y <= 7.0) or (Location_y >= 9.0)
37
+ (Location_x <= 4.0) or (Location_x >= 9.0) or (Location_y <= 2.0) or (Location_y >= 6.0)
38
+ ---
39
+ temporal_constraints:
40
+ Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 10.0
41
+ Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 10.0
42
+ Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 0.0
43
+ Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 0.0
44
+ (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 2.0) or (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 4.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 1.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 9.0)
45
+ (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 4.0) or (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 7.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 7.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 9.0)
46
+ (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) <= 4.0) or (Location_x + Speed_x*(Dt) + 0.5*Accelerate_x*(Dt)*(Dt) >= 9.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) <= 2.0) or (Location_y + Speed_y*(Dt) + 0.5*Accelerate_y*(Dt)*(Dt) >= 6.0)
47
+ ---
48
+ goals:
49
+ Location_x == 8.0
50
+ Location_y == 8.0
51
+ ---
52
+ reward:
53
+ -1.0*(Dt)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scipplan
3
- Version: 0.1.0a1
3
+ Version: 0.2.0a2
4
4
  Summary: Metric Hybrid Factored Planning in Nonlinear Domains with Constraint Generation in Python.
5
5
  Author: Ari Gestetner, Buser Say
6
- Author-email: ages0001@student.monash.edu, buser.say@monash.edu
6
+ Author-email: ari.gestetner@monash.edu, buser.say@monash.edu
7
7
  License: MIT License
8
8
  Keywords: scip,automated planner
9
9
  Classifier: Development Status :: 3 - Alpha
@@ -16,6 +16,8 @@ Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
+ Requires-Dist: PySCIPOpt ==5.2.1
20
+ Requires-Dist: sympy ==1.13.3
19
21
 
20
22
  # SCIPPlan
21
23
 
@@ -1,9 +1,9 @@
1
- scipplan/__init__.py,sha256=UDxjLI2ncrtalcFrRMmLy7c097VACESqS51ELRaQpwY,196
2
- scipplan/config.py,sha256=wMu8jimLX9Bo4Y4rQ7NbhF5_ah3celnEaQOcrrUF9kk,5136
3
- scipplan/helpers.py,sha256=YwEr0NeDvb29_Ot686km3ZMJ-vHu-L8zjuexmlKDjpY,974
1
+ scipplan/__init__.py,sha256=ixsTY7OH5FwbQyfs19fKu0-LtwjJgvw62l0VyFuQats,195
2
+ scipplan/config.py,sha256=Ojs_pdjhwRuANPJcGyb3m5mMGqbTZkHuNvppd_Wd4FQ,5615
3
+ scipplan/helpers.py,sha256=YmS0HPQymsO5_e3jK7WQ-hBRZnxoZtewLhuzubw5sR4,975
4
4
  scipplan/parse_model.py,sha256=-vssLQZHbXxkoiHjTHD-ZxY2h0w9LvGuJZXSd4RZvlM,9564
5
- scipplan/plan_model.py,sha256=daHnVHn2e89OtXXMl63QEoeKGOmy_LwT2oCRTjUUlKQ,11145
6
- scipplan/scipplan.py,sha256=aoHXP4YhYn9IAY4N2ZKQGgzKTG1tDEC_TpVctnO307k,7741
5
+ scipplan/plan_model.py,sha256=6siDOhLkjJeibXhJh9PGocOjRQOZcSk_x5ZzeW6IrzA,14258
6
+ scipplan/scipplan.py,sha256=Ykz_L0f2dyX4-EQB1iCH-QR3waVUwxKzgskdQeUP9nE,8675
7
7
  scipplan/variables.py,sha256=3sxY3zQuxsa5z2fTFjv4zOSb9GarzojZ4W4kIx9FX68,2561
8
8
  scipplan/zero_crossing.py,sha256=kGyJsWZLLXqLW1p3LPDlPC34rTkFF8daDzqgbEcaXus,1043
9
9
  scipplan/translation/constants_navigation_1.txt,sha256=X0jvJe5MiwvayKBVXo9TQlGZGfUlpnFpMiReL68rsXc,43
@@ -18,21 +18,27 @@ scipplan/translation/initials_navigation_3.txt,sha256=s7ukUEHwcmMsey1bHCRJh515PL
18
18
  scipplan/translation/instantaneous_constraints_navigation_1.txt,sha256=WbITeszv_n93_BhE2eiNqFPAZVO4f2s44KcKUsNURyA,244
19
19
  scipplan/translation/instantaneous_constraints_navigation_2.txt,sha256=e5YdZn3OKLJh0kEiCNqpOgxgAAQxIHMB3J5OTYvPlgw,333
20
20
  scipplan/translation/instantaneous_constraints_navigation_3.txt,sha256=HnzfFntGIQ0WIMnEfcYPg1cy7u9dJn3xuYqdXZVFFvE,422
21
+ scipplan/translation/odes_navigation_1.txt,sha256=Uv13eTSTvURb6TtY7rq-otlpJMS8cQDYSyaO3X2_SRs,1015
22
+ scipplan/translation/odes_navigation_2.txt,sha256=DcbpXv-q0NP8Tx10YKqD6425esblgPNlTxchkyWMJAc,1192
23
+ scipplan/translation/odes_navigation_3.txt,sha256=ZFTyFEiL1KP0yxOCOzOSoXz9dXulRmtXDBnfZqaVbaE,1370
21
24
  scipplan/translation/pvariables_navigation_1.txt,sha256=97t5uPWAWKmtbDPJZIor5nn5qPU6aMcGdpLAuKnlDbQ,217
22
25
  scipplan/translation/pvariables_navigation_2.txt,sha256=lGUNN04bC-CJFTThNC3dwP9kU2xGftSshx-24I6zlZw,216
23
26
  scipplan/translation/pvariables_navigation_3.txt,sha256=1-yvM5BSJ5TXBlHkMbcXWd5zoc2ezSBpIIuM_zwEXSo,216
24
27
  scipplan/translation/reward_navigation_1.txt,sha256=dvR0CkxkWRbO3wP0fenXDSDMpueEUtSUqw990UnCcJY,26
25
28
  scipplan/translation/reward_navigation_2.txt,sha256=ck6uUGNhM_DWiG1hHN6_xTps1muychzqTOpz1iLF9bk,26
26
29
  scipplan/translation/reward_navigation_3.txt,sha256=O8unFCIySCz4GCBX_9mQcm-JMn5Ur6upp3HBbA4e_C8,22
30
+ scipplan/translation/solutions_navigation_1.txt,sha256=5iLPRtJXqfAXi0QG-3WPtKn8t0pH4-E2AtNp8-7k1CQ,1542
31
+ scipplan/translation/solutions_navigation_2.txt,sha256=b1c74m54iRCcZoe8uqquUQyn6HtRTiFqIA8ss2mZUdg,1895
32
+ scipplan/translation/solutions_navigation_3.txt,sha256=Jv3bzMt84LVyR1DSVJ5B8Ky9id_khZ1PxZ1s3QPKpk8,2249
27
33
  scipplan/translation/temporal_constraints_navigation_1.txt,sha256=h06iRA5TDr6R5XdjhEyYnZ3f-FQwUkbKGNw-t0k0jm8,875
28
34
  scipplan/translation/temporal_constraints_navigation_2.txt,sha256=x73dbxxb_YzvdvtVNaJfG-S9ggf-yqTYdoU6NiDQBqk,1319
29
35
  scipplan/translation/temporal_constraints_navigation_3.txt,sha256=Ki4nAX9-QtBbY9ZdHwHdqta8JQoLrAVvlZrLa1pWLnQ,1668
30
36
  scipplan/translation/transitions_navigation_1.txt,sha256=kfnr3_A9mCfflLsL4aq7OeR_BHSNST6eYuAg4ZxaPoU,411
31
37
  scipplan/translation/transitions_navigation_2.txt,sha256=kfnr3_A9mCfflLsL4aq7OeR_BHSNST6eYuAg4ZxaPoU,411
32
38
  scipplan/translation/transitions_navigation_3.txt,sha256=aIPP3FOjXZ3G6sTqicEIZ0JKJxdxHCRRZIdc5bUPFBM,395
33
- scipplan-0.1.0a1.dist-info/LICENSE,sha256=tfR4peJA8KJtYEn1NzNV-LWQVRAserdq7OJgYghreR0,1057
34
- scipplan-0.1.0a1.dist-info/METADATA,sha256=_mgsJkFO6gqiLO7b76i79d4sCbj-SD-XjNpgllWYeXk,11236
35
- scipplan-0.1.0a1.dist-info/WHEEL,sha256=-G_t0oGuE7UD0DrSpVZnq1hHMBV9DD2XkS5v7XpmTnk,110
36
- scipplan-0.1.0a1.dist-info/entry_points.txt,sha256=3qiNbbp6qIwivyPmmikyp7ByCfmsa9rGFNJPcN9Is8I,52
37
- scipplan-0.1.0a1.dist-info/top_level.txt,sha256=xO2FLRn7YQ-C25E8lagIEbik5T5FTr-Ta5bdiZezEPY,9
38
- scipplan-0.1.0a1.dist-info/RECORD,,
39
+ scipplan-0.2.0a2.dist-info/LICENSE,sha256=tfR4peJA8KJtYEn1NzNV-LWQVRAserdq7OJgYghreR0,1057
40
+ scipplan-0.2.0a2.dist-info/METADATA,sha256=z5n-lnRohnGouOC9IYge-rjf0EDnqYwRhwLZ_D8L9NU,11296
41
+ scipplan-0.2.0a2.dist-info/WHEEL,sha256=-G_t0oGuE7UD0DrSpVZnq1hHMBV9DD2XkS5v7XpmTnk,110
42
+ scipplan-0.2.0a2.dist-info/entry_points.txt,sha256=3qiNbbp6qIwivyPmmikyp7ByCfmsa9rGFNJPcN9Is8I,52
43
+ scipplan-0.2.0a2.dist-info/top_level.txt,sha256=xO2FLRn7YQ-C25E8lagIEbik5T5FTr-Ta5bdiZezEPY,9
44
+ scipplan-0.2.0a2.dist-info/RECORD,,