Skip to content

Commit e5629a3

Browse files
committed
tabling: adapt trail
1 parent ef05e82 commit e5629a3

File tree

1 file changed

+62
-36
lines changed

1 file changed

+62
-36
lines changed

src/runtime.ml

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -384,11 +384,9 @@ module ConstraintStoreAndTrail : sig
384384

385385
type trail
386386

387-
val empty : trail
387+
val empty : unit -> trail
388388

389-
val initial_trail : trail Fork.local_ref
390389
val trail : trail Fork.local_ref
391-
val cut_trail : unit -> unit [@@inline]
392390

393391
(* If true, no need to trail an imperative action. Not part of trial_this
394392
* because you can save allocations and a function call by testing locally *)
@@ -430,20 +428,19 @@ end = struct (* {{{ *)
430428

431429

432430
type trail_item =
433-
| Assignement of uvar_body
434-
| StuckGoalAddition of stuck_goal
435-
| StuckGoalRemoval of stuck_goal
431+
| Assignement of uvar_body * trail
432+
| Restore of uvar_body * term * trail
433+
| StuckGoalAddition of stuck_goal * trail
434+
| StuckGoalRemoval of stuck_goal * trail
435+
| Top
436+
and trail = trail_item ref
436437
[@@deriving show]
437438

438-
type trail = trail_item list
439-
[@@deriving show]
440-
let empty = []
439+
let empty () = ref Top
441440

442-
let trail = Fork.new_local []
443-
let initial_trail = Fork.new_local []
441+
let trail = Fork.new_local (empty ())
444442
let last_call = Fork.new_local false;;
445443

446-
let cut_trail () = trail := !initial_trail [@@inline];;
447444
let blockers_map = Fork.new_local (IntMap.empty : stuck_goal list IntMap.t)
448445
let blocked_by r = IntMap.find (uvar_id r) !blockers_map
449446

@@ -460,18 +457,31 @@ let contents ?overlapping () =
460457
| _ -> None) !delayed
461458

462459
let trail_assignment x =
463-
[%spy "dev:trail:assign" ~rid Fmt.pp_print_bool !last_call pp_trail_item (Assignement x)];
464-
if not !last_call then trail := Assignement x :: !trail
460+
assert(! (!trail) = Top);
461+
if not !last_call then begin
462+
let new_top = ref Top in
463+
[%spy "dev:trail:assign" ~rid Fmt.pp_print_bool !last_call pp_trail_item (Assignement(x,new_top))];
464+
!trail := Assignement(x ,new_top);
465+
trail := new_top;
466+
end;
465467
[@@inline]
466468
;;
467469
let trail_stuck_goal_addition x =
468-
[%spy "dev:trail:add-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalAddition x)];
469-
if not !last_call then trail := StuckGoalAddition x :: !trail
470+
if not !last_call then begin
471+
let new_top = ref Top in
472+
[%spy "dev:trail:add-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalAddition(x,new_top))];
473+
!trail := StuckGoalAddition(x,new_top);
474+
trail := new_top;
475+
end;
470476
[@@inline]
471477
;;
472478
let trail_stuck_goal_removal x =
473-
[%spy "dev:trail:remove-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalRemoval x)];
474-
if not !last_call then trail := StuckGoalRemoval x :: !trail
479+
if not !last_call then begin
480+
let new_top = ref Top in
481+
[%spy "dev:trail:remove-constraint" ~rid Fmt.pp_print_bool !last_call pp_trail_item (StuckGoalRemoval(x,new_top))];
482+
!trail := StuckGoalRemoval(x,new_top);
483+
trail := new_top;
484+
end;
475485
[@@inline]
476486
;;
477487

@@ -560,15 +570,34 @@ let undo ~old_trail ?old_state () =
560570
rules. *)
561571
to_resume := []; new_delayed := [];
562572
[%spy "dev:trail:undo" ~rid pp_trail !trail pp_string "->" pp_trail old_trail];
563-
while !trail != old_trail do
564-
match !trail with
565-
| Assignement r :: rest ->
566-
r.contents <- C.dummy;
567-
trail := rest
568-
| StuckGoalAddition sg :: rest -> remove sg; trail := rest
569-
| StuckGoalRemoval sg :: rest -> add sg; trail := rest
570-
| [] -> anomaly "undo to unknown trail"
571-
done;
573+
let rec aux h k =
574+
match !h with
575+
| Top -> k ()
576+
| Assignement(r,h') ->
577+
aux h' (fun () ->
578+
h' := Restore(r,r.contents, h);
579+
r.contents <- C.dummy;
580+
k ())
581+
| Restore(r,v,h') ->
582+
aux h' (fun () ->
583+
h' := Assignement(r,h);
584+
r.contents <- v;
585+
k ())
586+
| StuckGoalAddition(sg,h') ->
587+
aux h' (fun () ->
588+
h := StuckGoalRemoval(sg,h);
589+
remove sg;
590+
k ())
591+
| StuckGoalRemoval(sg,h') ->
592+
aux h' (fun () ->
593+
h := StuckGoalAddition(sg,h);
594+
add sg;
595+
k ())
596+
in
597+
aux old_trail (fun () ->
598+
trail := old_trail;
599+
old_trail := Top);
600+
assert(!(!trail) = Top);
572601
match old_state with
573602
| Some old_state -> state := old_state
574603
| None -> ()
@@ -3858,11 +3887,9 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
38583887
[%spy "user:rule:cut:branch" ~rid UUID.pp agid (pp_option Util.CData.pp) (Util.option_map Ast.cloc.Util.CData.cin c.loc) (ppclause ~hd) c])
38593888
clauses;
38603889
prune alts.next
3861-
end
3862-
in
3863-
prune alts in
3864-
if cutto_alts == noalts then (T.cut_trail[@inlined]) ();
3865-
[%spy "user:rule:cut" ~rid ~gid pp_string "success"];
3890+
end in
3891+
prune alts in
3892+
if cutto_alts == noalts then T.trail := T.empty ();
38663893
match gs with
38673894
| [] -> pop_andl cutto_alts next cutto_alts
38683895
| { depth; program; goal; gid = gid [@trace] } :: gs -> run depth program goal (gid[@trace]) gs next cutto_alts cutto_alts
@@ -4031,8 +4058,7 @@ end;*)
40314058
let { Fork.exec = exec ; get = get ; set = set } = Fork.fork () in
40324059
set orig_prolog_program compiled_program;
40334060
set Constraints.chrules chr;
4034-
set T.initial_trail T.empty;
4035-
set T.trail T.empty;
4061+
set T.trail (T.empty ());
40364062
set T.last_call false;
40374063
set CS.new_delayed [];
40384064
set CS.to_resume [];
@@ -4050,9 +4076,9 @@ end;*)
40504076
[%spy "dev:trail:init" ~rid (fun fmt () -> T.print_trail fmt) ()];
40514077
let gid[@trace] = UUID.make () in
40524078
[%spy "user:newgoal" ~rid ~gid (uppterm initial_depth [] ~argsdepth:0 empty_env) initial_goal];
4053-
T.initial_trail := !T.trail;
4079+
set T.trail (T.empty ());
40544080
run initial_depth !orig_prolog_program initial_goal (gid[@trace]) [] FNil noalts noalts) in
4055-
let destroy () = exec (fun () -> T.undo ~old_trail:T.empty ()) () in
4081+
let destroy () = () in
40564082
let next_solution = exec next_alt in
40574083
incr max_runtime_id;
40584084
{ search; next_solution; destroy; exec; get }

0 commit comments

Comments
 (0)