1 package DX::QueryState;
3 use Types::Standard qw(HashRef);
7 use DX::ResolvedPropositionSet;
9 use DX::ActionBuilder::UnsetValue;
10 use DX::ActionPolicy::Allow;
11 use DX::Utils qw(:builders);
14 has predicates => (is => 'ro', isa => HashRef[Predicate], required => 1);
16 has globals => (is => 'ro', isa => DictValue, required => 1);
18 has proposition_sequence => (
19 is => 'ro', isa => PropositionSequence, required => 1
23 is => 'lazy', builder => sub {
24 $_[0]->new_search_state_for($_[0]->proposition_sequence)
28 sub new_search_state_for {
29 my ($self, $prop_seq) = @_;
30 my @local_names = map { keys %{$_->introduced_names} }
31 @{$prop_seq->members};
32 my $scope = DX::Scope->new(
33 predicates => $self->predicates,
34 globals => $self->globals,
37 map +($_ => DX::Value::Unset->new(
38 identity_path => [ 0, $_ ],
39 action_builder => DX::ActionBuilder::UnsetValue->new(
40 target_path => [ 0, $_ ],
47 map +($_ => [ 0, $_ ]), @local_names
50 my $hyp = DX::Hypothesis->new(
52 resolved_propositions => DX::ResolvedPropositionSet->new_empty,
53 outstanding_propositions => $prop_seq->members,
55 action_applications => [],
56 action_policy => DX::ActionPolicy::Allow->new,
58 return DX::SearchState->new(
59 current_hypothesis => $hyp,
64 sub with_additional_proposition {
65 my ($self, $prop) = @_;
66 my $prop_seq = $self->proposition_sequence
67 ->with_additional_proposition($prop);
68 my $sol_ss = $self->new_search_state_for($prop_seq)
70 die "No solution\n" unless $sol_ss;
72 proposition_sequence => $prop_seq,
73 search_state => $sol_ss,
77 sub with_forced_backtrack {
79 my $next_ss = $self->search_state->find_next_solution;
80 die "No next solution\n" unless $next_ss;
81 $self->but(search_state => $next_ss);