@@ -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
421419type 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 () )
433431let last_call = Fork. new_local false ;;
434432
435- let cut_trail () = trail := ! initial_trail [@@ inline];;
436-
437433module Ugly = struct let delayed : stuck_goal list ref = Fork. new_local [] end
438434open Ugly
439435let contents ?overlapping () =
@@ -447,18 +443,31 @@ let contents ?overlapping () =
447443 | _ -> None ) ! delayed
448444
449445let 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;;
454455let 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;;
459464let 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