public void TryDropPossibility_WhenRejectedByParent_LeavesUnchanged() { var fakePossibilities = new FakePossibility[] { new FakePossibility(), new FakePossibility(), }; var childOptional = OptionalObjective.CreateWithPossibilities( Possibilities.CreatePossibilities(new(), 2), 1); var possibilities = fakePossibilities.Cast <IPossibility>().Append(childOptional).ToArray(); var optional = OptionalObjective.CreateWithPossibilities(possibilities, 3); var parent = new FakeObjective(isRequired: true); parent.CanDropPossibilities = false; IPossibility possibility = optional; IObjective objective = optional; Link.CreateConnectedLink(possibility, parent); var childToDrop = fakePossibilities[0]; Assert.False(objective.TryDropPossibility(childToDrop.AttachedObjectives.First())); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Empty(parent.DroppedPossibilities); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Equal(NodeState.UNKNOWN, childOptional.State); }
public void TryDropAndReturnPossibility_WhenOkWithParent_Succeeds() { var fakePossibilities = new FakePossibility[] { new FakePossibility(), new FakePossibility(), }; var optional = OptionalObjective.CreateWithPossibilities(fakePossibilities, 1); var parent = new FakeObjective(isRequired: true); IPossibility possibility = optional; IObjective objective = optional; var linkToParent = Link.CreateConnectedLink(possibility, parent); var childToDrop = fakePossibilities[0]; Assert.True(objective.TryDropPossibility(childToDrop.AttachedObjectives.First())); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.DroppedPossibilities); Assert.True(objective.TryDropPossibility(fakePossibilities[1].AttachedObjectives.First())); Assert.Equal(NodeState.DROPPED, optional.State); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Single(parent.DroppedPossibilities, linkToParent); objective.ReturnPossibility(fakePossibilities[1].AttachedObjectives.First()); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.DroppedPossibilities); objective.ReturnPossibility(childToDrop.AttachedObjectives.First()); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.DroppedPossibilities); }
public void TryDropAndReturnFromObjective_CascadesToOtherParents_DropsThenReturns() { var fakePossibilities = new FakePossibility[] { new FakePossibility(), new FakePossibility(), }; var childOptional = OptionalObjective.CreateWithPossibilities( Possibilities.CreatePossibilities(new(), 2), 1); var optional = OptionalObjective.CreateWithPossibilities( fakePossibilities.Cast <IPossibility>().Prepend(childOptional).ToArray(), 1); var parentToDropFrom = OptionalObjective.CreateWithPossibilities( new IPossibility[] { new FakePossibility(), }, 1); var linkToParent = Link.CreateConnectedLink(optional, parentToDropFrom); var parentToCascadeDrop = OptionalObjective.CreateWithPossibilities( new IPossibility[] { new FakePossibility(), optional, }, 2); var required = new FakeObjective(isRequired: true); Link.CreateConnectedLink(parentToDropFrom, required); Link.CreateConnectedLink(parentToCascadeDrop, required); IPossibility possibility = optional; Assert.True(possibility.TryDropFromObjective(linkToParent)); Assert.Equal(NodeState.DROPPED, optional.State); Assert.Equal(NodeState.DROPPED, parentToCascadeDrop.State); possibility.ReturnFromObjective(linkToParent); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Equal(NodeState.UNKNOWN, parentToCascadeDrop.State); }
public void TrySelectPossibility_WhenRejectedByParent_LeavesUnchanged() { var fakePossibilities = new FakePossibility[] { new FakePossibility(), new FakePossibility(), }; var childOptional = OptionalObjective.CreateWithPossibilities( Possibilities.CreatePossibilities(new(), 2), 1); var optional = OptionalObjective.CreateWithPossibilities(fakePossibilities, 1); var linkToChildOptional = Link.CreateConnectedLink(childOptional, optional); var parent = new FakeObjective(isRequired: true); parent.CanSelectPossibilities = false; var linkToParent = Link.CreateConnectedLink(optional, parent); IPossibility possibility = optional; IObjective objective = optional; Assert.False(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First())); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Equal(NodeState.UNKNOWN, childOptional.State); Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(), p => Assert.Equal(NodeState.UNKNOWN, p.State)); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.SelectedPossibilities); }
internal static Link CreateConnectedLink(IPossibility possibility, IObjective objective) { var link = new Link(possibility, objective); possibility.AppendObjective(link); objective.AppendPossibility(link); return(link); }
public void TrySelectAndDeselectPossibility_Succeeds() { var fakePossibilities = new FakePossibility[] { new FakePossibility(), new FakePossibility(), }; var childOptional = OptionalObjective.CreateWithPossibilities( Possibilities.CreatePossibilities(new(), 2), 1); var optional = OptionalObjective.CreateWithPossibilities(fakePossibilities, 2); var linkToChildOptional = Link.CreateConnectedLink(childOptional, optional); var parent = new FakeObjective(isRequired: true); var linkToParent = Link.CreateConnectedLink(optional, parent); IPossibility possibility = optional; IObjective objective = optional; Assert.True(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First())); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Equal(NodeState.UNKNOWN, childOptional.State); Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(), p => Assert.Equal(NodeState.UNKNOWN, p.State)); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.SelectedPossibilities); Assert.True(objective.TrySelectPossibility(fakePossibilities[1].AttachedObjectives.First())); Assert.Equal(NodeState.SELECTED, optional.State); Assert.Equal(NodeState.UNKNOWN, childOptional.State); Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(), p => Assert.Equal(NodeState.UNKNOWN, p.State)); Assert.Single(parent.SelectedPossibilities, linkToParent); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); objective.DeselectPossibility(fakePossibilities[1].AttachedObjectives.First()); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Equal(NodeState.UNKNOWN, childOptional.State); Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(), p => Assert.Equal(NodeState.UNKNOWN, p.State)); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.SelectedPossibilities); objective.DeselectPossibility(fakePossibilities[0].AttachedObjectives.First()); Assert.Equal(NodeState.UNKNOWN, optional.State); Assert.Equal(NodeState.UNKNOWN, childOptional.State); Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(), p => Assert.Equal(NodeState.UNKNOWN, p.State)); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); Assert.Empty(parent.SelectedPossibilities); }
public void AllUnknownPossibilitiesAreConcrete_UpdatesWhenPossibilitiesChange() { var puzzle = new Puzzle(4); var matrix = ExactCoverGraph.Create(puzzle); var fakePossibility = new FakePossibility(isConcrete: false); var possibilities = new IPossibility[] { new Possibility(new Coordinate(), 0), fakePossibility, }; var objective = Objective.CreateFullyConnected(matrix, possibilities, 1); Assert.Single(fakePossibility.AttachedObjectives); Assert.False(objective.AllUnknownPossibilitiesAreConcrete); Assert.True(((IObjective)objective).TryDropPossibility(fakePossibility.AttachedObjectives.First())); Assert.True(objective.AllUnknownPossibilitiesAreConcrete); }
public void TrySelectAndDeselect_WhenSharedByOpposingObjectives_Fails() { var puzzle = new Puzzle(4); var matrix = ExactCoverGraph.Create(puzzle); var concretePossibility = new Possibility(new(), 1); var possibilities = new IPossibility[] { concretePossibility }; var parentA = OptionalObjective.CreateWithPossibilities(possibilities, 1); var parentB = OptionalObjective.CreateWithPossibilities(possibilities.Append(new FakePossibility()).ToArray(), 1); var required = Objective.CreateFullyConnected( matrix, new IPossibility[] { parentA, parentB }, 1); Assert.False(concretePossibility.TrySelect()); Assert.Equal(NodeState.UNKNOWN, parentA.State); Assert.Equal(NodeState.UNKNOWN, parentB.State); Assert.NotEqual(NodeState.SELECTED, required.State); }
public void TryDetachAndReattachObjective_IfRequiredObjective_DropsThenReturns() { var concretePossibility = new Possibility(new(), 1); IPossibility possibility = concretePossibility; var objective = new FakeObjective(); var objectiveToDetach = new FakeObjective(isRequired: true); var linkToDrop = Link.CreateConnectedLink(possibility, objective); var linkToDetach = Link.CreateConnectedLink(possibility, objectiveToDetach); Assert.True(possibility.TryDropFromObjective(linkToDetach)); Assert.Equal(NodeState.DROPPED, concretePossibility.State); Assert.Single(objective.DroppedPossibilities, linkToDrop); Assert.Empty(objectiveToDetach.DroppedPossibilities); possibility.ReturnFromObjective(linkToDetach); Assert.Equal(NodeState.UNKNOWN, concretePossibility.State); Assert.Empty(objective.DroppedPossibilities); Assert.Empty(objectiveToDetach.DroppedPossibilities); }
public void TryDetach_CausingDrop_IfDropDisallowed_LeavesUnchanged() { var concretePossibility = new Possibility(new(), 1); IPossibility possibility = concretePossibility; var objective = new FakeObjective(isRequired: true); objective.CanDropPossibilities = false; var objectiveToDetach = new FakeObjective(isRequired: true); Link linkToOther = Link.CreateConnectedLink(possibility, objective); Link linkToDetach = Link.CreateConnectedLink(possibility, objectiveToDetach); Assert.False(possibility.TryDropFromObjective(linkToDetach)); Assert.Equal(NodeState.UNKNOWN, concretePossibility.State); Assert.Empty(objective.DroppedPossibilities); Assert.Empty(objectiveToDetach.DroppedPossibilities); // Verify the attempted-detached objective was still attached by dropping the // possibility from it. Assert.True(possibility.TryDropFromObjective(linkToOther)); Assert.Equal(NodeState.DROPPED, concretePossibility.State); Assert.Single(objectiveToDetach.DroppedPossibilities, linkToDetach); }
public void TryDropFromObjective_LeavesPossibilitiesUnchanged() { var fakePossibilities = new FakePossibility[] { new FakePossibility(), new FakePossibility(), }; var childOptional = OptionalObjective.CreateWithPossibilities( Possibilities.CreatePossibilities(new(), 2), 1); var optional = OptionalObjective.CreateWithPossibilities( fakePossibilities.Cast <IPossibility>().Prepend(childOptional).ToArray(), 1); var parent = new FakeObjective(isRequired: true); var linkToParent = Link.CreateConnectedLink(optional, parent); IPossibility possibility = optional; IObjective objective = optional; Assert.True(possibility.TryDropFromObjective(linkToParent)); Assert.Equal(NodeState.DROPPED, optional.State); Assert.Equal(NodeState.UNKNOWN, childOptional.State); Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(), p => Assert.Equal(NodeState.UNKNOWN, p.State)); Assert.Empty(parent.SelectedPossibilities); Assert.Empty(fakePossibilities[0].DroppedFromObjectives); Assert.Empty(fakePossibilities[1].DroppedFromObjectives); }
private Link(IPossibility possibility, IObjective objective) { Possibility = possibility; Objective = objective; PreviousOnObjective = NextOnObjective = NextOnPossibility = PreviousOnPossibility = this; }