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