source: src/dgp/tre @ cfdf333

Last change on this file since cfdf333 was 5f4d9c3, checked in by Maciej Prill <mprill@…>, 13 years ago

Rewritten the build system, added lem UTF-8 version.

  • Property mode set to 100755
File size: 7.6 KB
Line 
1#!/usr/bin/ruby -I /usr/local/lib/utt -I $HOME/.local/lib/utt
2
3$: << "#{ENV['HOME']}/.local/lib/utt"
4$: << "/usr/local/lib/utt"
5
6require 'getoptlong'
7require 'seg.rb'
8
9opts = GetoptLong.new(
10[ '--help',     '-h',   GetoptLong::NO_ARGUMENT ],
11[ '--debug',    '-d',   GetoptLong::NO_ARGUMENT ],
12[ '--format',   '-F',   GetoptLong::REQUIRED_ARGUMENT ],
13[ '--info',     '-I',   GetoptLong::REQUIRED_ARGUMENT ],
14[ '--only-trees','-t',  GetoptLong::NO_ARGUMENT ])
15
16$helptext=
17"The program generates trees from the graph output by dgp. dgp must\n"+
18"must be run with '-i ds' option.\n\n"+
19"Command:       tre [options]\n\n"+
20"Options:\n"+
21"--help         -h      Print help (this text) and exit.\n"+
22"--debug        -d      Verbose output. For developers only.\n"+
23"--format=s     -F s    Output format. Recognized values:\n"+
24"                               a       root + list of arcs\n"+
25"                               p       parenthesized notation\n"+
26"                               h       human readable indented tree format\n"+
27"                       Multiple values are allowed. (default p)\n"+
28"--info=s       -I s    Information printed. Recognized values:\n"+
29"                               n       node identifier\n"+
30"                               f       surface form\n"+
31"                               m       morphological information\n"+
32"                               l       arc labels\n"+
33"--only-trees   -t      Do not copy input. Print trees only.\n"
34
35$DEBUG=false
36$FORMAT='p'
37$INFO='DEFAULT'
38$ONLYTREES=false
39
40opts.each do |opt, arg|
41  case opt
42  when '--help'
43    print $helptext
44    exit 0
45  when '--debug'
46    $DEBUG=true
47  when '--format'
48    $FORMAT=arg
49  when '--info'
50    $INFO=arg
51  when '--only-trees'
52    $ONLYTREES=true
53  else
54    print "Unknown option #{opt}. Ignored.\n"
55  end
56end
57
58if $INFO=='DEFAULT'
59  case $FORMAT
60    when 'p','a'
61    $INFO='nl'
62    when 'h'
63    $INFO='fmnl'
64  end
65end
66
67$dgpsep=';'
68
69def tre(input)
70  $gphid=[]
71  $form=[]
72  $lem=[]
73  nodes=[]
74  count=0
75  seg=Seg.new
76  for line in input
77    print line unless $ONLYTREES
78    seg.set(line)
79    if dgp=seg['dgp']
80      if nodes==[] && seg[3]!='BOS'
81        print "A sentence must start with BOS segment. Aborting.\n"
82        return
83      end
84
85      id=dgp[/^\d+/].to_i
86
87      if gph=seg['gph']
88        $gphid[id]=gph[/^\d+/].to_i
89      else
90        print "No gph field. Aborting.\n"
91        return
92      end
93
94      $form[$gphid[id]]=seg[4]
95      $lem[$gphid[id]]=seg['lem']
96             
97      nodes[id] = [seg[1].to_i,dgp]
98
99      if seg[3]=='EOS'
100        $pref = "#{seg[1]} #{seg[2]} SYN *"
101        parsegraph(nodes)
102        printgraph if $DEBUG
103        $thetrees=[]
104        gentrees2
105        for t in $thetrees
106          count += 1
107          t1=ground(t)
108          case $FORMAT
109          when /a/
110            print "#{$pref} tre:#{count} arc:"
111            printarcs(t1[0],t1[1])
112            print "\n"
113          when /p/
114            print "#{$pref} tre:#{count} par:"
115            printpar(t1[0],t1[1])
116            print "\n"
117          when /h/
118            print "#\n# tree #{count}\n# ------\n"
119            printtree(t1[0],t1[1],0)
120          end
121        end
122        nodes=[]
123      end
124    end
125  end
126end
127
128
129def nodeinfo(id)
130  info=""
131  if $INFO =~ /n/
132    info += id.to_s                           
133    info += '.' if $INFO =~ /[fm]/
134  end
135  if $INFO =~ /f/
136    info += $form[id] 
137    info += ';' if $INFO =~ /m/
138  end
139  if $INFO =~ /m/
140    info += $lem[id] 
141  end
142  info
143end
144
145
146def printarcs(root,arcs)
147  print nodeinfo(root)
148  for a in arcs
149    print ';'
150    print "#{a[2]}:" if $INFO =~ /l/
151      print nodeinfo(a[0])+'-'+nodeinfo(a[1])
152  end
153end
154
155def printtree(root,arcs,o)
156  if o==0
157        print "# %-16s" % "root: "
158  end
159  print nodeinfo(root),"\n"
160  for arc in arcs.select{ |a| a[0]==root }.sort{|a,b| a[1]<=>b[1] }
161    print '# ',"   "*(o+1)
162    print "%-16s" % (arc[2]+": ")
163    printtree(arc[1],arcs,o+1)
164  end
165end
166
167def printpar(root,arcs)
168  print nodeinfo(root)
169  deps = arcs.select{ |a| a[0]==root }.sort{|a,b| a[1]<=>b[1] }
170  unless deps == []
171    print '('
172    cont=false
173    for arc in deps
174      if cont then print ',' else cont=true end
175      print arc[2],':' if $INFO =~ /l/
176      printpar(arc[1],arcs)
177    end
178    print ')'
179  end
180end
181
182
183def parsegraph(nodes)
184
185  $n   =nodes.length
186  $sat =[];
187
188  $vis =[];
189  $succ=[];
190  $lhs =[];
191  $arcs=[];
192  $pos=[]
193
194  for dgp in nodes
195
196    parts  = dgp[1].split($dgpsep,6)
197
198    if parts[3]==nil || parts[4]==nil || parts[5]==nil
199      $stderr.print "ERR: tre requires dgp be called with '--info s' option. Aborting.\n"
200      exit
201    end
202
203    i      = parts[0].to_i
204    $pos[i] = dgp[0].to_i
205    $sat << i if parts[1]=="s"
206    $arcs |= parts[2].split(',').map{ |a| case a
207                                          when /\-\-(\w+)-(\d+)\/(\d+)/
208                                            [i, $2.to_i, $1, $3.to_i]
209                                          when /\+\+(\d+)-(\w+)\/(\d+)/
210                                            [$1.to_i, i, $2, $3.to_i]
211                                          end }
212    $succ |= parts[3][1..-2].split(',').map{|x| [x.to_i,i]}
213    $vis  |= parts[4][1..-2].split(',').map{|x| [x.to_i,i]} 
214    $lhs  |= parts[5][1..-2].split(',').map{|x| [x.to_i,i]} + [[i,i]]
215
216  end
217end
218
219
220def ground(t)
221  [ $gphid[t[0]] , t[1].map{|a| [$gphid[a[0]],$gphid[a[1]],a[2]]} ]
222end 
223
224
225def gentrees2()
226  $thetrees=[];
227  bos=0; eos=$n-1;
228  roots = (1...eos).select{|i| $vis.include? [i,eos]}.select{|i| $vis.include? [bos,i]}
229  if $DEBUG then print "ROOTS: #{roots.inspect}\n" end
230  for i in roots
231    $theroot=i
232    for r in buildR(i , eos, [])
233      (rmin,rmax,rtree) = r
234      buildR(bos, rmin, rtree)
235    end
236  end
237end
238
239
240def buildR(min, max, tree)
241  if $DEBUG then print "buildR--#{min}--#{max}--#{tree.inspect}\n" end
242  trees=[]
243  for a in $arcs.select{|a| a[0]==max && $vis.include?([min,a[1]]) }
244    if $DEBUG then print "ARC: #{a.inspect}\n" end
245    for r in buildR(a[1],a[3],tree+[a])
246      (rmin,rmax,rarcs) = r
247      for l in buildR(min,rmin,rarcs)
248        (lmin,lmax,larcs) = l
249        trees << [lmin,rmax,larcs]
250      end
251    end
252  end
253  for i in (0...$n).select{|i| $succ.include?([i,max])}.select{|i| $lhs.include?([min,i])}
254    for l in buildL(min,i,tree)
255      (lmin,lmax,larcs) = l
256      trees << [lmin,lmax,larcs]
257    end
258  end
259  trees 
260end
261   
262
263def buildL(min,max,tree)
264  if $DEBUG then print "buildL--#{min}--#{max}--#{tree.inspect}\n" end
265  if $pos[min]==$pos[max]
266    if min==0 && max==0
267      $thetrees.push [$theroot,tree]
268      if $DEBUG then print "adding tree: #{tree.inspect}\n" end
269    end
270    return [[max,max,tree]]
271  end
272  trees=[]
273  for arc in $arcs.select{|a| a[1]==max && $lhs.include?([min,a[0]]) }
274    if $DEBUG then print "ARC: #{arc.inspect}\n" end
275    for r in buildR(arc[3],max,tree+[arc])
276      (rmin,rmax,rarcs) = r
277      for l in buildL(min,rmin,rarcs)
278        (lmin,lmax,larcs) = l
279        trees << [lmin,lmax,larcs]
280      end
281    end
282  end
283  trees
284end
285
286
287def printgraph()
288 
289  print "N:    #{$n}\n"
290  print "SAT:  #{set_to_s($sat)}\n"
291  print "SUCC: #{rel_to_s($succ)}\n"
292  print "VIS:  #{rel_to_s($vis)}\n"
293  print "LHS:  #{rel_to_s($lhs)}\n"
294  print "ARCS: #{arcs_to_s($arcs)}\n"
295end
296
297def set_to_s(s) "{#{s.join(',')}}" end
298def rel_to_s(r) "{#{r.map{|p| "(#{p[0]},#{p[1]})"}.join(',')}}" end
299def arc_to_s(q) "-#{q[0]}-#{q[2]}-#{q[1]}/#{q[3]}" end
300def arcs_to_s(a) "{#{a.map{|q| arc_to_s(q)}.join(',')}}" end
301
302######################################################################
303
304tre($stdin)
Note: See TracBrowser for help on using the repository browser.