sma backtracking (smart will be later ;)
Matt S Trout [Sun, 22 Apr 2018 18:21:16 +0000 (18:21 +0000)]
fragment.output/btdemo
lib/DX/ResolutionSpace.pm
lib/DX/Step/Backtrack.pm
lib/DX/Step/FailRecheck.pm
lib/DX/TraceFormatter.pm
lib/DX/Utils.pm

index 33df4d0..45a087d 100644 (file)
@@ -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'
index 51b8490..a3e82b5 100644 (file)
@@ -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;
index 06d1986..df74d92 100644 (file)
@@ -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;
index d4d3d94..5582c5a 100644 (file)
@@ -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
   );
 }
 
index f23cc67..420ffef 100644 (file)
@@ -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 -
index fe1990c..74ff1e7 100644 (file)
@@ -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]};