Exemple #1
0
    def propagate(self, control, change) -> Optional[List[Tuple]]:
        """
		For any relevant change, check the assignment of the whole nogood
		for the assigned times it is in. If it it conflicting or unit add the nogood to the solver

		After the check, replace the watch if possible.

		:param control: clingo PropagateControl object
		:param change: watch and assigned time pair
		:return None if propagation has to stop, A list of (delete, add) pairs of watches if propagation can continue
		"""

        lit, assigned_time = change

        if not self.is_valid_time(assigned_time):
            return [], ConstraintCheck.UNIT

        ng = form_nogood(self.t_atom_info, assigned_time)
        if ng is None:
            return [], ConstraintCheck.UNIT

        update_result = check_assignment(ng, control)
        if update_result == ConstraintCheck.NONE:
            return ng, update_result

        lock = self.check_if_lock(assigned_time)
        if not control.add_nogood(ng, lock=lock) or not control.propagate():
            util.Count.add(StatNames.CONF_COUNT_MSG.value)
            return None
        util.Count.add(StatNames.UNITS_COUNT_MSG.value)

        return ng, update_result
Exemple #2
0
    def propagate(self, control, change) -> Optional[List[Tuple]]:
        """
		For any relevant change, immediately form the nogood
		for the assigned times it is in and add it to the solver

		:param control: clingo PropagateControl object
		:param change: lit and assigned time pair
		:return None if propagation has to stop, A list of (delete, add) pairs of watches if propagation can continue
		"""

        lit, assigned_time = change

        if not self.is_valid_time(assigned_time):
            return [], ConstraintCheck.UNIT

        ng = form_nogood(self.t_atom_info, assigned_time)
        if ng is None:
            return [], ConstraintCheck.UNIT

        if check_assignment(ng, control) == ConstraintCheck.NONE:
            return [], ConstraintCheck.UNIT

        lock = self.check_if_lock(assigned_time)

        if not control.add_nogood(ng, lock=lock) or not control.propagate():
            util.Count.add(StatNames.CONF_COUNT_MSG.value)
            return None
        util.Count.add(StatNames.UNITS_COUNT_MSG.value)

        # always return UNIT so that it doesnt attempt to change the watches for size 2
        return [], ConstraintCheck.UNIT
Exemple #3
0
	def build_constraints(self, init, t_atom) -> List[int]:
		t_atom_info, min_time, max_time = parse_atoms(t_atom)

		for assigned_time in range(min_time, max_time + 1):
			lits = form_nogood(t_atom_info, assigned_time)
			if lits is None:
				continue

			init.add_clause([-l for l in lits if l != 1])
    def test_form_nogood(self):
        reset_mappings()

        TimeAtomToSolverLit.add((1, "a(1,", 2), 1)
        TimeAtomToSolverLit.add((1, "a(2,", 1), 2)
        TimeAtomToSolverLit.add((1, "b(1,", 2), 3)
        TimeAtomToSolverLit.add((-1, "c(1,", 2), -4)

        real_info = {
            "+.a(1,": atom_info(sign=1, time_mod=0, name="a(1,"),
            "+~a(2,": atom_info(sign=1, time_mod=1, name="a(2,"),
            "+.b(1,": atom_info(sign=1, time_mod=0, name="b(1,"),
            "-.c(1,": atom_info(sign=-1, time_mod=0, name="c(1,")
        }

        ng = form_nogood(real_info, 2)
        actual_ng = [-4, 1, 2, 3]

        self.assertEqual(sorted(ng), actual_ng)

        self.assertIsNone(form_nogood(real_info, 1))
Exemple #5
0
    def propagate(self, control, change) -> Optional[List[Tuple]]:
        """
		For any relevant change, check the assignment of the whole nogood
		for the assigned times it is in. If it it conflicting or unit add the nogood to the solver

		After the check, replace the watch if possible.

		:param control: clingo PropagateControl object
		:param change: watch that was assigned
		:return None if propagation has to stop, A list of (delete, add) pairs of watches if propagation can continue
		"""

        delete_add = []

        replacement_info: List[List[int]] = []

        for assigned_time in self.watches_to_at[change]:
            if not self.is_valid_time(assigned_time):
                continue

            ng = form_nogood(self.t_atom_info, assigned_time)
            if ng is None:
                continue

            result = self.check_assignment(ng, control, assigned_time)
            if result is None:
                return None
            elif result == ConstraintCheck.UNIT:
                continue
            else:
                # only look for replacement if nogood is not conflicting nor unit
                for lit, ats in self.watches_to_at.items():
                    if lit != change:
                        if assigned_time in ats:
                            second_watch = lit
                            break

                new_watch = get_replacement_watch(ng, [change, second_watch],
                                                  control)
                if new_watch is not None:
                    delete_add.append((change, new_watch))
                    replacement_info.append([change, new_watch, assigned_time])

        self.replace_watches(replacement_info, control)

        return delete_add
Exemple #6
0
    def propagate(self, control, change) -> Optional[List[Tuple]]:
        """
		For any relevant change, check the assignment of the whole nogood
		for the assigned times it is in. If it it conflicting or unit add the nogood to the solver

		After the check, replace the watch if possible.

		:param control: clingo PropagateControl object
		:param change: watch that was assigned
		:return None if propagation has to stop, A list of (delete, add) pairs of watches if propagation can continue
		"""

        delete_add = []

        replacement_info: List[List[int]] = []

        for assigned_time in self.watches_to_at[change]:
            if not self.is_valid_time(assigned_time):
                continue

            ng = form_nogood(self.t_atom_info, assigned_time)
            if ng is None:
                continue

            result = self.check_assignment(ng, control, assigned_time)
            if result is None:
                return None
            elif result == ConstraintCheck.UNIT:
                return []
            else:
                for lit in ng:
                    if lit == change:
                        continue

                    if control.assignment.value is None:
                        self.watches_to_at[change].remove(assigned_time)
                        self.watches_to_at[lit].add(assigned_time)
                        delete_add.append([change, lit])
                        break

        return delete_add
Exemple #7
0
    def propagate(self, control, change) -> Optional[List[Tuple]]:
        """
		:param control: clingo PropagateControl object
		:param change: literal that was assigned
		:return None if propagation has to stop, A list of (delete, add) pairs of watches if propagation can continue
		"""

        ats = get_at_from_internal_lit(change, self.t_atom_info)

        for assigned_time in ats:
            if not self.is_valid_time(assigned_time):
                continue

            self.counts[assigned_time] += 1
            if self.counts[assigned_time] >= self.size - 1:
                ng = form_nogood(self.t_atom_info, assigned_time)
                if ng is None:
                    continue

                if self.check_assignment(ng, control, assigned_time) is None:
                    return None
        return 1