class Class::FlattenedHierarchy
Attributes
ranges[R]
Public Class Methods
child_relations_among(*classes)
click to toggle source
# File lib/redparse/decisiontree.rb, line 30 def self.child_relations_among(*classes) classes.unshift Object result={} classes.each{|klass| result[klass]=[] } classes.each{|klass| klass.ancestors.each{|anc| if anc=result[anc] anc << klass break end }} return result end
new(*classes)
click to toggle source
# File lib/redparse/decisiontree.rb, line 59 def initialize(*classes) @sorted=FlattenedHierarchy.sort_by_inheiritance(*classes) @ranges=create_member_ranges end
sort_by_inheiritance(*classes)
click to toggle source
# File lib/redparse/decisiontree.rb, line 46 def self.sort_by_inheiritance(*classes) children_of=child_relations_among(*classes) result=[] class_eater=proc{|klass| result << klass children_of[klass].each(&class_eater) } class_eater[::Object] #classes.each(&class_eater) return result end
Public Instance Methods
nonoverlapping_class_range_list(classes)
click to toggle source
# File lib/redparse/decisiontree.rb, line 75 def nonoverlapping_class_range_list(classes) classes,ranges=overlapping_class_range_list(classes) myclasses=[];myranges=[] classes_index_stack=[] classes.each_with_index{|k,i| x=ranges[i].first if i>0 and ranges[i-1]===x #if overlaps previous range classes_index_stack.push i-1 #add to the stack of saved-up ranges else #pop off old superclasses that no longer apply #to this k, adding trailing fragments for the #ranges of those superclasses as we go along until classes_index_stack.empty? current_range=ranges[classes_index_stack.last] break if current_range===x #stop if this superclass still applies ending=classes_index_stack.pop #trailing fragment done_thru=myranges.last.last current_end=current_range.last unless done_thru==current_end myranges << (done_thru+1..current_end) myclasses << classes[ending] end end end #if a gap between (sub-?)classes, emit a fragment for the appropriate super (or default to nil) next_expected=myranges.last.last+1 if next_expected!=x #was: (ranges[i].huh) myclasses<< (classes[classes_index_stack.last] unless classes_index_stack.empty?) myranges<<(next_expected..x-1) end #emit initial fragment for current class myclasses << k myranges << (x..[ranges[i+1].first-1,ranges[i].last].min) } return myclasses, myranges end
nonoverlapping_results_range_list(class2results)
click to toggle source
# File lib/redparse/decisiontree.rb, line 119 def nonoverlapping_results_range_list(class2results) classes=class2results.keys classes,ranges=nonoverlapping_class_range_list(classes) return classes.map{|k| class2results[k] }, ranges end
overlapping_class_range_list(classes)
click to toggle source
# File lib/redparse/decisiontree.rb, line 70 def overlapping_class_range_list(classes) classes=@sorted&classes return classes,classes.map{|k| @ranges[k] } end
range(klass)
click to toggle source
# File lib/redparse/decisiontree.rb, line 64 def range klass @ranges[klass] end
Private Instance Methods
create_member_ranges()
click to toggle source
# File lib/redparse/decisiontree.rb, line 142 def create_member_ranges result={} @sorted.each_with_index{|klass,i| result[klass]=i..last_member_num(klass,i) } return result end
last_member_num(klass,i)
click to toggle source
# File lib/redparse/decisiontree.rb, line 126 def last_member_num(klass,i) @sorted[i]==klass or fail low=i high=@sorted.size until low==high mid=(low+high)/2 if classes[mid]<=klass low=mid else high=mid end end return high end