summaryrefslogtreecommitdiff
path: root/intersect.rb
diff options
context:
space:
mode:
Diffstat (limited to 'intersect.rb')
-rw-r--r--intersect.rb100
1 files changed, 32 insertions, 68 deletions
diff --git a/intersect.rb b/intersect.rb
index 41ddfd6..d8404a2 100644
--- a/intersect.rb
+++ b/intersect.rb
@@ -2,13 +2,10 @@
require_relative './grammar.rb'
-# interescts a WFSA (WFST) with a WSCFG to produce a hypergraph
-
-
class Chart
attr_accessor :m
-
+
def initialize input
@m = []
(input.size+1).times {
@@ -18,10 +15,6 @@ class Chart
}
end
- def at span
- return @m[span.left][span.right]
- end
-
def at i,j
return @m[i][j]
end
@@ -41,47 +34,35 @@ class Item < Rule
end
def to_s
- "#{lhs} -> #{rhs.map{|i|i.to_s}.insert(@dot,'*').join ' '} (dot:#{@dot}) (a:#{arity}) (#{@span.left}, #{@span.right})"
+ "#{lhs} -> #{rhs.map{|i|i.to_s}.insert(@dot,'*').join ' '} dot:#{@dot} a:#{arity} (#{@span.left}, #{@span.right})"
end
end
-
-
-#def shift
-#end
-#def reduce
-#end
-#def init
- #axioms,goals etc
-#end
-#def parse
-#end
-
-
+# set-up
g = Grammar.new 'grammar'
input = "ich sah ein kleines haus".split.map { |i| Terminal.new i }
-#start = NonTerminal.new 'S'
-
passive_chart = Chart.new input
active_chart = Chart.new input
-
-
-# 1st row: arity0 rules
-unary_rules = g.rules.reject { |r| r.arity>0 }
-input.each_with_index { |t,j|
- unary_rules.each { |r|
- if r.rhs.first.w == t.w
- passive_chart.at(j,j+1) << Item.new(r)
- passive_chart.at(j,j+1).last.span.left = j
- passive_chart.at(j,j+1).last.span.right = j+1
- passive_chart.at(j,j+1).last.dot = 1
+# pre-fill passive chart w/ arity-0 rules
+g.rules.reject { |r| r.arity>0 }.each { |r|
+ input.each_index.select{ |j| input[j].w==r.rhs.first.w }.each { |j|
+ k = 1
+ if r.rhs.size > 1
+ slice = input[j,j+(r.rhs.size-1)].map { |i| i.w }
+ if slice == r.rhs.map { |i| i.w }
+ k = r.rhs.size
+ else
+ next
+ end
end
+ passive_chart.at(j,j+k) << Item.new(r)
+ passive_chart.at(j,j+k).last.span.left = j
+ passive_chart.at(j,j+k).last.span.right = j+k
+ passive_chart.at(j,j+k).last.dot = k
}
}
-
-
# pre-fill active chart with non 0arity rules starting with a (single(!)) T
g.rules.reject{|r| r.rhs[0].class==NonTerminal||r.arity==0}.each {|r|
input.each_with_index { |i,j|
@@ -89,12 +70,13 @@ g.rules.reject{|r| r.rhs[0].class==NonTerminal||r.arity==0}.each {|r|
(j+2).upto(input.size) { |k| # no empty NT!
active_chart.at(j,k) << Item.new(r)
active_chart.at(j,k).last.span.left = j
- active_chart.at(j,k).last.span.right = j+1 # k
+ active_chart.at(j,k).last.span.right = j+1
active_chart.at(j,k).last.dot = 1
}
end
}
}
+
# pre-fill active chart
s = g.rules.reject { |r| r.rhs.first.class!=NonTerminal}#.reject{|r| r.lhs.sym == 'S'}
(input.size).times { |k|
@@ -102,22 +84,16 @@ s = g.rules.reject { |r| r.rhs.first.class!=NonTerminal}#.reject{|r| r.lhs.sym =
s.each { |r|
active_chart.at(i,i+k+2) << Item.new(r)
active_chart.at(i,i+k+2).last.span.left = i
- active_chart.at(i,i+k+2).last.span.right = i #i+k+2
+ active_chart.at(i,i+k+2).last.span.right = i
active_chart.at(i,i+k+2).last.dot = 0
}
}
}
-
-
-
-
-
-# parse
-
-def scan i, j, active_chart, input
+# scan
+def scan i, j, active_chart, passive_chart, input
active_chart.at(i,j).each { |item|
- if item.rhs[item.dot].class == Terminal
+ while item.rhs[item.dot].class == Terminal
if item.rhs[item.dot].w == input[item.span.left+item.dot].w
item.dot += 1
if item.dot == item.rhs.size
@@ -129,14 +105,12 @@ def scan i, j, active_chart, input
}
end
-
-puts "parse"
+# parse
def visit i, j, sz, active_chart, passive_chart, g, input
puts "| #{i},#{j}"
# SCAN
- scan i, j, active_chart, input
-
+ scan i, j, active_chart, passive_chart, input
1.upto(sz) { |span|
break if span==(j-i)
@@ -147,7 +121,7 @@ def visit i, j, sz, active_chart, passive_chart, g, input
passive_chart.at(k, k+span).each { |passive_item|
if active_item.rhs[active_item.dot].class==NonTerminal && passive_item.lhs.sym == active_item.rhs[active_item.dot].sym
next if not active_item.span.right==passive_item.span.left
- active_item.span.right = passive_item.span.right #if passive_item.span.right > active_item.span.right
+ active_item.span.right = passive_item.span.right
active_item.dot += 1
if active_item.dot == active_item.rhs.size
passive_chart.at(i,j) << Item.new(active_item)
@@ -157,30 +131,20 @@ def visit i, j, sz, active_chart, passive_chart, g, input
}
}
- # SCAN
- active_chart.at(i,j).each { |item|
- if item.rhs[item.dot].class == Terminal
- if item.rhs[item.dot].w == input[item.span.left+item.dot].w
- item.dot += 1
- if item.dot == item.rhs.size
- passive_chart.at(i,j) << Item.new(item)
- passive_chart.at(i,j).last.span.right = item.span.left+item.dot
- end
- end
- end
- }
+ scan i, j, active_chart, passive_chart, input
}
end
+# once for each cell
(input.size).times { |k|
0.upto(input.size-(k+2)) { |i|
- visit i, i+k+2, input.size, active_chart, passive_chart, g, input
+ visit i, i+k+2, input.size, active_chart, passive_chart, g, input
}
}
-puts "---"
-active_chart.at(0,5).each { |item|
+puts "---"
+passive_chart.at(3,5).each { |item|
puts item.to_s
}