CMiniLexicon::FindMajorSignatures(): use log file routines
[linguistica.git] / Edge.cpp
blobe5ebd32a2d46982b3220bfe86ad1c926987ccb20
1 // Implementation of CEdge methods
2 // Copyright © 2009 The University of Chicago
3 #include "Edge.h"
5 #include "Config.h"
6 #include <Q3ValueList>
7 #include "GrammarRule.h"
8 #include "StringFunc.h"
9 #include "Typedefs.h"
11 namespace {
12 bool IsTerminalCategory(CStringSurrogate ssPiece)
14 return !(ssPiece.GetLength() > 1 ||
15 ssPiece.GetLength() <= 0);
19 //////////////////////////////////////////////////////////////////////
20 // Construction/Destruction
21 //////////////////////////////////////////////////////////////////////
23 CEdge::CEdge()
25 m_InFinalParse = FALSE;
26 m_Parent = NULL;
27 m_MinimumLength = 20000; // Just needs to be a large number
28 m_Depth = 0;
31 CEdge::~CEdge()
33 /*CEdge* pEdge;
34 for( pEdge = m_Daughters.first(); pEdge; pEdge = m_Daughters.next() )
36 if( pEdge )
38 delete pEdge;
40 }*/
44 CEdge::CEdge( CGrammarRule* rule, CParse* word, int i )
46 Append( rule->GetLHS() );
47 if( rule->GetRHS().GetKey()[0] == GRAMMAR_RULE_WILD_CARD )
49 QString rightSide;
50 for( int j = 0; j < rule->GetRHS().GetKeyLength(); j++ )
52 if( rule->GetRHS().GetKey()[j] == GRAMMAR_RULE_WILD_CARD )
54 rightSide = word->GetKey()[ j + i - 1 ];
55 CSS ssRHS( rightSide );
56 Append( ssRHS );
60 else Append( rule->GetRHS() );
62 m_Start = i;
63 m_End = i;
64 m_DotLocation = 2; // that's where a rule always starts
65 m_InFinalParse = FALSE;
66 m_Parent = NULL;
67 m_MinimumLength = 20000; // Just needs to be a large number
68 m_Depth = 0;
72 CEdge::CEdge( CEdge& Edge ) : CParse( Edge )
74 m_Start = Edge.GetStart();
75 m_DotLocation = Edge.GetDotLocation();
76 m_InFinalParse = FALSE;
77 m_Parent = Edge.m_Parent;
78 m_MinimumLength = Edge.m_MinimumLength;
79 m_Depth = Edge.getDepth();
81 CEdge *pEdge;
82 for( pEdge = Edge.m_Daughters.first(); pEdge; pEdge = Edge.m_Daughters.next() )
84 m_Daughters.append( pEdge );
89 CEdge::CEdge( CParse& Cat, QString Key, int i, int End ) // Used in Scanning
91 Append( Cat );
92 Append( Key );
93 m_Start = i ;
94 m_End = End;
95 m_DotLocation = 3;
96 m_InFinalParse = FALSE;
97 m_Parent = NULL;
98 m_MinimumLength = 20000; // Just needs to be a large number
99 m_Depth = 0;
103 CSS CEdge::GetNextNode()
105 return GetPiece( m_DotLocation );
109 int CEdge::GetStart() { return m_Start; }
112 void CEdge::SetDotLocation (int n) { m_DotLocation = n; }
115 int CEdge::GetDotLocation() { return m_DotLocation; }
118 void CEdge::SetStart( int n ) { m_Start = n; }
121 QString CEdge::LHS()
123 return GetPiece(1).Display();
127 QString CEdge::RHS()
129 return ThisPieceAndWhatFollows(2).Display();
133 CStringSurrogate CEdge::GetLHS()
135 return GetPiece(1);
139 bool CEdge::Complete ()
141 if( m_DotLocation > Size() ) { return TRUE; }
142 return FALSE;
146 void CEdge::MoveDotToTheRight()
148 Q_ASSERT( m_DotLocation <= m_PieceCount + 1 ) ;// check that
149 m_DotLocation++;
153 bool CEdge::NextNodeIsNonterminal()
155 CSS ssPiece = GetPiece( m_DotLocation );
156 return !IsTerminalCategory( ssPiece );
160 bool CEdge::NextNodeIsTerminal()
162 return IsTerminalCategory( GetPiece( m_DotLocation ) );
166 bool CEdge::Incomplete()
168 if( m_DotLocation == Size() + 1 ) { return FALSE; }
169 else { return TRUE; }
173 QString CEdge::Display()
175 QString String = GetPiece(1).Display() + " ->";
176 int i;
177 for( i = 2; i <= m_PieceCount; i++ )
179 if( i == m_DotLocation )
180 String += "*";
181 else
182 String += " ";
183 String += GetPiece(i).Display();
185 if( m_DotLocation == i )
186 String += "*";
188 return String;
192 void CEdge::GetParse( CParse* parse, bool clearParse )
194 if( clearParse ) parse->ClearParse();
196 QString rhs = RHS();
197 CStringSurrogate rightSide( rhs );
199 if( m_Daughters.isEmpty() )
201 parse->Append(rightSide);
203 else
205 CEdge* daughter;
206 for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
208 daughter->GetParse( parse, FALSE );
214 QRect CEdge::drawTree(Q3Canvas* canvas, int left, int depth,
215 QMap<QString, QString>* filter)
217 int X_PADDING = 10;
218 int Y_SPACING = 30;
220 // int X_MARGIN = 10; unused variable 'X_Margin'
221 int Y_MARGIN = 10;
223 //================================================
225 Q3CanvasItem* edge = new Q3CanvasText( LHS(), canvas ),
226 * leaf = NULL;
227 Q3CanvasLine* line;
229 m_CanvasItems.clear();
230 m_CanvasItems.append( edge );
232 int myLeft = left,
233 myTop = ( depth * Y_SPACING ) + Y_MARGIN,
234 myCenterX,
235 myBottom,
236 childCenterX,
237 childLeft,
238 childTop,
239 shiftAmount;
241 Q3ValueList<QRect> daughterBoundingRectangles;
242 Q3ValueList<QRect>::iterator it;
244 QRect myBoundingRect, rectangle;
245 myBoundingRect.setTop( myTop );
246 myBoundingRect.setLeft( myLeft );
247 myBoundingRect.setBottom( myTop + edge->boundingRect().height() - 1 );
248 myBoundingRect.setRight( myLeft + edge->boundingRect().width() - 1 );
250 int count = 0;
251 // bool first = TRUE; unused variable 'first'
253 CEdge* daughter;
254 for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
256 daughterBoundingRectangles.append( rectangle );
258 daughterBoundingRectangles[count] = daughter->drawTree( canvas, left, depth + 1, filter );
260 // Adjust left position based on bounding rectangle of last daughter
261 left = daughterBoundingRectangles[count].right() + X_PADDING;
263 count++;
266 if( m_Daughters.isEmpty() )
268 // Create leaf node
269 childLeft = myLeft;
270 childTop = ( ( depth + 1 ) * Y_SPACING ) + Y_MARGIN;
272 leaf = new Q3CanvasText( Filter( filter, RHS() ), canvas );
273 m_CanvasItems.append( leaf );
275 leaf->move( childLeft, childTop );
276 leaf->show();
278 // Adjust my bounding rect
279 if( leaf->boundingRect().right() > myBoundingRect.right() ) myBoundingRect.setRight( leaf->boundingRect().right() );
280 myBoundingRect.setBottom( leaf->boundingRect().bottom() );
282 else
284 for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it )
286 // Adjust my bounding rect
287 if( (*it).right() > myBoundingRect.right() ) myBoundingRect.setRight( (*it).right() );
288 if( (*it).bottom() > myBoundingRect.bottom() ) myBoundingRect.setBottom( (*it).bottom() );
292 if( myBoundingRect.width() == edge->boundingRect().width() )
294 // Shift all children to the right
295 if( m_Daughters.isEmpty() )
297 shiftAmount = int (( myBoundingRect.width() - leaf->boundingRect().width() ) / 2.0);
299 leaf->move( leaf->boundingRect().left() + shiftAmount, leaf->boundingRect().top() );
300 leaf->show();
302 else
304 shiftAmount = int (( myBoundingRect.width() - ( daughterBoundingRectangles.last().right() - daughterBoundingRectangles.first().left() ) ) / 2.0);
306 for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
308 daughter->shiftTree( canvas, shiftAmount, 0 );
311 for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it )
313 // Adjust the bounding rect position
314 (*it).setLeft( (*it).left() + shiftAmount );
315 (*it).setRight( (*it).right() + shiftAmount );
319 else myLeft = ( myBoundingRect.right() - ( myBoundingRect.width() / 2 ) ) - ( edge->boundingRect().width() / 2 );
322 if( myLeft < myBoundingRect.left() ) myLeft = myBoundingRect.left();
323 edge->move( myLeft, myTop );
325 // Draw lines to daughter nodes
326 if( m_Daughters.isEmpty() )
328 myCenterX = edge->boundingRect().center().x();
329 myBottom = edge->boundingRect().bottom();
331 childCenterX = leaf->boundingRect().center().x();
332 childTop = leaf->boundingRect().top();
334 if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX;
336 line = new Q3CanvasLine( canvas );
337 line->setPoints( myCenterX, myBottom, childCenterX, childTop );
338 line->show();
340 m_CanvasItems.append( line );
342 else
344 Q3ValueList<QRect>::iterator it;
345 for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it )
347 myCenterX = edge->boundingRect().center().x();
348 myBottom = edge->boundingRect().bottom();
350 childCenterX = (*it).center().x();
351 childTop = (*it).top();
353 if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX;
355 line = new Q3CanvasLine( canvas );
356 line->setPoints( myCenterX, myBottom, childCenterX, childTop );
357 line->show();
359 m_CanvasItems.append( line );
363 edge->show();
364 canvas->update();
366 return myBoundingRect;
370 void CEdge::shiftTree( Q3Canvas* canvas, int right, int down )
372 CEdge* daughter;
373 for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
375 daughter->shiftTree( canvas, right, down );
378 Q3CanvasItem* item;
379 for( item = m_CanvasItems.first(); item; item = m_CanvasItems.next() )
381 item->moveBy( right, down );
382 item->show();
387 void CEdge::setMinimumLength( int length, QMap<QString,int>* mins )
389 if( m_Parent && mins && mins->find( LHS() ) != mins->end() )
391 int parentLength = m_Parent->getMinimumLength();
392 parentLength -= (*mins)[ LHS() ];
393 parentLength += length;
395 m_Parent->setMinimumLength( parentLength, mins );
398 m_MinimumLength = length;
402 QString CEdge::DisplayParse( QMap<QString, QString>* filter )
404 QString parse = LHS() + "( ";
406 if( m_Daughters.count() )
408 CEdge* daughter;
409 for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
411 parse += daughter->DisplayParse( filter );
412 parse += " ";
415 else
417 if( filter ) parse += Filter( filter, RHS() );
418 else parse += RHS();
420 parse += " ";
423 return parse + ")";