From: Matt S Trout Date: Sun, 22 Apr 2018 18:21:16 +0000 (+0000) Subject: sma backtracking (smart will be later ;) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=scpubgit%2FDX.git;a=commitdiff_plain;h=3cc9323ecb560e91954fc7d3f721f7c498c616cf sma backtracking (smart will be later ;) --- diff --git a/fragment.output/btdemo b/fragment.output/btdemo index 33df4d0..45a087d 100644 --- a/fragment.output/btdemo +++ b/fragment.output/btdemo @@ -126,136 +126,18 @@ recheck eq ?X {{ a 1 b 2 c 3 }} { actions { SetValue 0.X {{ a 1 b 2 c 3 }} } depends_on { CONTENTS_OF 0.X } } - backtrack because { CONTENTS_OF 0.X } - fail_recheck -} -backtrack because { CONTENTS_OF 0.XValue } -remaining resolution_space { - proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } - aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } - members { - resolution_strategy { - action_prototypes { set_value 0.YKey; set_value 0.YValue } - implementation_candidates { - { { 'e' } { 0.Y.e } } - { { 'f' } { 0.Y.f } } - } - } - } -} -resolve { - proposition member_at Y ?YKey ?YValue - actions { SetValue 0.YKey 'e'; BindValue 0.YValue 0.Y.e } - depends_on { CONTENTS_OF 0.Y.e; CONTENTS_OF 0.YKey; CONTENTS_OF 0.YValue } -} -consider eq XValue 2 -resolution_space { - proposition eq XValue 2 - geometry_depends_on { CONTENTS_OF 0.XValue } - aperture { VALUE_SET 0.XValue; VALUE_SET 0.X.a } - members { - resolution { - actions { SetBoundValue 0.XValue 2 } - veracity_depends_on { CONTENTS_OF 0.XValue } - } + backtrack { + failure_dependencies { CONTENTS_OF 0.X } + exhaustion } -} -resolve { - proposition eq XValue 2 - actions { SetBoundValue 0.XValue 2 } - depends_on { CONTENTS_OF 0.XValue } -} -recheck eq ?X {{ a 1 b 2 c 3 }} { - consider eq ?X {{ a 1 b 2 c 3 }} - resolution_space { - proposition eq ?X {{ a 1 b 2 c 3 }} - geometry_depends_on { CONTENTS_OF 0.X } - aperture { VALUE_SET 0.X } - members { - resolution { - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - veracity_depends_on { CONTENTS_OF 0.X } - } - } - } - resolve { - proposition eq ?X {{ a 1 b 2 c 3 }} - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - depends_on { CONTENTS_OF 0.X } - } - backtrack because { CONTENTS_OF 0.X } fail_recheck } -backtrack because { CONTENTS_OF 0.XValue } -remaining resolution_space { - proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } - aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } - members { - resolution_strategy { - action_prototypes { set_value 0.YKey; set_value 0.YValue } - implementation_candidates { { { 'f' } { 0.Y.f } } } - } - } -} -resolve { - proposition member_at Y ?YKey ?YValue - actions { SetValue 0.YKey 'f'; BindValue 0.YValue 0.Y.f } - depends_on { CONTENTS_OF 0.Y.f; CONTENTS_OF 0.YKey; CONTENTS_OF 0.YValue } -} -consider eq XValue 2 -resolution_space { - proposition eq XValue 2 - geometry_depends_on { CONTENTS_OF 0.XValue } - aperture { VALUE_SET 0.XValue; VALUE_SET 0.X.a } - members { - resolution { - actions { SetBoundValue 0.XValue 2 } - veracity_depends_on { CONTENTS_OF 0.XValue } - } - } -} -resolve { - proposition eq XValue 2 - actions { SetBoundValue 0.XValue 2 } - depends_on { CONTENTS_OF 0.XValue } -} -recheck eq ?X {{ a 1 b 2 c 3 }} { - consider eq ?X {{ a 1 b 2 c 3 }} - resolution_space { - proposition eq ?X {{ a 1 b 2 c 3 }} - geometry_depends_on { CONTENTS_OF 0.X } - aperture { VALUE_SET 0.X } - members { - resolution { - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - veracity_depends_on { CONTENTS_OF 0.X } - } - } - } - resolve { - proposition eq ?X {{ a 1 b 2 c 3 }} - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - depends_on { CONTENTS_OF 0.X } - } - backtrack because { CONTENTS_OF 0.X } - fail_recheck -} -backtrack because { CONTENTS_OF 0.XValue } -remaining resolution_space { - proposition member_at X ?XKey ?XValue - geometry_depends_on { INDICES_OF 0.X; TYPE_OF 0.XKey; TYPE_OF 0.XValue } - aperture { VALUE_SET 0.XKey; VALUE_SET 0.XValue } - members { - resolution_strategy { - action_prototypes { set_value 0.XKey; set_value 0.XValue } - implementation_candidates { - { { 'b' } { 0.X.b } } - { { 'c' } { 0.X.c } } - } - } - } +backtrack { + failure_dependencies { CONTENTS_OF 0.X; CONTENTS_OF 0.XValue } + decision { for member_at Y ?YKey ?YValue } + non_relevant + decision { for member_at X ?XKey ?XValue } + found_alternative } resolve { proposition member_at X ?XKey ?XValue @@ -328,23 +210,18 @@ recheck eq ?Y {{ d 1 e 2 f 3 }} { actions { SetValue 0.Y {{ d 1 e 2 f 3 }} } depends_on { CONTENTS_OF 0.Y } } - backtrack because { CONTENTS_OF 0.Y } + backtrack { + failure_dependencies { CONTENTS_OF 0.Y } + exhaustion + } fail_recheck } -backtrack because { CONTENTS_OF 0.YValue } -remaining resolution_space { - proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } - aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } - members { - resolution_strategy { - action_prototypes { set_value 0.YKey; set_value 0.YValue } - implementation_candidates { - { { 'e' } { 0.Y.e } } - { { 'f' } { 0.Y.f } } - } - } - } +backtrack { + failure_dependencies { CONTENTS_OF 0.Y; CONTENTS_OF 0.YValue } + decision { for eq XValue 2 } + non_relevant + decision { for member_at Y ?YKey ?YValue } + found_alternative } resolve { proposition member_at Y ?YKey ?YValue @@ -372,7 +249,11 @@ solution resume remaining resolution_space { proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } + geometry_depends_on { + CONTENTS_OF 0.Y + TYPE_OF 0.YKey + CONTENTS_OF 0.YValue + } aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } members { resolution_strategy { @@ -429,199 +310,27 @@ recheck eq ?Y {{ d 1 e 2 f 3 }} { actions { SetValue 0.Y {{ d 1 e 2 f 3 }} } depends_on { CONTENTS_OF 0.Y } } - backtrack because { CONTENTS_OF 0.Y } - fail_recheck -} -backtrack because { CONTENTS_OF 0.YValue } -remaining resolution_space { - proposition member_at X ?XKey ?XValue - geometry_depends_on { INDICES_OF 0.X; TYPE_OF 0.XKey; TYPE_OF 0.XValue } - aperture { VALUE_SET 0.XKey; VALUE_SET 0.XValue } - members { - resolution_strategy { - action_prototypes { set_value 0.XKey; set_value 0.XValue } - implementation_candidates { { { 'c' } { 0.X.c } } } - } - } -} -resolve { - proposition member_at X ?XKey ?XValue - actions { SetValue 0.XKey 'c'; BindValue 0.XValue 0.X.c } - depends_on { CONTENTS_OF 0.X.c; CONTENTS_OF 0.XKey; CONTENTS_OF 0.XValue } -} -consider member_at Y ?YKey ?YValue -resolution_space { - proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } - aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } - members { - resolution_strategy { - action_prototypes { set_value 0.YKey; set_value 0.YValue } - implementation_candidates { - { { 'd' } { 0.Y.d } } - { { 'e' } { 0.Y.e } } - { { 'f' } { 0.Y.f } } - } - } - } -} -resolve { - proposition member_at Y ?YKey ?YValue - actions { SetValue 0.YKey 'd'; BindValue 0.YValue 0.Y.d } - depends_on { CONTENTS_OF 0.Y.d; CONTENTS_OF 0.YKey; CONTENTS_OF 0.YValue } -} -consider eq XValue 2 -resolution_space { - proposition eq XValue 2 - geometry_depends_on { CONTENTS_OF 0.XValue } - aperture { VALUE_SET 0.XValue; VALUE_SET 0.X.c } - members { - resolution { - actions { SetBoundValue 0.XValue 2 } - veracity_depends_on { CONTENTS_OF 0.XValue } - } - } -} -resolve { - proposition eq XValue 2 - actions { SetBoundValue 0.XValue 2 } - depends_on { CONTENTS_OF 0.XValue } -} -recheck eq ?X {{ a 1 b 2 c 3 }} { - consider eq ?X {{ a 1 b 2 c 3 }} - resolution_space { - proposition eq ?X {{ a 1 b 2 c 3 }} - geometry_depends_on { CONTENTS_OF 0.X } - aperture { VALUE_SET 0.X } - members { - resolution { - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - veracity_depends_on { CONTENTS_OF 0.X } - } - } - } - resolve { - proposition eq ?X {{ a 1 b 2 c 3 }} - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - depends_on { CONTENTS_OF 0.X } - } - backtrack because { CONTENTS_OF 0.X } - fail_recheck -} -backtrack because { CONTENTS_OF 0.XValue } -remaining resolution_space { - proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } - aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } - members { - resolution_strategy { - action_prototypes { set_value 0.YKey; set_value 0.YValue } - implementation_candidates { - { { 'e' } { 0.Y.e } } - { { 'f' } { 0.Y.f } } - } - } - } -} -resolve { - proposition member_at Y ?YKey ?YValue - actions { SetValue 0.YKey 'e'; BindValue 0.YValue 0.Y.e } - depends_on { CONTENTS_OF 0.Y.e; CONTENTS_OF 0.YKey; CONTENTS_OF 0.YValue } -} -consider eq XValue 2 -resolution_space { - proposition eq XValue 2 - geometry_depends_on { CONTENTS_OF 0.XValue } - aperture { VALUE_SET 0.XValue; VALUE_SET 0.X.c } - members { - resolution { - actions { SetBoundValue 0.XValue 2 } - veracity_depends_on { CONTENTS_OF 0.XValue } - } - } -} -resolve { - proposition eq XValue 2 - actions { SetBoundValue 0.XValue 2 } - depends_on { CONTENTS_OF 0.XValue } -} -recheck eq ?X {{ a 1 b 2 c 3 }} { - consider eq ?X {{ a 1 b 2 c 3 }} - resolution_space { - proposition eq ?X {{ a 1 b 2 c 3 }} - geometry_depends_on { CONTENTS_OF 0.X } - aperture { VALUE_SET 0.X } - members { - resolution { - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - veracity_depends_on { CONTENTS_OF 0.X } - } - } - } - resolve { - proposition eq ?X {{ a 1 b 2 c 3 }} - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - depends_on { CONTENTS_OF 0.X } - } - backtrack because { CONTENTS_OF 0.X } - fail_recheck -} -backtrack because { CONTENTS_OF 0.XValue } -remaining resolution_space { - proposition member_at Y ?YKey ?YValue - geometry_depends_on { INDICES_OF 0.Y; TYPE_OF 0.YKey; TYPE_OF 0.YValue } - aperture { VALUE_SET 0.YKey; VALUE_SET 0.YValue } - members { - resolution_strategy { - action_prototypes { set_value 0.YKey; set_value 0.YValue } - implementation_candidates { { { 'f' } { 0.Y.f } } } - } - } -} -resolve { - proposition member_at Y ?YKey ?YValue - actions { SetValue 0.YKey 'f'; BindValue 0.YValue 0.Y.f } - depends_on { CONTENTS_OF 0.Y.f; CONTENTS_OF 0.YKey; CONTENTS_OF 0.YValue } -} -consider eq XValue 2 -resolution_space { - proposition eq XValue 2 - geometry_depends_on { CONTENTS_OF 0.XValue } - aperture { VALUE_SET 0.XValue; VALUE_SET 0.X.c } - members { - resolution { - actions { SetBoundValue 0.XValue 2 } - veracity_depends_on { CONTENTS_OF 0.XValue } - } - } -} -resolve { - proposition eq XValue 2 - actions { SetBoundValue 0.XValue 2 } - depends_on { CONTENTS_OF 0.XValue } -} -recheck eq ?X {{ a 1 b 2 c 3 }} { - consider eq ?X {{ a 1 b 2 c 3 }} - resolution_space { - proposition eq ?X {{ a 1 b 2 c 3 }} - geometry_depends_on { CONTENTS_OF 0.X } - aperture { VALUE_SET 0.X } - members { - resolution { - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - veracity_depends_on { CONTENTS_OF 0.X } - } - } - } - resolve { - proposition eq ?X {{ a 1 b 2 c 3 }} - actions { SetValue 0.X {{ a 1 b 2 c 3 }} } - depends_on { CONTENTS_OF 0.X } + backtrack { + failure_dependencies { CONTENTS_OF 0.Y } + exhaustion } - backtrack because { CONTENTS_OF 0.X } fail_recheck } -backtrack because { CONTENTS_OF 0.XValue } +backtrack { + failure_dependencies { CONTENTS_OF 0.Y; CONTENTS_OF 0.YValue } + decision { for eq XValue 2 } + non_relevant + decision { for member_at Y ?YKey ?YValue } + failure_dependencies { CONTENTS_OF 0.Y; TYPE_OF 0.YKey; CONTENTS_OF 0.YValue } + decision { for member_at X ?XKey ?XValue } + non_relevant + decision { for eq ?Y {{ d 1 e 2 f 3 }} } + failure_dependencies { CONTENTS_OF 0.Y; TYPE_OF 0.YKey; CONTENTS_OF 0.YValue } + decision { for eq ?X {{ a 1 b 2 c 3 }} } + non_relevant + exhaustion +} +exhaustion {{ X {{ a 1 b 2 c 3 }} XKey 'b' diff --git a/lib/DX/ResolutionSpace.pm b/lib/DX/ResolutionSpace.pm index 51b8490..a3e82b5 100644 --- a/lib/DX/ResolutionSpace.pm +++ b/lib/DX/ResolutionSpace.pm @@ -2,7 +2,7 @@ package DX::ResolutionSpace; use DX::Step::Backtrack; use DX::Step::ResolveProposition; -use DX::Utils qw(expand_deps); +use DX::Utils qw(compact_deps); use DX::Class; has proposition => (is => 'ro', isa => Proposition); @@ -25,7 +25,7 @@ sub for_deparse { map [ statement => [ [ symbol => (split '::', ${$_->[0]})[-1] ], [ value_path => [ @{$_}[1..$#$_] ] ], - ] ], @{expand_deps($self->geometry_depends_on)} + ] ], @{$self->geometry_depends_on} ] ] ], (@{$self->aperture} ? [ aperture => [ block => [ @@ -58,4 +58,10 @@ sub next_step { return "DX::Step::${step_type}"->new(resolution_space => $self); } +sub with_geometry_dependencies { + my ($self, $deps) = @_; + my $new_deps = compact_deps([ @{$self->geometry_depends_on}, @$deps ]); + return $self->but(geometry_depends_on => $new_deps); +} + 1; diff --git a/lib/DX/Step/Backtrack.pm b/lib/DX/Step/Backtrack.pm index 06d1986..df74d92 100644 --- a/lib/DX/Step/Backtrack.pm +++ b/lib/DX/Step/Backtrack.pm @@ -1,7 +1,7 @@ package DX::Step::Backtrack; use DX::DependencyMap; -use DX::Utils qw(format_deps); +use DX::Utils qw(format_deps compact_deps); use DX::Class; with 'DX::Role::Step'; @@ -13,31 +13,59 @@ sub apply_to { my $rspace = $self->resolution_space; trace backtrack => [ statement => [ [ symbol => 'backtrack' ], - [ statement => [ - [ symbol => 'because' ], - format_deps($rspace->geometry_depends_on) - ] ] + [ 'enter_block' ] + ] ]; + trace backtrack => [ statement => [ + [ symbol => 'failure_dependencies' ], + format_deps($rspace->geometry_depends_on) ] ]; my $dmap = DX::DependencyMap->new_empty ->with_dependencies_for( backtrack => $rspace->geometry_depends_on ); - - foreach my $adj (@{$ss->decisions_taken}) { + DECISION: foreach my $adj (@{$ss->decisions_taken}) { my ($rspace_was, $ss_was) = @$adj; - $dmap = $dmap->with_dependencies_for( - backtrack => $rspace_was->geometry_depends_on - ); - next unless @{$rspace_was->remaining_resolution_space->members}; - trace rspace => [ statement => [ - [ symbol => 'remaining' ], - @{$rspace_was->remaining_resolution_space->for_deparse->[1]} + trace backtrack => [ statement => [ + [ symbol => 'decision' ], + [ pairs => [ + [ for => $rspace_was->proposition, ] + #aperture => + ] ] ] ]; - return $ss_was->but( - next_step => $rspace_was->remaining_resolution_space->next_step - ); + foreach my $event (@{$rspace_was->aperture}) { + if ($dmap->dependents_of($event)) { + my $remain = $rspace_was->remaining_resolution_space; + if (@{$remain->members}) { + trace backtrack => [ statement => [ + [ symbol => 'found_alternative' ] + ] ]; + trace backtrack => [ 'leave_block' ]; + return $ss_was->but( + next_step => $remain->with_geometry_dependencies( + $dmap->dependencies_for('backtrack') + )->next_step + ); + } + $dmap = $dmap->with_dependencies_for( + backtrack => $rspace_was->geometry_depends_on + ); + trace backtrack => [ statement => [ + [ symbol => 'failure_dependencies' ], + format_deps(compact_deps($dmap->dependencies_for('backtrack'))) + ] ]; + next DECISION; + } + } + trace backtrack => [ statement => [ [ symbol => 'non_relevant' ] ] ]; } - return $ss->but(next_step => $ss->on_exhaustion_step); + trace backtrack => [ statement => [ [ symbol => 'exhaustion' ] ] ]; + trace backtrack => [ 'leave_block' ]; + return $ss->but( + next_step + => $ss->on_exhaustion_step->but( + exhaustion_depends_on => $dmap->dependencies_for('backtrack') + ) + ); } 1; diff --git a/lib/DX/Step/FailRecheck.pm b/lib/DX/Step/FailRecheck.pm index d4d3d94..5582c5a 100644 --- a/lib/DX/Step/FailRecheck.pm +++ b/lib/DX/Step/FailRecheck.pm @@ -8,13 +8,18 @@ has resume_search_state => (is => 'ro', isa => SearchState, required => 1); has resolution_space => (is => 'ro', isa => ResolutionSpace, required => 1); +has exhaustion_depends_on => (is => 'ro', isa => DependencyList); + sub apply_to { my ($self, $old_ss) = @_; trace recheck => [ statement => [ [ symbol => 'fail_recheck' ] ] ]; trace recheck => [ 'leave_block' ]; return $self->resume_search_state->but( next_step - => $self->resolution_space->remaining_resolution_space->next_step + => $self->resolution_space + ->remaining_resolution_space + ->with_geometry_dependencies($self->exhaustion_depends_on) + ->next_step ); } diff --git a/lib/DX/TraceFormatter.pm b/lib/DX/TraceFormatter.pm index f23cc67..420ffef 100644 --- a/lib/DX/TraceFormatter.pm +++ b/lib/DX/TraceFormatter.pm @@ -28,8 +28,9 @@ sub format { sub _format { my ($self, $thing) = @_; my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing}; + # return $self->${\"_format_as_${as}"}($data); if $WS eq "\n"; local $WS = ' '; - my $spaced = $self->${\"_format_as_${as}"}($data);# + my $spaced = $self->${\"_format_as_${as}"}($data); if ($spaced =~ /\n/ or (length($spaced) > ($self->max_width - diff --git a/lib/DX/Utils.pm b/lib/DX/Utils.pm index fe1990c..74ff1e7 100644 --- a/lib/DX/Utils.pm +++ b/lib/DX/Utils.pm @@ -69,7 +69,7 @@ sub format_deps { sub compact_deps { my ($deps) = @_; my @sorted = sort_by { join "\0", @{$_->[0]} } - map { [ [ join("\0", @{$_}[1..$#$_]), $${$_->[0]} ], $_ ] } @$deps; + map { [ [ join("\0", @{$_}[1..$#$_], ''), $${$_->[0]} ], $_ ] } @$deps; my @compacted; while (my $s = shift @sorted) { my ($path, $type) = @{$s->[0]};