summaryrefslogtreecommitdiff
path: root/overlapping_rules/merge_rules.rb
diff options
context:
space:
mode:
Diffstat (limited to 'overlapping_rules/merge_rules.rb')
-rwxr-xr-xoverlapping_rules/merge_rules.rb179
1 files changed, 179 insertions, 0 deletions
diff --git a/overlapping_rules/merge_rules.rb b/overlapping_rules/merge_rules.rb
new file mode 100755
index 0000000..987d417
--- /dev/null
+++ b/overlapping_rules/merge_rules.rb
@@ -0,0 +1,179 @@
+#!/usr/bin/env ruby
+
+require_relative './util.rb'
+
+# ISSUES
+# new rule already in global g?
+# => uniq!
+# singletons? => uniq -D
+# R+S = R => X
+# variants?
+#
+
+
+def is_sub(first, second, dir='left')
+ if dir=='right'
+ first = first.reverse; second = second.reverse
+ end
+
+ second_index = 0
+ match = false
+ first_range = Range.new; second_range = Range.new
+ first.each_with_index { |i,first_index|
+ break if i.match('\[X,\d\]') #(/\[X,\d\]/)
+ break if second_index > second.size-1
+ if i == second[second_index]
+ if !match
+ first_range.from = first_index
+ first_range.to = first_index
+ second_range.from = second_index
+ second_range.to = second_index
+ match = true
+ else
+ first_range.to = first_index
+ second_range.to = second_index
+ end
+ second_index += 1
+ else
+ first_range.from = first_range.to = second_range.from = second_range.to = nil
+ end
+ }
+ if dir=='right' && first_range.from&&first_range.to&&second_range.from&&second_range.to
+ first_range.correct(first.size-1)
+ second_range.correct(second.size-1)
+ end
+ return first_range, second_range if (first_range.from&&first_range.to&&second_range.from&&second_range.to)&&
+ (first_range.from>0||first_range.to>0||second_range.from>0||second_range.to>0)
+ return false
+end
+
+def merge(r, s, r_f_range, s_f_range, r_e_range, s_e_range, dir)
+ #ret = [] ?
+ new_rule = Rule.new
+ new_rule.f = Array.new(s.f)
+ new_rule.e = Array.new(s.e)
+ new_rule.nt = r.nt
+ if dir == 'left'
+ return nil if r_f_range.from==0&&r_e_range.from==0
+ (r_f_range.from-1).downto(0) { |i| new_rule.f.unshift r.f[i] }
+ (r_e_range.from-1).downto(0) { |i| new_rule.e.unshift r.e[i] }
+ elsif dir == 'right'
+ return nil if r_f_range.from==r.f.size-1&&r_e_range.from==r.e.size-1
+ (r_f_range.to+1).upto(r.f.size-1) { |i| new_rule.f << r.f[i] }
+ (r_e_range.to+1).upto(r.e.size-1) { |i| new_rule.e << r.e[i] }
+ end
+ return new_rule
+end
+
+def test
+ a = ["der", "eurozone", "[X,1]", "die", "[X,2]"]
+ b = ["eurozone"]
+ x = ["the", "eurozone", "[X,1]", "[X,2]"]
+ y = ["eurozone", "members"]
+
+ r,s = is_sub(a,b)
+ puts "#{r} #{s}"
+
+ r,s = is_sub(b,a)
+ puts "#{r} #{s}"
+
+ r,s = is_sub(x,y)
+ puts "#{r} #{s}"
+
+ r,s = is_sub(y,x)
+ puts "#{r} #{s}"
+
+ puts
+ puts
+
+ a = ["schuld", "an", "[X,1]", "inflation"]
+ b = ["schuld"]
+ x = ["blamed", "for", "[X,1]", "inflation"]
+ y = ["for", "responsible"]
+
+ r,s = is_sub(a,b)
+ puts "#{r} #{s}"
+
+ r,s = is_sub(b,a)
+ puts "#{r} #{s}"
+
+ r,s = is_sub(x,y)
+ puts "#{r} #{s}"
+
+ r,s = is_sub(y,x)
+ puts "#{r} #{s}"
+ exit
+end
+test if ARGV[0] == 'test'
+
+# main
+def main
+ strings = {}
+ while line = STDIN.gets
+ ids, data = line.split "\t", 2
+ r_id, s_id = ids.split '+', 2
+ r_id = r_id.to_s
+ s_id = s_id.to_s
+ r_raw, s_raw = data.split ' <<<>>> ', 2
+ r = Rule.new r_raw, r_id
+ s = Rule.new s_raw, s_id
+ #STDERR.puts "reporter:status:processing rules #{r_id} and #{s_id}"
+
+ # left, R->S
+ range_f_first, range_f_second = is_sub(r.f, s.f)
+ range_e_first, range_e_second = is_sub(r.e, s.e)
+ if range_f_first&&range_f_second&&range_e_first&&range_e_second
+ new_rule = merge(r, s, range_f_first, range_f_first, range_e_first, range_e_second, 'left')
+ if new_rule && !strings.has_key?(new_rule.rule_id_string)
+ #puts "R: #{r.f} ||| #{r.e}\nS: #{s.f} ||| #{s.e}"
+ #puts "f:(#{range_f_first} #{range_f_second}) e:(#{range_e_first} #{range_e_second})\n"
+ puts new_rule.to_s
+ strings[new_rule.rule_id_string] = true
+ #puts "\n"
+ end
+ end
+
+ # left, S->R
+ range_f_first, range_f_second = is_sub(s.f, r.f)
+ range_e_first, range_e_second = is_sub(s.e, r.e)
+ if range_f_first&&range_f_second&&range_e_first&&range_e_second
+ new_rule = merge(s, r, range_f_first, range_f_first, range_e_first, range_e_second, 'left')
+ if new_rule && !strings.has_key?(new_rule.rule_id_string)
+ #puts "S: #{s.f} ||| #{s.e}\nR: #{r.f} ||| #{r.e}"
+ #puts "f:(#{range_f_first} #{range_f_second}) e:(#{range_e_first} #{range_e_second})\n"
+ puts new_rule.to_s
+ strings[new_rule.rule_id_string] = true
+ #puts "\n"
+ end
+ end
+
+ # right, R->S
+ range_f_first, range_f_second = is_sub(r.f, s.f, 'right')
+ range_e_first, range_e_second = is_sub(r.e, s.e, 'right')
+ if range_f_first&&range_f_second&&range_e_first&&range_e_second
+ new_rule = merge(r, s, range_f_first, range_f_first, range_e_first, range_e_second, 'right')
+ if new_rule && !strings.has_key?(new_rule.rule_id_string)
+ #puts "Rr: #{r.f} ||| #{r.e}\nSr: #{s.f} ||| #{s.e}"
+ #puts "f:(#{range_f_first} #{range_f_second}) e:(#{range_e_first} #{range_e_second})\n"
+ puts new_rule.to_s
+ strings[new_rule.rule_id_string] = true
+ #puts "\n"
+ end
+ end
+
+ # right, S->R
+ range_f_first, range_f_second = is_sub(s.f, r.f, 'right')
+ range_e_first, range_e_second = is_sub(s.e, r.e, 'right')
+ if range_f_first&&range_f_second&&range_e_first&&range_e_second
+ new_rule = merge(s, r, range_f_first, range_f_first, range_e_first, range_e_second, 'right')
+ if new_rule && !strings.has_key?(new_rule.rule_id_string)
+ #puts "Sr: #{s.f} ||| #{s.e}\nRr: #{r.f} ||| #{r.e}"
+ #puts "f:(#{range_f_first} #{range_f_second}) e:(#{range_e_first} #{range_e_second})\n"
+ puts new_rule.to_s
+ strings[new_rule.rule_id_string] = true if new_rule
+ #puts "\n"
+ end
+ end
+ end
+end
+