def compile(self, student, *, teacher=None, trainset, valset=None):
if valset is None:
train_size = int(0.5 * len(trainset))
trainset, valset = trainset[:train_size], trainset[train_size:]
super().compile(student, teacher=teacher, trainset=trainset)
original_program = self.student.deepcopy()
all_predictors = [p for p in original_program.predictors() if hasattr(p, "signature")]
instructions_list = [p.signature.instructions for p in all_predictors]
best_score = -np.inf
best_program = None
for candidate_idx in range(self.num_candidates):
candidate_program = original_program.deepcopy()
candidate_predictors = [p for p in candidate_program.predictors() if hasattr(p, "signature")]
for i, predictor in enumerate(candidate_predictors):
predictor.signature.instructions = instructions_list[i]
for i, predictor in enumerate(candidate_predictors):
rules = self.induce_natural_language_rules(predictor, trainset)
predictor.signature.instructions = instructions_list[i]
self.update_program_instructions(predictor, rules)
score = self.evaluate_program(candidate_program, valset)
if score > best_score:
best_score = score
best_program = candidate_program
logger.info(f"Evaluated Candidate {candidate_idx + 1} with score {score}. Current best score: {best_score}")
logger.info(f"Final best score: {best_score}")
return best_program