@@ -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
432430type  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 () )
444442let  last_call =  Fork. new_local false ;;
445443
446- let  cut_trail  ()  =  trail :=  ! initial_trail [@@ inline];;
447444let  blockers_map =  Fork. new_local (IntMap. empty : stuck_goal list IntMap.t )
448445let  blocked_by  r  =  IntMap. find (uvar_id r) ! blockers_map
449446
@@ -460,18 +457,31 @@ let contents ?overlapping () =
460457    |  _  -> None ) ! delayed
461458
462459let  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;;
467469let  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;;
472478let  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