Appends new tokens to batch. New tokens appended to already complete programs (ie. out of tree tokens) are ignored. Note that units requirements and update is not done in append (as it is computationally costly and unnecessary if units are not used). Use the assign_r
(self, new_tokens_idx, forbid_inconsistent_units = False)
| 212 | return getattr(self.lib_vect, attr)[0] |
| 213 | |
| 214 | def append (self, new_tokens_idx, forbid_inconsistent_units = False): |
| 215 | """ |
| 216 | Appends new tokens to batch. |
| 217 | New tokens appended to already complete programs (ie. out of tree tokens) are ignored. |
| 218 | Note that units requirements and update is not done in append (as it is computationally costly and unnecessary |
| 219 | if units are not used). Use the assign_required_units method on all previous steps + this one before appending |
| 220 | to compute units. This is done by prior.PhysicalUnitsPrior. |
| 221 | Parameters |
| 222 | ---------- |
| 223 | new_tokens_idx : numpy.array of shape (batch_size,) of int |
| 224 | Index of tokens to append in the library. |
| 225 | forbid_inconsistent_units : bool |
| 226 | If True, forbids (by raising an error) appending of new tokens having constraining units inconsistent |
| 227 | with current units constraints. Consistency of new tokens' physical units vs the current programs is |
| 228 | checked. To work properly the assign_required_units method should have been called on all previous steps + |
| 229 | this one before appending. |
| 230 | """ |
| 231 | # Will be modified afterward |
| 232 | new_tokens_idx = np.copy(new_tokens_idx) |
| 233 | |
| 234 | # -------------------------------------------------------------------------------------------------------------- |
| 235 | # --------------------------------------------- ASSERTIONS ----------------------------------------------------- |
| 236 | # -------------------------------------------------------------------------------------------------------------- |
| 237 | # Basic assertions |
| 238 | |
| 239 | # --------------------- Assert that time step is not exceeded --------------------- |
| 240 | if self.curr_step == self.max_time_step: |
| 241 | raise IndexError("Can not append to batch programs as it is already full over time dim, max_time_step " |
| 242 | "= %i was reached." % (self.max_time_step)) |
| 243 | |
| 244 | # ------------------------------ Check new_tokens_idx ------------------------------ |
| 245 | # Type |
| 246 | assert type(new_tokens_idx) == np.ndarray, "Arg new_tokens_idx must be a numpy array of dtype = int" |
| 247 | assert (new_tokens_idx.dtype == int or new_tokens_idx.dtype==np.dtype("int64")), "Arg new_tokens_idx must be a numpy array of dtype = int" |
| 248 | |
| 249 | # Shape |
| 250 | assert new_tokens_idx.shape == (self.batch_size,), "Arg new_tokens_idx must have shape = (batch_size,) = (%i,)" \ |
| 251 | % self.batch_size |
| 252 | |
| 253 | # Min / Max |
| 254 | assert new_tokens_idx.min() >= 0, "Min value of new_tokens_idx must be >= 0." |
| 255 | assert new_tokens_idx.max() < self.n_choices, "Max value of new_tokens_idx must be < %i" % self.n_choices |
| 256 | |
| 257 | # ------------------ Assert enough space for new tokens' dummies ------------------ |
| 258 | # Raise error if number of dummies needed to handle new tokens exceeds max_time_step |
| 259 | |
| 260 | # Space necessary in time dim to finish the program if new tokens were appended |
| 261 | n_space_necessary = self.lib("arity")[new_tokens_idx] + self.n_dummies + self.n_lengths # (batch_size,) of int |
| 262 | |
| 263 | # Is it impossible to append new token to program : mask |
| 264 | mask_impossible_to_append = n_space_necessary > self.max_time_step # (batch_size,) of bool |
| 265 | |
| 266 | if mask_impossible_to_append.any(): |
| 267 | error_msg = "Can not append tokens :\n%s\n which have arities :\n%s\n to programs :\n%s\n as the number " \ |
| 268 | "of tokens that would be required to finish the program would then be of " \ |
| 269 | "(n_dummies + new token arity) =\n%s\n which would exceed max_time_step = %i" \ |
| 270 | % (self.lib_names[new_tokens_idx][mask_impossible_to_append], |
| 271 | self.lib("arity")[new_tokens_idx][mask_impossible_to_append], |