from typing import Optional, Dict, Set from frozendict import frozendict import instrument import operators class Archive: true_branches: Dict[int, any] false_branches: Dict[int, any] false_score: Dict[int, any] true_score: Dict[int, any] f_name: str def __init__(self, f_name: str) -> None: self.reset() self.f_name = f_name def reset(self): self.true_branches = {} self.false_branches = {} self.true_score = {} self.false_score = {} def branches_covered(self) -> int: return len(self.true_branches.keys()) + len(self.false_branches.keys()) def branches_str(self) -> str: branch_ids = sorted([f"{branch:2d}T" for branch in self.true_branches.keys()] + [f"{branch:2d}F" for branch in self.false_branches.keys()]) return ' '.join([branch.strip() for branch in branch_ids]) def build_suite(self) -> Set[instrument.Params]: return set(list(self.true_branches.values()) + list(self.false_branches.values())) def suite_str(self): suite = self.build_suite() return " ".join([",".join([f'{k}={repr(v)}' for k, v in test.items()]) for test in suite]) def consider_test(self, test_case: frozendict): try: instrument.invoke(self.f_name, test_case) except AssertionError: return range_start, range_end = instrument.n_of_branches[self.f_name] for branch in range(range_start, range_end): if (branch in operators.distances_true and operators.distances_true[branch] == 0 and branch not in self.true_branches): self.true_branches[branch] = test_case if (branch in operators.distances_false and operators.distances_false[branch] == 0 and branch not in self.false_branches): self.false_branches[branch] = test_case def satisfies_unseen_branch(self, test_case: frozendict) -> Optional[str]: try: instrument.invoke(self.f_name, test_case) except AssertionError: return None range_start, range_end = instrument.n_of_branches[self.f_name] for branch in range(range_start, range_end): if (branch in operators.distances_true and operators.distances_true[branch] == 0 and branch not in self.true_branches): return f"{branch}T" if (branch in operators.distances_false and operators.distances_false[branch] == 0 and branch not in self.false_branches): return f"{branch}F" return None