1 #ifndef TRACE_FOLLOW_CIUF
2 #define TRACE_FOLLOW_CIUF
3 #include "triggering_events.hpp"
4 #include "abstract_queue.hpp"
5 #include "library/vec1.hpp"
6 #include "tracer.hpp"
7 
8 class TraceFollowingQueue : public AbstractQueue
9 {
10     vec1<TraceList> trace;
11     Reverting<int> trace_depth;
12 
13     // This is used for tracing individual propagators.
14     // We duplicate trace_depth, as updating that for every
15     // constraint can get fairly expensive.
16     int local_trace_depth;
17     int local_trace_split_count;
18     int local_trace_sort_count;
19 public:
20 
TraceFollowingQueue(const vec1<TraceList> & _trace,MemoryBacktracker * mb)21     TraceFollowingQueue(const vec1<TraceList>& _trace, MemoryBacktracker* mb)
22     : trace(_trace), trace_depth(mb->makeReverting<int>())
23     { trace_depth.set(1); }
24 
beginBranch()25     void beginBranch()
26     {
27         local_trace_depth = trace_depth.get();
28         local_trace_split_count = 1;
29         local_trace_sort_count = 1;
30         D_ASSERT(trace[local_trace_depth].traceEvent.event == TraceEvent_Branch);
31     }
32 
endBranch()33     void endBranch()
34     {
35         D_ASSERT(local_trace_split_count == 2);
36         D_ASSERT(trace_depth.get() == local_trace_depth);
37         trace_depth.set(local_trace_depth + 1);
38     }
39 
40 
execute_trace()41     SplitState execute_trace()
42     {
43         debug_out(1, "TraceFollowingQueue", "starting trace");
44         int depth = trace_depth.get();
45 
46         while(trace[depth].traceEvent.event == TraceEvent_Constraint)
47         {
48             local_trace_depth = depth;
49             local_trace_split_count = 1;
50             local_trace_sort_count = 1;
51             if(trace[depth].traceEvent.invoke().hasFailed())
52             {
53                 info_out(1,  "trace deviation - invoke failed");
54                 return SplitState(false);
55             }
56 
57             if(local_trace_split_count - 1 != trace[depth].branchEvents.size())
58             {
59                 info_out(1, "trace deviation - wrong length");
60                 return SplitState(false);
61             }
62             info_out(2, "After splitting: " <<
63                         trace[depth].traceEvent.getPartitionStack()->dumpCurrentPartition());
64 
65             depth++;
66         }
67         trace_depth.set(depth);
68         debug_out(1, "TraceFollowingQueue", "trace passed");
69 
70         return SplitState(true);
71     }
72 
hasSortData()73     virtual bool hasSortData()
74     { return true; }
75 
getPartitionEvent()76     virtual PartitionEvent& getPartitionEvent()
77     {
78         D_ASSERT(local_trace_sort_count <= trace[local_trace_depth].partitionEvents.size());
79         return trace[local_trace_depth].partitionEvents[local_trace_sort_count++];
80     }
81 
addPartitionEvent(PartitionEvent)82     virtual void addPartitionEvent(PartitionEvent)
83     { abort(); }
84 
triggerSplit(int oldcell,int newcell,int oldcellsize,int newcellsize)85     virtual SplitState triggerSplit(int oldcell, int newcell, int oldcellsize, int newcellsize)
86     {
87         BranchEvent thisBranch(oldcell, newcell, oldcellsize, newcellsize);
88         if(trace[local_trace_depth].branchEvents.size() < local_trace_split_count)
89             return SplitState(false);
90 
91         if(trace[local_trace_depth].branchEvents[local_trace_split_count] != thisBranch)
92             return SplitState(false);
93         local_trace_split_count++;
94         return SplitState(true);
95     }
96 
97 
98     // This should never happen
addTrigger(AbstractConstraint *,TriggerType)99     virtual void addTrigger(AbstractConstraint*, TriggerType)
100     { abort(); }
101 
102 
103 };
104 #endif
105