source: app/src/dgp/tre.rb @ cfed5c1

help
Last change on this file since cfed5c1 was cfed5c1, checked in by pawelk <pawelk@…>, 16 years ago

Poprawione i sprawdzone dystrybulowanie dgp. Pewne pliki (seg.rb, attr.pm) nie sa jeszcze umieszczane we wlasciwym miejscu (teraz sa w bin, a powinny byc w lib/utt).
Plik z gramatyka (lib/gram.dgc) zawiera bledy!

git-svn-id: svn://atos.wmid.amu.edu.pl/utt@31 e293616e-ec6a-49c2-aa92-f4a8b91c5d16

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