def complete_column(carry_out: int, Carry_Out_Dig: PyValue, sum_dig: int, Sum_Dig: PyValue, digits_in: List[int], Leading_Digits): """ If Sum_Dig (the variable representing the digit in the sum for this column) is not yet instantiated, instantiate it to sum_dig (if that digit is available). If Sum_Dig is already instantiated, ensure it is consistent with the sum_dig. Instantiate Carry_Out_Dig to carry_out. """ # Is Sum_Dig uninstantiated? If so, instantiate it to sum_digit if possible. # Then instantiate Carry_Out_Dig, and return (yield) digits_in with sum_digit removed. if not Sum_Dig.is_instantiated(): if sum_dig not in digits_in: # sum_dig is not available in digits_in. Fail, i.e., return instead of yield. return # sum_dig is available in digits_in. Give it to Sum_Dig as long as this does not give # 0 to one of the leading digits. if sum_dig != 0 or all(Sum_Dig is not LD for LD in Leading_Digits): for _ in unify_pairs([(Carry_Out_Dig, carry_out), (Sum_Dig, sum_dig)]): # Remove sum_digit from digits_in i = digits_in.index(sum_dig) yield digits_in[:i] + digits_in[i + 1:] # If Sum_Dig is instantiated, is it equal to sum_digit? # If so, instantiate Carry_Out_Dig and return the current digits_in. elif sum_dig == Sum_Dig.get_py_value(): for _ in unify(Carry_Out_Dig, carry_out): yield digits_in
def connected(S1: PyValue, Line_Dist: PyValue, S2: PyValue): # S1: Union[PyValue, Var], Line_Dist: Var, S2: Union[PyValue, Var """ Are stations S1 and S2 connected on the same train line? If so, which line is it, and how many stations are between them? Line_Dist will be unified with (line, count_of_stations) """ # print(f'-> connected({S1}, {Line_Dist}, {S2})?') Line = PyValue() # Can use either forall or nested for _ in has_station's # for _ in forall([lambda: has_station(Line, S1), # lambda: has_station(Line, S2)]): for _ in has_station(Line, S1): for _ in has_station(Line, S2): # Ensure that S1 != S2 if S1 != S2: line = Line.get_py_value() stations = lines[line] pos1 = stations.index(S1.get_py_value()) pos2 = stations.index(S2.get_py_value()) yield from unify(Line_Dist, (line, abs(pos1 - pos2)))