(result1: List[Tuple], result2: List[Tuple], order_matters: bool)
| 75 | |
| 76 | # check whether two denotations are correct |
| 77 | def result_eq(result1: List[Tuple], result2: List[Tuple], order_matters: bool) -> bool: |
| 78 | if len(result1) == 0 and len(result2) == 0: |
| 79 | return True |
| 80 | |
| 81 | # if length is not the same, then they are definitely different bag of rows |
| 82 | if len(result1) != len(result2): |
| 83 | return False |
| 84 | |
| 85 | num_cols = len(result1[0]) |
| 86 | |
| 87 | # if the results do not have the same number of columns, they are different |
| 88 | if len(result2[0]) != num_cols: |
| 89 | return False |
| 90 | |
| 91 | # unorder each row and compare whether the denotation is the same |
| 92 | # this can already find most pair of denotations that are different |
| 93 | if not quick_rej(result1, result2, order_matters): |
| 94 | return False |
| 95 | |
| 96 | # the rest of the problem is in fact more complicated than one might think |
| 97 | # we want to find a permutation of column order and a permutation of row order, |
| 98 | # s.t. result_1 is the same as result_2 |
| 99 | # we return true if we can find such column & row permutations |
| 100 | # and false if we cannot |
| 101 | tab1_sets_by_columns = [{row[i] for row in result1} for i in range(num_cols)] |
| 102 | |
| 103 | # on a high level, we enumerate all possible column permutations that might make result_1 == result_2 |
| 104 | # we decrease the size of the column permutation space by the function get_constraint_permutation |
| 105 | # if one of the permutation make result_1, result_2 equivalent, then they are equivalent |
| 106 | for perm in get_constraint_permutation(tab1_sets_by_columns, result2): |
| 107 | if len(perm) != len(set(perm)): |
| 108 | continue |
| 109 | if num_cols == 1: |
| 110 | result2_perm = result2 |
| 111 | else: |
| 112 | result2_perm = [permute_tuple(element, perm) for element in result2] |
| 113 | if order_matters: |
| 114 | if result1 == result2_perm: |
| 115 | return True |
| 116 | else: |
| 117 | # in fact the first condition must hold if the second condition holds |
| 118 | # but the first is way more efficient implementation-wise |
| 119 | # and we use it to quickly reject impossible candidates |
| 120 | if set(result1) == set(result2_perm) and multiset_eq(result1, result2_perm): |
| 121 | return True |
| 122 | return False |
| 123 | |
| 124 | |
| 125 | def replace_cur_year(query: str) -> str: |
no test coverage detected