Skip to content

Commit e2817fb

Browse files
committed
tabling: adapt trail
1 parent 9d23826 commit e2817fb

File tree

1 file changed

+60
-33
lines changed

1 file changed

+60
-33
lines changed

src/runtime.ml

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,9 @@ module ConstraintStoreAndTrail : sig
376376

377377
type trail
378378

379-
val empty : trail
379+
val empty : unit -> trail
380380

381-
val initial_trail : trail Fork.local_ref
382381
val trail : trail Fork.local_ref
383-
val cut_trail : unit -> unit [@@inline]
384382

385383
(* If true, no need to trail an imperative action. Not part of trial_this
386384
* because you can save allocations and a function call by testing locally *)
@@ -419,21 +417,19 @@ end = struct (* {{{ *)
419417

420418

421419
type trail_item =
422-
| Assignement of uvar_body
423-
| StuckGoalAddition of stuck_goal
424-
| StuckGoalRemoval of stuck_goal
420+
| Assignement of uvar_body * trail
421+
| Restore of uvar_body * term * trail
422+
| StuckGoalAddition of stuck_goal * trail
423+
| StuckGoalRemoval of stuck_goal * trail
424+
| Top
425+
and trail = trail_item ref
425426
[@@deriving show]
426427

427-
type trail = trail_item list
428-
[@@deriving show]
429-
let empty = []
428+
let empty () = ref Top
430429

431-
let trail = Fork.new_local []
432-
let initial_trail = Fork.new_local []
430+
let trail = Fork.new_local (empty ())
433431
let last_call = Fork.new_local false;;
434432

435-
let cut_trail () = trail := !initial_trail [@@inline];;
436-
437433
module Ugly = struct let delayed : stuck_goal list ref = Fork.new_local [] end
438434
open Ugly
439435
let contents ?overlapping () =
@@ -447,18 +443,31 @@ let contents ?overlapping () =
447443
| _ -> None) !delayed
448444

449445
let trail_assignment x =
450-
[%spy "dev:trail:assign" ~rid Fmt.pp_print_bool !last_call pp_trail_item (Assignement x)];
451-
if not !last_call then trail := Assignement x :: !trail
446+
assert(! (!trail) = Top);
447+
if not !last_call then begin
448+
let new_top = ref Top in
449+
[%spy "dev:trail:assign" ~rid Fmt.pp_print_bool !last_call pp_trail_item (Assignement(x,new_top))];
450+
!trail := Assignement(x ,new_top);
451+
trail := new_top;
452+
end;
452453
[@@inline]
453454
;;
454455
let trail_stuck_goal_addition x =
455-
[%spy "dev:trail:add-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalAddition x)];
456-
if not !last_call then trail := StuckGoalAddition x :: !trail
456+
if not !last_call then begin
457+
let new_top = ref Top in
458+
[%spy "dev:trail:add-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalAddition(x,new_top))];
459+
!trail := StuckGoalAddition(x,new_top);
460+
trail := new_top;
461+
end;
457462
[@@inline]
458463
;;
459464
let trail_stuck_goal_removal x =
460-
[%spy "dev:trail:remove-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalRemoval x)];
461-
if not !last_call then trail := StuckGoalRemoval x :: !trail
465+
if not !last_call then begin
466+
let new_top = ref Top in
467+
[%spy "dev:trail:remove-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalRemoval(x,new_top))];
468+
!trail := StuckGoalRemoval(x,new_top);
469+
trail := new_top;
470+
end;
462471
[@@inline]
463472
;;
464473

@@ -523,15 +532,34 @@ let undo ~old_trail ?old_state () =
523532
rules. *)
524533
to_resume := []; new_delayed := [];
525534
[%spy "dev:trail:undo" ~rid pp_trail !trail pp_string "->" pp_trail old_trail];
526-
while !trail != old_trail do
527-
match !trail with
528-
| Assignement r :: rest ->
529-
r.contents <- C.dummy;
530-
trail := rest
531-
| StuckGoalAddition sg :: rest -> remove sg; trail := rest
532-
| StuckGoalRemoval sg :: rest -> add sg; trail := rest
533-
| [] -> anomaly "undo to unknown trail"
534-
done;
535+
let rec aux h k =
536+
match !h with
537+
| Top -> k ()
538+
| Assignement(r,h') ->
539+
aux h' (fun () ->
540+
h' := Restore(r,r.contents, h);
541+
r.contents <- C.dummy;
542+
k ())
543+
| Restore(r,v,h') ->
544+
aux h' (fun () ->
545+
h' := Assignement(r,h);
546+
r.contents <- v;
547+
k ())
548+
| StuckGoalAddition(sg,h') ->
549+
aux h' (fun () ->
550+
h := StuckGoalRemoval(sg,h);
551+
remove sg;
552+
k ())
553+
| StuckGoalRemoval(sg,h') ->
554+
aux h' (fun () ->
555+
h := StuckGoalAddition(sg,h);
556+
add sg;
557+
k ())
558+
in
559+
aux old_trail (fun () ->
560+
trail := old_trail;
561+
old_trail := Top);
562+
assert(!(!trail) = Top);
535563
match old_state with
536564
| Some old_state -> state := old_state
537565
| None -> ()
@@ -3451,7 +3479,7 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
34513479
end in
34523480
prune alts
34533481
) alts];
3454-
if cutto_alts == noalts then (T.cut_trail[@inlined]) ();
3482+
if cutto_alts == noalts then T.trail := T.empty ();
34553483
match gs with
34563484
| [] -> pop_andl cutto_alts next cutto_alts
34573485
| { depth; program; goal; gid = gid [@trace] } :: gs -> run depth program goal (gid[@trace]) gs next cutto_alts cutto_alts
@@ -3579,8 +3607,7 @@ end;*)
35793607
let { Fork.exec = exec ; get = get ; set = set } = Fork.fork () in
35803608
set orig_prolog_program compiled_program;
35813609
set Constraints.chrules chr;
3582-
set T.initial_trail T.empty;
3583-
set T.trail T.empty;
3610+
set T.trail (T.empty ());
35843611
set T.last_call false;
35853612
set CS.new_delayed [];
35863613
set CS.to_resume [];
@@ -3594,9 +3621,9 @@ end;*)
35943621
set rid !max_runtime_id;
35953622
let search = exec (fun () ->
35963623
[%spy "dev:trail:init" ~rid (fun fmt () -> T.print_trail fmt) ()];
3597-
T.initial_trail := !T.trail;
3624+
set T.trail (T.empty ());
35983625
run initial_depth !orig_prolog_program initial_goal ((UUID.make ())[@trace]) [] FNil noalts noalts) in
3599-
let destroy () = exec (fun () -> T.undo ~old_trail:T.empty ()) () in
3626+
let destroy () = () in
36003627
let next_solution = exec next_alt in
36013628
incr max_runtime_id;
36023629
{ search; next_solution; destroy; exec; get }

0 commit comments

Comments
 (0)