mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-19 13:16:27 +01:00
merging trunk
git-svn-id: svn://localhost/ardour2/branches/undo@652 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
7ff370e798
commit
7968974c01
116 changed files with 735 additions and 12963 deletions
|
|
@ -838,6 +838,11 @@ if env['NLS']:
|
|||
print 'This system is not configured for internationalized applications (no libintl.h). An english-only version will be built\n'
|
||||
env['NLS'] = 0
|
||||
|
||||
have_intltool = conf.TryAction(Action('intltool-update --version'))
|
||||
if have_intltool[0] != 1:
|
||||
print 'This system is not configured for internationalized applications (no intltool-update command). An english-only version will be built\n'
|
||||
env['NLS'] = 0
|
||||
|
||||
|
||||
env = conf.Finish()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gtk-ardour 0.347.2\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2003-05-11 17:36+0200\n"
|
||||
"Last-Translator: Karsten Petersen <kapet@kapet.de>\n"
|
||||
"Language-Team: Deutsch <de@li.org>\n"
|
||||
|
|
@ -4773,29 +4773,29 @@ msgstr ""
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
" Please set ARDOUR2_UI_RC to point to a valid UI style file"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
"\n"
|
||||
|
|
@ -4806,12 +4806,12 @@ msgid ""
|
|||
"Please consider the possibilities, and perhaps (re)start JACK."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr ""
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4819,7 +4819,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4827,60 +4827,60 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
msgid " with libardour "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Achtung: Es gibt zu Ardour KEINERLEI Gewährleistung!"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr "Dies ist freie Software und Sie dürfen sie gerne weiterverbreiten,"
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
#, fuzzy
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr "solange Sie sich an die Spielregeln aus der Datei COPYING halten."
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.99beta23\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2005-01-11\n"
|
||||
"Last-Translator: Muadibas <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Hellenic(Greek) <LL@li.org>\n"
|
||||
|
|
@ -4776,19 +4776,19 @@ msgstr "παύση του user interface\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr "%d: εδέχθη σήμα %d\n"
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr "δεν γίνεται να διαμορφώθεί η διαχείρηση σημάτων για %1"
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr "δεν γίνεται να διαμορφώθεί η προκαθορισμένη μάσκα σημάτων (%1)"
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4797,12 +4797,12 @@ msgstr ""
|
|||
"Δίχως αρχείο εμφάνισεως UI, ο ardour θα φαίνεται παράξενα.\n"
|
||||
"Παρακαλώ θέστε το ARDOUR_UI_RC να δείχνει σε ενεργό αρχείο εμφανίσεως UI"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
#, fuzzy
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr "Δεν γινόταν να συνδεθώ στον JACK server σαν \"%1\""
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
|
|
@ -4822,12 +4822,12 @@ msgstr ""
|
|||
"\n"
|
||||
"Παρακαλώ αναλογιστείτε τις πιθανότητες, και ίσως (ξανα)ξεκινήστε τον JACK."
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "δεν γινόταν να φορτωθεί η συνεδρία γραμμής εντολών \"%1\""
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4835,7 +4835,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4843,63 +4843,63 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr "Ardour/GTK "
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
#, fuzzy
|
||||
msgid " with libardour "
|
||||
msgstr " τρέχοντας με libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
#, fuzzy
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr "Πνευματικα Δικαιώματα 1999-2004 Paul Davis"
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Ο Ardour έρχεται με απολύτως ΚΑΜΙΑ ΕΓΓΥΗΣΗ"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr ""
|
||||
"Το παρόν είναι ελεύθερο λογισμικό, είστε ελεύθεροι να το επαναδιανείμετε "
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
#, fuzzy
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr "υπό ορισμένους όρους, ανατρέξτε στο αρχείο COPYING για λεπτομέρειες"
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "δεν γινόταν να δημιουργηθεί ARDOUR GUI"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr "Δεν γινόταν να συνδεθώ στον JACK server σαν \"%1\""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "δεν γινόταν να εκκινηθεί ο Ardour."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: ardour 0.688.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2004-01-21 12:45+0100\n"
|
||||
"Last-Translator: Alex Krohn <alexkrohn@fastmail.fm>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
|
|
@ -4827,19 +4827,19 @@ msgstr "deteniendo interfase visual\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4848,12 +4848,12 @@ msgstr ""
|
|||
"Sin un archivo de interfase visual, Ardour no se \n"
|
||||
"ver�correctamente. Apunte ARDOUR_UI_RC a un archivo v�ido"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
#, fuzzy
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr "No se pudo conectar a JACK con el nombre \"%1\""
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
|
|
@ -4873,12 +4873,12 @@ msgstr ""
|
|||
"\n"
|
||||
"Considere estas posibilidades y o reinicie a JACK.\n"
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "no se pudo cargar desde l�ea de comando a la sesin \"%1\""
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4886,7 +4886,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4894,61 +4894,61 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
#, fuzzy
|
||||
msgid " with libardour "
|
||||
msgstr " corriendo con libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Ardour no ofrece ningn tipo de garant�"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr "Este software es gratuito.Usted puede distribuirlo "
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
#, fuzzy
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr "bajo ciertas condiciones; lea el archivo COPYING para m� detalles"
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "no se pudo crear la interfase visual de Ardour"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr "No se pudo conectar a JACK con el nombre \"%1\""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "no se pudo iniciar a Ardour."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gtk-ardour 0.334.5\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2005-02-14 11:19-0500\n"
|
||||
"Last-Translator: Alain Fréhel <alain.frehel@free.fr>\n"
|
||||
"Language-Team: French <ardour-dev@lists.sourceforge.net>\n"
|
||||
|
|
@ -4809,19 +4809,19 @@ msgstr "en train d'arrêter l'interface utilisateur\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr "%d(%d) : reçu le signal %d\n"
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr "impossible d'installer le gestionnaire de signaux pour %1"
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr "impossible de définir le masque de signalisation"
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4830,12 +4830,12 @@ msgstr ""
|
|||
"Sans un fichier de style pour son IHM, ardour aura une apparence bizarre.\n"
|
||||
"Veuillez faire pointer ARDOUR_UI_RC vers un fichier de style d'IHM valide"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
#, fuzzy
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr "Impossible de se reconnecter à JACK"
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
|
|
@ -4855,12 +4855,12 @@ msgstr ""
|
|||
"\n"
|
||||
"Veuillez étudier les possibilités, et peut-être (re)lancer JACK."
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "impossible de charger la session indiqué en ligne de commande \"%1\""
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4872,7 +4872,7 @@ msgstr ""
|
|||
"Une session nommé \"%1\" existe déjà.\n"
|
||||
"Pour éviter ce message, lancez ardour comme cela : \"ardour %1"
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4885,11 +4885,11 @@ msgstr ""
|
|||
"Pour la créer depuis la ligne de commande, lancez ardour comme cela : "
|
||||
"\"ardour --new %1"
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr "Ardour/GTK"
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
|
|
@ -4897,20 +4897,20 @@ msgstr ""
|
|||
"\n"
|
||||
" (fonctionnant avec "
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
msgid " with libardour "
|
||||
msgstr " avec libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
#, fuzzy
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr "Copyright (C) 1999-2005 Paul Davis"
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
|
|
@ -4918,33 +4918,33 @@ msgstr ""
|
|||
"Certaines parties Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Ardour est distribué sans AUCUNE GARANTIE"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr "ni même pour la COMMERCIALISATION ou pour UN BUT PARTICULIER."
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr "Ceci est un logiciel libre, et vous êtes encouragé à le distribuer "
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr ""
|
||||
"sous certaines conditions ; voir le fichier source pour les conditions de "
|
||||
"distribution."
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "impossible de créer l'interface utilisateur d'ARDOUR"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr "Impossible de se connecter au serveur JACK en tant que \"%1\""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "impossible d'initialiser Ardour."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: ardour 0.354.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2003-05-20 13:03-0500\n"
|
||||
"Last-Translator: Filippo Pappalardo <filippo@email.it>\n"
|
||||
"Language-Team: Italian\n"
|
||||
|
|
@ -4727,19 +4727,19 @@ msgstr "chiusura dell'interfaccia\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr "%d: ricevuto segnale %d\n"
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4748,11 +4748,11 @@ msgstr ""
|
|||
"Senza uno Stile per l'Interfaccia, ardour apparirà strano\n"
|
||||
"Impostare la variabile ARDOUR_UI_RC per puntare ad uno Stile"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
"\n"
|
||||
|
|
@ -4763,12 +4763,12 @@ msgid ""
|
|||
"Please consider the possibilities, and perhaps (re)start JACK."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "Impossibile caricare la sessione \"%1\" da linea di comando"
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4776,7 +4776,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4784,60 +4784,60 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
#, fuzzy
|
||||
msgid " with libardour "
|
||||
msgstr " con libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "Impossibile creare l'interfaccia di Ardour"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "impossibile avviare Ardour"
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: ardour 0.688.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2005-08-15 21:50-0000\n"
|
||||
"Last-Translator: Chris Ross, Alexander Franca & Leandro Marco\n"
|
||||
"Language-Team: Portuguese\n"
|
||||
|
|
@ -4779,19 +4779,19 @@ msgstr "interrompendo a interface do usuário\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4800,12 +4800,12 @@ msgstr ""
|
|||
"Sem um arquivo de estilo o ardour vai ficar meio esquisito.\n"
|
||||
"Por favor, configure a variável ambiente ARDOUR_UI_RC para um arquivo válido"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
#, fuzzy
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr "Não foi possível se conectar ao servidor JACK"
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
|
|
@ -4825,12 +4825,12 @@ msgstr ""
|
|||
"\n"
|
||||
"Por favor, considere essas razões, e talvez (re)inicie o JACK."
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "não foi possível carregar a sessão da linha de comando \"%1\""
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4838,7 +4838,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4846,60 +4846,60 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
#, fuzzy
|
||||
msgid " with libardour "
|
||||
msgstr " executando com libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Ardour não oferece ABSOLUTAMENTE NENHUMA GARANTIA"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr "Isto é um Software Livre. Fique à vontade para redistribuí-lo "
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr "com algumas condições; veja o fonte para mais detalhes"
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "não foi possível criar a INTERFACE ARDOUR"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr "Não foi possível se conectar ao servidor JACK com \"%1\""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "não foi possível iniciar o Ardour."
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.814.2\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2004-12-07 13:00+0000\n"
|
||||
"Last-Translator: Rui Nuno Capela <rncbc@rncbc.org>\n"
|
||||
"Language-Team: Portuguese\n"
|
||||
|
|
@ -4768,19 +4768,19 @@ msgstr "interface homem-máquina em fase terminal\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr "%d: sinal %d recebido\n"
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr "não foi possível estabelecer receptor de sinal %1"
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr "não foi possível estabelecer máscara de sinal %1"
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4791,12 +4791,12 @@ msgstr ""
|
|||
"Por favor, indique um ficheiro de estilo visual válido em ARDOUR_UI_RC "
|
||||
"(variável de ambiente)"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
#, fuzzy
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr "Não foi possível conectar ao serviço JACK como \"%1\""
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
|
|
@ -4816,12 +4816,12 @@ msgstr ""
|
|||
"\n"
|
||||
"Por favor, considere estas possibilidades e (re)inicie o serviço JACK."
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "não foi possível carregar a sessão de linha de comando \"%1\""
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4829,7 +4829,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4837,63 +4837,63 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
#, fuzzy
|
||||
msgid " with libardour "
|
||||
msgstr " em execução com libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Ardour é fornecido ABSOLUTAMENTE SEM QUALQUER GARANTIA"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr "Sendo software livre, é permitida e até encorajada a sua distribuição"
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
#, fuzzy
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr ""
|
||||
"desde que sejam respeitadas algumas condições; para mais informações, leia "
|
||||
"por favor o ficheiro COPYING."
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "não foi possível criar o interface gráfico (GUI)"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr "Não foi possível conectar ao serviço JACK como \"%1\""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "não foi possível inicializar o Ardour"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: gtk-ardour 0.413.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 18:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2004-03-31 00:45+0300\n"
|
||||
"Last-Translator: Igor Blinov pitstop@nm.ru\n"
|
||||
"Language-Team: Russian\n"
|
||||
|
|
@ -4795,19 +4795,19 @@ msgstr "завершение работы...\n"
|
|||
msgid "%d(%d): received signal %d\n"
|
||||
msgstr "%d: принят сигнал %d\n"
|
||||
|
||||
#: main.cc:186
|
||||
#: main.cc:180
|
||||
msgid "cannot become new process group leader (%1)"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:213
|
||||
#: main.cc:207
|
||||
msgid "cannot setup signal handling for %1"
|
||||
msgstr "cannot setup signal handling for %1"
|
||||
|
||||
#: main.cc:224
|
||||
#: main.cc:218
|
||||
msgid "cannot set default signal mask (%1)"
|
||||
msgstr "cannot set default signal mask (%1)"
|
||||
|
||||
#: main.cc:254
|
||||
#: main.cc:248
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Without a UI style file, ardour will look strange.\n"
|
||||
|
|
@ -4817,12 +4817,12 @@ msgstr ""
|
|||
"без файла определяющего стиль отображения.\n"
|
||||
"Пожалуйста, укажите его (файл) в переменной окружения ARDOUR_UI_RC"
|
||||
|
||||
#: main.cc:276
|
||||
#: main.cc:270
|
||||
#, fuzzy
|
||||
msgid "Ardour could not connect to JACK."
|
||||
msgstr "Не удалось соединиться с сервером JACK как \"%1\""
|
||||
|
||||
#: main.cc:280
|
||||
#: main.cc:274
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"There are several possible reasons:\n"
|
||||
|
|
@ -4842,12 +4842,12 @@ msgstr ""
|
|||
"\n"
|
||||
"Пожалуйста, проверьте все варианты, возможно потребуется (пере)запуск JACK."
|
||||
|
||||
#: main.cc:310
|
||||
#: main.cc:304
|
||||
msgid "could not load command line session \"%1\""
|
||||
msgstr "не удалось загрузить сессию \"%1\", указанную в командной строке"
|
||||
|
||||
#. it wasn't new, but we require a new session
|
||||
#: main.cc:330
|
||||
#: main.cc:324
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4855,7 +4855,7 @@ msgid ""
|
|||
"To avoid this message, start ardour as \"ardour %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:341
|
||||
#: main.cc:335
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -4863,62 +4863,62 @@ msgid ""
|
|||
"To create it from the command line, start ardour as \"ardour --new %1"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:405
|
||||
#: main.cc:399
|
||||
msgid "Ardour/GTK "
|
||||
msgstr "Ardour/GTK "
|
||||
|
||||
#: main.cc:407
|
||||
#: main.cc:401
|
||||
msgid ""
|
||||
"\n"
|
||||
" (built using "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:411
|
||||
#: main.cc:405
|
||||
#, fuzzy
|
||||
msgid " with libardour "
|
||||
msgstr " работает с libardour "
|
||||
|
||||
#: main.cc:416
|
||||
#: main.cc:410
|
||||
msgid " and GCC version "
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:426
|
||||
#: main.cc:420
|
||||
#, fuzzy
|
||||
msgid "Copyright (C) 1999-2006 Paul Davis"
|
||||
msgstr "Авторское право 1999-2004 Paul Davis"
|
||||
|
||||
#: main.cc:427
|
||||
#: main.cc:421
|
||||
msgid ""
|
||||
"Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel "
|
||||
"Baker"
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:429
|
||||
#: main.cc:423
|
||||
msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
|
||||
msgstr "Ardour распространяется БЕЗ ВСЯКИХ ГАРАНТИЙ"
|
||||
|
||||
#: main.cc:430
|
||||
#: main.cc:424
|
||||
msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
msgstr ""
|
||||
|
||||
#: main.cc:431
|
||||
#: main.cc:425
|
||||
msgid "This is free software, and you are welcome to redistribute it "
|
||||
msgstr "Это свободное программное обеспечение, Вы можете распространять его"
|
||||
|
||||
#: main.cc:432
|
||||
#: main.cc:426
|
||||
#, fuzzy
|
||||
msgid "under certain conditions; see the source for copying conditions."
|
||||
msgstr "на определённых условиях; подробнее об этом читайте в файле COPYING."
|
||||
|
||||
#: main.cc:441
|
||||
#: main.cc:435
|
||||
msgid "could not create ARDOUR GUI"
|
||||
msgstr "не удалось создать графический интерфейс для ARDOUR"
|
||||
|
||||
#: main.cc:459
|
||||
#: main.cc:453
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr "Не удалось соединиться с сервером JACK как \"%1\""
|
||||
|
||||
#: main.cc:462
|
||||
#: main.cc:456
|
||||
msgid "could not initialize Ardour."
|
||||
msgstr "не удалось запустить Ardour."
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ arch_specific_objects = [ ]
|
|||
|
||||
osc_files = [ 'osc.cc' ]
|
||||
vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ]
|
||||
coreaudio_files = [ 'coreaudio_source.cc' ]
|
||||
coreaudio_files = [ 'coreaudiosource.cc' ]
|
||||
extra_sources = [ ]
|
||||
|
||||
if ardour['VST']:
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class AudioFileSource : public AudioSource {
|
|||
Removable = 0x8,
|
||||
RemovableIfEmpty = 0x10,
|
||||
RemoveAtDestroy = 0x20,
|
||||
BuildPeaks = 0x40
|
||||
NoPeakFile = 0x40
|
||||
};
|
||||
|
||||
virtual ~AudioFileSource ();
|
||||
|
|
@ -62,7 +62,7 @@ class AudioFileSource : public AudioSource {
|
|||
cannot.
|
||||
*/
|
||||
|
||||
static AudioFileSource* create (string path_plus_channel);
|
||||
static AudioFileSource* create (const string& path_plus_channel, Flag flags = Flag (0));
|
||||
static AudioFileSource* create (const XMLNode&);
|
||||
|
||||
static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error);
|
||||
|
|
@ -97,7 +97,7 @@ class AudioFileSource : public AudioSource {
|
|||
static void set_search_path (string);
|
||||
static void set_header_position_offset (jack_nframes_t offset, bool negative);
|
||||
|
||||
static sigc::signal<void,struct tm*, time_t> HeaderPositionOffsetChanged;
|
||||
static sigc::signal<void> HeaderPositionOffsetChanged;
|
||||
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
|
|
@ -107,7 +107,7 @@ class AudioFileSource : public AudioSource {
|
|||
to cause issues.
|
||||
*/
|
||||
|
||||
void handle_header_position_change (struct tm*, time_t tnow);
|
||||
void handle_header_position_change ();
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -27,16 +27,23 @@ namespace ARDOUR {
|
|||
|
||||
class CoreAudioSource : public AudioFileSource {
|
||||
public:
|
||||
CoreAudioSource (const string& path_plus_channel, bool build_peak = true);
|
||||
CoreAudioSource (const XMLNode&);
|
||||
CoreAudioSource (const string& path_plus_channel, Flag);
|
||||
~CoreAudioSource ();
|
||||
|
||||
float sample_rate() const;
|
||||
int update_header (jack_nframes_t when, struct tm&, time_t);
|
||||
|
||||
int flush_header () {return 0;};
|
||||
void set_header_timeline_position () {};
|
||||
|
||||
protected:
|
||||
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
|
||||
|
||||
jack_nframes_t write_unlocked (Sample *dst, jack_nframes_t cnt, char * workbuf)
|
||||
{ return 0; }
|
||||
|
||||
|
||||
private:
|
||||
ExtAudioFileRef af;
|
||||
uint16_t n_channels;
|
||||
|
|
@ -45,7 +52,7 @@ class CoreAudioSource : public AudioFileSource {
|
|||
mutable jack_nframes_t tmpbufsize;
|
||||
mutable Glib::Mutex _tmpbuf_lock;
|
||||
|
||||
void init (const string &str, bool build_peak);
|
||||
void init (const string &str);
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
|
|
@ -32,8 +32,7 @@ namespace ARDOUR {
|
|||
class DestructiveFileSource : public SndFileSource {
|
||||
public:
|
||||
DestructiveFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate,
|
||||
Flag flags = AudioFileSource::Flag (AudioFileSource::Writable|
|
||||
AudioFileSource::BuildPeaks));
|
||||
Flag flags = AudioFileSource::Flag (AudioFileSource::Writable));
|
||||
|
||||
DestructiveFileSource (const XMLNode&);
|
||||
~DestructiveFileSource ();
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ class SndFileSource : public AudioFileSource {
|
|||
Flag flags = AudioFileSource::Flag (AudioFileSource::Writable|
|
||||
AudioFileSource::Removable|
|
||||
AudioFileSource::RemovableIfEmpty|
|
||||
AudioFileSource::CanRename|
|
||||
AudioFileSource::BuildPeaks));
|
||||
AudioFileSource::CanRename));
|
||||
|
||||
/* constructor to be called for existing in-session files */
|
||||
|
||||
|
|
@ -52,7 +51,7 @@ class SndFileSource : public AudioFileSource {
|
|||
int update_header (jack_nframes_t when, struct tm&, time_t);
|
||||
int flush_header ();
|
||||
|
||||
static Flag default_in_session_flags();
|
||||
void handle_smpte_offset_change (jack_nframes_t offset, bool negative);
|
||||
|
||||
protected:
|
||||
void set_header_timeline_position ();
|
||||
|
|
|
|||
|
|
@ -1754,6 +1754,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
|||
srcs.push_back (s);
|
||||
|
||||
if ((fsrc = dynamic_cast<AudioFileSource *>(s)) != 0) {
|
||||
cerr << "updating source after capture\n";
|
||||
fsrc->update_header (capture_info.front()->start, when, twhen);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <sigc++/bind.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -94,14 +94,6 @@ AudioTrack::~AudioTrack ()
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
AudioTrack::handle_smpte_offset_change ()
|
||||
{
|
||||
diskstream
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
AudioTrack::deprecated_use_diskstream_connections ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
// if these headers come before sigc++ is included
|
||||
// the parser throws ObjC++ errors. (nil is a keyword)
|
||||
#ifdef HAVE_COREAUDIO
|
||||
#include <ardour/coreaudio_source.h>
|
||||
#include <ardour/coreaudiosource.h>
|
||||
#include <AudioToolbox/ExtendedAudioFile.h>
|
||||
#include <AudioToolbox/AudioFormat.h>
|
||||
#endif // HAVE_COREAUDIO
|
||||
|
|
@ -55,7 +55,7 @@ using namespace PBD;
|
|||
string AudioFileSource::peak_dir = "";
|
||||
string AudioFileSource::search_path;
|
||||
|
||||
sigc::signal<void,struct tm*, time_t> AudioFileSource::HeaderPositionOffsetChanged;
|
||||
sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged;
|
||||
bool AudioFileSource::header_position_negative;
|
||||
uint64_t AudioFileSource::header_position_offset;
|
||||
|
||||
|
|
@ -122,7 +122,6 @@ AudioFileSource::init (string pathstr, bool must_exist)
|
|||
next_peak_clear_should_notify = false;
|
||||
|
||||
if (!find (pathstr, must_exist, is_new)) {
|
||||
cerr << "cannot find " << pathstr << " with me = " << must_exist << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -211,16 +210,16 @@ AudioFileSource::create (const XMLNode& node)
|
|||
|
||||
#ifdef HAVE_COREAUDIO
|
||||
AudioFileSource*
|
||||
AudioFileSource::create (const string& idstr)
|
||||
AudioFileSource::create (const string& idstr, Flag flags)
|
||||
{
|
||||
AudioFileSource* es = 0;
|
||||
|
||||
try {
|
||||
es = new CoreAudioSource (idstr);
|
||||
es = new CoreAudioSource (idstr, flags);
|
||||
}
|
||||
|
||||
catch (failed_constructor& err) {
|
||||
es = new SndFileSource (idstr);
|
||||
es = new SndFileSource (idstr, flags);
|
||||
}
|
||||
|
||||
return es;
|
||||
|
|
@ -229,9 +228,9 @@ AudioFileSource::create (const string& idstr)
|
|||
#else
|
||||
|
||||
AudioFileSource*
|
||||
AudioFileSource::create (string idstr)
|
||||
AudioFileSource::create (const string& idstr, Flag flags)
|
||||
{
|
||||
return new SndFileSource (idstr);
|
||||
return new SndFileSource (idstr, flags);
|
||||
}
|
||||
|
||||
#endif // HAVE_COREAUDIO
|
||||
|
|
@ -595,13 +594,19 @@ AudioFileSource::set_search_path (string p)
|
|||
void
|
||||
AudioFileSource::set_header_position_offset (jack_nframes_t offset, bool negative)
|
||||
{
|
||||
time_t tnow;
|
||||
|
||||
time (&tnow);
|
||||
|
||||
header_position_offset = offset;
|
||||
header_position_negative = negative;
|
||||
HeaderPositionOffsetChanged (localtime (&tnow), tnow); /* EMIT SIGNAL */
|
||||
|
||||
HeaderPositionOffsetChanged ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioFileSource::handle_header_position_change ()
|
||||
{
|
||||
if (writable()) {
|
||||
set_header_timeline_position ();
|
||||
flush_header ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -610,17 +615,6 @@ AudioFileSource::set_timeline_position (jack_nframes_t pos)
|
|||
timeline_position = pos;
|
||||
}
|
||||
|
||||
void
|
||||
AudioFileSource::handle_header_position_change (struct tm* now, time_t tnow)
|
||||
{
|
||||
/* don't do this if the file has never had its header flushed to disk yet */
|
||||
|
||||
if (writable() && _timestamp) {
|
||||
set_header_timeline_position ();
|
||||
flush_header ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioFileSource::set_allow_remove_if_empty (bool yn)
|
||||
{
|
||||
|
|
@ -655,8 +649,14 @@ AudioFileSource::set_name (string newname, bool destructive)
|
|||
bool
|
||||
AudioFileSource::is_empty (string path)
|
||||
{
|
||||
/* XXX fix me */
|
||||
bool ret = false;
|
||||
AudioFileSource* afs = create (path, NoPeakFile);
|
||||
|
||||
return false;
|
||||
if (afs) {
|
||||
ret = (afs->length() == 0);
|
||||
delete afs;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <pbd/error.h>
|
||||
|
||||
#include <ardour/coreaudio_source.h>
|
||||
#include <ardour/coreaudiosource.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -31,22 +30,21 @@ using namespace PBD;
|
|||
CoreAudioSource::CoreAudioSource (const XMLNode& node)
|
||||
: AudioFileSource (node)
|
||||
{
|
||||
init (_name, true);
|
||||
init (_name);
|
||||
|
||||
AudioSourceCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
CoreAudioSource::CoreAudioSource (const string& idstr, bool build_peak)
|
||||
: AudioFileSource(idstr, build_peak)
|
||||
CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags)
|
||||
: AudioFileSource(idstr, flags)
|
||||
{
|
||||
init (idstr, build_peak);
|
||||
init (idstr);
|
||||
|
||||
if (build_peak) {
|
||||
AudioSourceCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CoreAudioSource::init (const string& idstr, bool build_peak)
|
||||
CoreAudioSource::init (const string& idstr)
|
||||
{
|
||||
string::size_type pos;
|
||||
string file;
|
||||
|
|
@ -132,7 +130,7 @@ CoreAudioSource::init (const string& idstr, bool build_peak)
|
|||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
if (build_peak) {
|
||||
if (_build_peakfiles) {
|
||||
if (initialize_peakfile (false, file)) {
|
||||
error << "initialize peakfile failed" << endmsg;
|
||||
ExtAudioFileDispose (af);
|
||||
|
|
@ -155,7 +153,7 @@ CoreAudioSource::~CoreAudioSource ()
|
|||
}
|
||||
|
||||
jack_nframes_t
|
||||
CoreAudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
|
||||
CoreAudioSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
|
||||
{
|
||||
OSStatus err = noErr;
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: libardour 0.664.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 15:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2003-05-21 12:50+0500\n"
|
||||
"Last-Translator: Muadibas\n"
|
||||
"Language-Team: Hellenic(Greek)\n"
|
||||
|
|
@ -198,77 +198,77 @@ msgid "programming error: AudioTrack given state without diskstream!"
|
|||
msgstr ""
|
||||
"σφάλμα προγραμματισμού: εδόθη κατάσταση στην AudioTrack δίχως diskstream!"
|
||||
|
||||
#: libs/ardour/audioengine.cc:150
|
||||
#: libs/ardour/audioengine.cc:144
|
||||
msgid "cannot activate JACK client"
|
||||
msgstr "Ο JACK δεν μπορεί να ενεργοποιηθεί"
|
||||
|
||||
#: libs/ardour/audioengine.cc:401
|
||||
#: libs/ardour/audioengine.cc:395
|
||||
msgid "register audio input port called before engine was started"
|
||||
msgstr "η register audio input port εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:432
|
||||
#: libs/ardour/audioengine.cc:426
|
||||
msgid "register audio output port called before engine was started"
|
||||
msgstr "η register audio output port εκλήθη πρίν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:493
|
||||
#: libs/ardour/audioengine.cc:487
|
||||
msgid "connect called before engine was started"
|
||||
msgstr "η σύνδεση εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:509
|
||||
#: libs/ardour/audioengine.cc:503
|
||||
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:522 libs/ardour/audioengine.cc:551
|
||||
#: libs/ardour/audioengine.cc:516 libs/ardour/audioengine.cc:545
|
||||
msgid "disconnect called before engine was started"
|
||||
msgstr "η αποσύνδεση εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:609
|
||||
#: libs/ardour/audioengine.cc:603
|
||||
msgid "get_port_by_name() called before engine was started"
|
||||
msgstr "η ρουτίνα get_port_by_name() εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:642
|
||||
#: libs/ardour/audioengine.cc:636
|
||||
msgid "get_ports called before engine was started"
|
||||
msgstr "η ρουτίνα get_ports εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:717
|
||||
#: libs/ardour/audioengine.cc:711
|
||||
msgid "get_nth_physical called before engine was started"
|
||||
msgstr "η ρουτίνα get_nth_physical εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:745
|
||||
#: libs/ardour/audioengine.cc:739
|
||||
#, fuzzy
|
||||
msgid "get_port_total_latency() called with no JACK client connection"
|
||||
msgstr "η ρουτίνα get_port_total_latency() εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:751
|
||||
#: libs/ardour/audioengine.cc:745
|
||||
msgid "get_port_total_latency() called before engine was started"
|
||||
msgstr "η ρουτίνα get_port_total_latency() εκλήθη πριν να εκκινηθεί η engine"
|
||||
|
||||
#: libs/ardour/audioengine.cc:875
|
||||
#: libs/ardour/audioengine.cc:869
|
||||
msgid "Unable to connect to JACK server"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:878
|
||||
#: libs/ardour/audioengine.cc:872
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:883
|
||||
#: libs/ardour/audioengine.cc:877
|
||||
msgid "JACK server started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:917
|
||||
#: libs/ardour/audioengine.cc:911
|
||||
msgid "cannot shutdown connection to JACK"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:942
|
||||
#: libs/ardour/audioengine.cc:936
|
||||
msgid "failed to connect to JACK"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:958
|
||||
#: libs/ardour/audioengine.cc:952
|
||||
#, fuzzy
|
||||
msgid "could not reregister %1"
|
||||
msgstr "Σφάλμα: δεν μπόρεσα να γράψω %1"
|
||||
|
||||
#: libs/ardour/audioengine.cc:1015
|
||||
#: libs/ardour/audioengine.cc:1009
|
||||
msgid "could not reconnect %1 and %2 (err = %3)"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: libardour 0.664.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 15:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2003-05-21 12:50+0500\n"
|
||||
"Last-Translator: Filippo Pappalardo <filippo@email.it>\n"
|
||||
"Language-Team: Italian\n"
|
||||
|
|
@ -183,88 +183,88 @@ msgstr ""
|
|||
msgid "programming error: AudioTrack given state without diskstream!"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:150
|
||||
#: libs/ardour/audioengine.cc:144
|
||||
msgid "cannot activate JACK client"
|
||||
msgstr "impossibile attivare il client JACK"
|
||||
|
||||
#: libs/ardour/audioengine.cc:401
|
||||
#: libs/ardour/audioengine.cc:395
|
||||
msgid "register audio input port called before engine was started"
|
||||
msgstr ""
|
||||
"la richiesta di registrazione di una porta di entrata avvenuta prima "
|
||||
"dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:432
|
||||
#: libs/ardour/audioengine.cc:426
|
||||
msgid "register audio output port called before engine was started"
|
||||
msgstr ""
|
||||
"la richiesta di registrazione di una porta di uscita avvenuta prima "
|
||||
"dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:493
|
||||
#: libs/ardour/audioengine.cc:487
|
||||
msgid "connect called before engine was started"
|
||||
msgstr "richiesta di connessione avvenuta prima dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:509
|
||||
#: libs/ardour/audioengine.cc:503
|
||||
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:522 libs/ardour/audioengine.cc:551
|
||||
#: libs/ardour/audioengine.cc:516 libs/ardour/audioengine.cc:545
|
||||
msgid "disconnect called before engine was started"
|
||||
msgstr ""
|
||||
"richiesta di disconnessione avvenuta prima dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:609
|
||||
#: libs/ardour/audioengine.cc:603
|
||||
msgid "get_port_by_name() called before engine was started"
|
||||
msgstr ""
|
||||
"richiesta get_port_by_name() avvenuta prima dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:642
|
||||
#: libs/ardour/audioengine.cc:636
|
||||
msgid "get_ports called before engine was started"
|
||||
msgstr "richiesta di get_ports avvenuta prima dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:717
|
||||
#: libs/ardour/audioengine.cc:711
|
||||
msgid "get_nth_physical called before engine was started"
|
||||
msgstr ""
|
||||
"richiesta di get_nth_physical avvenuta prima dell'avvio dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:745
|
||||
#: libs/ardour/audioengine.cc:739
|
||||
#, fuzzy
|
||||
msgid "get_port_total_latency() called with no JACK client connection"
|
||||
msgstr ""
|
||||
"richiesta di get_port_total_latency() avvenuta prima dell'avvio "
|
||||
"dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:751
|
||||
#: libs/ardour/audioengine.cc:745
|
||||
msgid "get_port_total_latency() called before engine was started"
|
||||
msgstr ""
|
||||
"richiesta di get_port_total_latency() avvenuta prima dell'avvio "
|
||||
"dell'applicazione"
|
||||
|
||||
#: libs/ardour/audioengine.cc:875
|
||||
#: libs/ardour/audioengine.cc:869
|
||||
msgid "Unable to connect to JACK server"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:878
|
||||
#: libs/ardour/audioengine.cc:872
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:883
|
||||
#: libs/ardour/audioengine.cc:877
|
||||
msgid "JACK server started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:917
|
||||
#: libs/ardour/audioengine.cc:911
|
||||
msgid "cannot shutdown connection to JACK"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:942
|
||||
#: libs/ardour/audioengine.cc:936
|
||||
msgid "failed to connect to JACK"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:958
|
||||
#: libs/ardour/audioengine.cc:952
|
||||
#, fuzzy
|
||||
msgid "could not reregister %1"
|
||||
msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)"
|
||||
|
||||
#: libs/ardour/audioengine.cc:1015
|
||||
#: libs/ardour/audioengine.cc:1009
|
||||
msgid "could not reconnect %1 and %2 (err = %3)"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: libardour 0.716.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-06-21 15:09-0400\n"
|
||||
"POT-Creation-Date: 2006-06-27 13:00-0400\n"
|
||||
"PO-Revision-Date: 2004-03-31 00:55+0300\n"
|
||||
"Last-Translator: Igor Blinov pitstop@nm.ru\n"
|
||||
"Language-Team: Russian\n"
|
||||
|
|
@ -171,75 +171,75 @@ msgstr ""
|
|||
msgid "programming error: AudioTrack given state without diskstream!"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:150
|
||||
#: libs/ardour/audioengine.cc:144
|
||||
msgid "cannot activate JACK client"
|
||||
msgstr "ÎÅ ÕÄÁÌÏÓØ ÁËÔÉ×ÉÒÏ×ÁÔØ ËÌÉÅÎÔÁ JACK ÓÅÒ×ÅÒÁ"
|
||||
|
||||
#: libs/ardour/audioengine.cc:401
|
||||
#: libs/ardour/audioengine.cc:395
|
||||
msgid "register audio input port called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:432
|
||||
#: libs/ardour/audioengine.cc:426
|
||||
msgid "register audio output port called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:493
|
||||
#: libs/ardour/audioengine.cc:487
|
||||
msgid "connect called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:509
|
||||
#: libs/ardour/audioengine.cc:503
|
||||
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:522 libs/ardour/audioengine.cc:551
|
||||
#: libs/ardour/audioengine.cc:516 libs/ardour/audioengine.cc:545
|
||||
msgid "disconnect called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:609
|
||||
#: libs/ardour/audioengine.cc:603
|
||||
msgid "get_port_by_name() called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:642
|
||||
#: libs/ardour/audioengine.cc:636
|
||||
msgid "get_ports called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:717
|
||||
#: libs/ardour/audioengine.cc:711
|
||||
msgid "get_nth_physical called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:745
|
||||
#: libs/ardour/audioengine.cc:739
|
||||
msgid "get_port_total_latency() called with no JACK client connection"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:751
|
||||
#: libs/ardour/audioengine.cc:745
|
||||
msgid "get_port_total_latency() called before engine was started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:875
|
||||
#: libs/ardour/audioengine.cc:869
|
||||
msgid "Unable to connect to JACK server"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:878
|
||||
#: libs/ardour/audioengine.cc:872
|
||||
msgid "Could not connect to JACK server as \"%1\""
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:883
|
||||
#: libs/ardour/audioengine.cc:877
|
||||
msgid "JACK server started"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:917
|
||||
#: libs/ardour/audioengine.cc:911
|
||||
msgid "cannot shutdown connection to JACK"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:942
|
||||
#: libs/ardour/audioengine.cc:936
|
||||
msgid "failed to connect to JACK"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:958
|
||||
#: libs/ardour/audioengine.cc:952
|
||||
msgid "could not reregister %1"
|
||||
msgstr ""
|
||||
|
||||
#: libs/ardour/audioengine.cc:1015
|
||||
#: libs/ardour/audioengine.cc:1009
|
||||
msgid "could not reconnect %1 and %2 (err = %3)"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@ Session::set_smpte_offset_negative (bool neg)
|
|||
SMPTEOffsetChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Session::smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ SndFileSource::SndFileSource (const XMLNode& node)
|
|||
}
|
||||
|
||||
SndFileSource::SndFileSource (string idstr, Flag flags)
|
||||
/* files created this way are never writable or removable */
|
||||
: AudioFileSource (idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
|
||||
{
|
||||
init (idstr);
|
||||
|
|
@ -63,7 +64,7 @@ SndFileSource::SndFileSource (string idstr, Flag flags)
|
|||
throw failed_constructor ();
|
||||
}
|
||||
|
||||
if (_build_peakfiles) {
|
||||
if (!(_flags & NoPeakFile) && _build_peakfiles) {
|
||||
if (initialize_peakfile (false, _path)) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
|
|
@ -170,9 +171,10 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
|
|||
delete _broadcast_info;
|
||||
_broadcast_info = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_build_peakfiles) {
|
||||
if (!(_flags & NoPeakFile) && _build_peakfiles) {
|
||||
if (initialize_peakfile (true, _path)) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
|
|
@ -180,12 +182,6 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
|
|||
}
|
||||
}
|
||||
|
||||
/* since SndFileSource's constructed with this constructor can be writable, make sure we update if the header info changes */
|
||||
|
||||
if (writable()) {
|
||||
HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change));
|
||||
}
|
||||
|
||||
AudioSourceCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
|
|
@ -235,34 +231,56 @@ SndFileSource::open ()
|
|||
|
||||
_length = _info.frames;
|
||||
|
||||
|
||||
_broadcast_info = (SF_BROADCAST_INFO*) calloc (1, sizeof (SF_BROADCAST_INFO));
|
||||
|
||||
/* lookup broadcast info */
|
||||
|
||||
if (sf_command (sf, SFC_GET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
|
||||
|
||||
/* if the file has data but no broadcast info, then clearly, there is no broadcast info */
|
||||
|
||||
if (_length) {
|
||||
free (_broadcast_info);
|
||||
_broadcast_info = 0;
|
||||
_flags = Flag (_flags & ~Broadcast);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
|
||||
of the time reference.
|
||||
*/
|
||||
|
||||
set_timeline_position (_broadcast_info->time_reference_low);
|
||||
}
|
||||
|
||||
if (writable()) {
|
||||
sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
|
||||
|
||||
/* update header if header offset info changes */
|
||||
|
||||
AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SndFileSource::close ()
|
||||
{
|
||||
if (sf) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SndFileSource::~SndFileSource ()
|
||||
{
|
||||
GoingAway (this); /* EMIT SIGNAL */
|
||||
|
||||
close ();
|
||||
if (sf) {
|
||||
sf_close (sf);
|
||||
sf = 0;
|
||||
}
|
||||
|
||||
if (interleave_buf) {
|
||||
delete [] interleave_buf;
|
||||
}
|
||||
|
||||
if (_broadcast_info) {
|
||||
delete [] _broadcast_info;
|
||||
free (_broadcast_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -404,27 +422,38 @@ SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt, char * workbuf)
|
|||
int
|
||||
SndFileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
|
||||
{
|
||||
/* allow derived classes to override how this is done */
|
||||
|
||||
set_timeline_position (when);
|
||||
|
||||
if (_flags & Broadcast) {
|
||||
/* this will flush the header implicitly */
|
||||
return setup_broadcast_info (when, now, tnow);
|
||||
} else {
|
||||
return flush_header ();
|
||||
if (setup_broadcast_info (when, now, tnow)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return flush_header ();
|
||||
}
|
||||
|
||||
int
|
||||
SndFileSource::flush_header ()
|
||||
{
|
||||
if (!writable() || (sf == 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t tnow)
|
||||
{
|
||||
if (!writable()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(_flags & Broadcast)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* random code is 9 digits */
|
||||
|
||||
int random_code = random() % 999999999;
|
||||
|
|
@ -452,12 +481,10 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t
|
|||
|
||||
set_header_timeline_position ();
|
||||
|
||||
/* note that libsndfile flushes the header to disk when resetting the broadcast info */
|
||||
|
||||
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
|
||||
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
|
||||
_flags = Flag (_flags & ~Broadcast);
|
||||
delete _broadcast_info;
|
||||
free (_broadcast_info);
|
||||
_broadcast_info = 0;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -470,6 +497,10 @@ SndFileSource::set_header_timeline_position ()
|
|||
{
|
||||
uint64_t pos;
|
||||
|
||||
if (!(_flags & Broadcast)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_broadcast_info->time_reference_high = 0;
|
||||
|
||||
if (header_position_negative) {
|
||||
|
|
@ -491,6 +522,13 @@ SndFileSource::set_header_timeline_position ()
|
|||
|
||||
_broadcast_info->time_reference_high = (pos >> 32);
|
||||
_broadcast_info->time_reference_low = (pos & 0xffffffff);
|
||||
|
||||
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
|
||||
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
|
||||
_flags = Flag (_flags & ~Broadcast);
|
||||
free (_broadcast_info);
|
||||
_broadcast_info = 0;
|
||||
}
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
ClReader-lex.cc
|
||||
ClReader.cc
|
||||
ClReader.cc.h
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
Announcing the release of a free (for research use) constraint solver:
|
||||
|
||||
Cassowary Constraint Solver for Smalltalk, C++, and Java
|
||||
Version 0.60
|
||||
|
||||
Web Page: http://www.cs.washington.edu/research/constraints/cassowary
|
||||
Distribution: ftp://ftp.cs.washington.edu:/pub/constraints/code/cassowary/
|
||||
Contact: cassowary@cs.washington.edu
|
||||
|
||||
Greg J. Badros <gjb@cs.washington.edu> and
|
||||
Alan Borning <borning@cs.washington.edu>
|
||||
University of Washington
|
||||
Computer Science and Engineering
|
||||
15-December-1999
|
||||
|
||||
with Constraint Drawing Applet (CDA) by Michael Noth <noth@cs.washington.edu>
|
||||
|
||||
Cassowary is an incremental constraint solving toolkit that efficiently
|
||||
solves systems of linear equalities and inequalities. Constraints may
|
||||
be either requirements or preferences. Client code specifies the
|
||||
constraints to be maintained, and the solver updates the constrained
|
||||
variables to have values that satisfy the constraints.
|
||||
|
||||
A technical report is included in the distribution that describes the
|
||||
algorithm, interface, and implementation of the Cassowary solver.
|
||||
Additionally, the distribution contains toy sample applications written
|
||||
in Smalltalk, C++, Java, and Python, and a more complex example Java
|
||||
applet, the "Constraint Drawing Application".
|
||||
|
||||
More information is available on our web page:
|
||||
|
||||
http://www.cs.washington.edu/research/constraints/cassowary
|
||||
|
||||
See README for more details on getting started using these packages.
|
||||
See NEWS for a history of user-visible changes.
|
||||
See LICENSE for legalese regarding use of this distribution.
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
Cassowary Constraint Solving Toolkit was
|
||||
Implemented by:
|
||||
|
||||
Greg J. Badros <gjb@cs.washington.edu> and
|
||||
Alan Borning <borning@cs.washington.edu>
|
||||
University of Washington
|
||||
Computer Science and Engineering
|
||||
Seattle, WA 98195-2350
|
||||
|
||||
with Constraint Drawing Applet (CDA) by Michael Noth <noth@cs.washington.edu>
|
||||
|
||||
Please send bug reports to cassowary@cs.washington.edu
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
|
@ -1,444 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to
|
||||
share and change it. By contrast, the GNU General Public Licenses are
|
||||
intended to guarantee your freedom to share and change free software--to
|
||||
make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the Free
|
||||
Software Foundation and other authors who decide to use it. You can use
|
||||
it too, but we suggest you first think carefully about whether this
|
||||
license or the ordinary General Public License is the better strategy to
|
||||
use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish); that you receive source code or can get it if
|
||||
you want it; that you can change the software and use pieces of it in
|
||||
new free programs; and that you are informed that you can do these
|
||||
things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for you
|
||||
if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis or
|
||||
for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide complete
|
||||
object files to the recipients, so that they can relink them with the
|
||||
library after making changes to the library and recompiling it. And you
|
||||
must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that there is
|
||||
no warranty for the free library. Also, if the library is modified by
|
||||
someone else and passed on, the recipients should know that what they
|
||||
have is not the original version, so that the original author's
|
||||
reputation will not be affected by problems that might be introduced by
|
||||
others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of any
|
||||
free program. We wish to make sure that a company cannot effectively
|
||||
restrict the users of a free program by obtaining a restrictive license
|
||||
from a patent holder. Therefore, we insist that any patent license
|
||||
obtained for a version of the library must be consistent with the full
|
||||
freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License. This license, the GNU Lesser General Public
|
||||
License, applies to certain designated libraries, and is quite different
|
||||
from the ordinary General Public License. We use this license for
|
||||
certain libraries in order to permit linking those libraries into
|
||||
non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using a
|
||||
shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the entire
|
||||
combination fits its criteria of freedom. The Lesser General Public
|
||||
License permits more lax criteria for linking other code with the
|
||||
library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it does
|
||||
Less to protect the user's freedom than the ordinary General Public
|
||||
License. It also provides other free software developers Less of an
|
||||
advantage over competing non-free programs. These disadvantages are the
|
||||
reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to encourage
|
||||
the widest possible use of a certain library, so that it becomes a
|
||||
de-facto standard. To achieve this, non-free programs must be allowed to
|
||||
use the library. A more frequent case is that a free library does the
|
||||
same job as widely used non-free libraries. In this case, there is
|
||||
little to gain by limiting the free library to free software only, so we
|
||||
use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of free
|
||||
software. For example, permission to use the GNU C Library in non-free
|
||||
programs enables many more people to use the whole GNU operating system,
|
||||
as well as its variant, the GNU/Linux operating system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is linked
|
||||
with the Library has the freedom and the wherewithal to run that program
|
||||
using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or other
|
||||
authorized party saying it may be distributed under the terms of this
|
||||
Lesser General Public License (also called "this License"). Each
|
||||
licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work which
|
||||
has been distributed under these terms. A "work based on the Library"
|
||||
means either the Library or any derivative work under copyright law:
|
||||
that is to say, a work containing the Library or a portion of it, either
|
||||
verbatim or with modifications and/or translated straightforwardly into
|
||||
another language. (Hereinafter, translation is included without
|
||||
limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for making
|
||||
modifications to it. For a library, complete source code means all the
|
||||
source code for all modules it contains, plus any associated interface
|
||||
definition files, plus the scripts used to control compilation and
|
||||
installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of running
|
||||
a program using the Library is not restricted, and output from such a
|
||||
program is covered only if its contents constitute a work based on the
|
||||
Library (independent of the use of the Library in a tool for writing
|
||||
it). Whether that is true depends on what the Library does and what the
|
||||
program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's complete
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the notices
|
||||
that refer to this License and to the absence of any warranty; and
|
||||
distribute a copy of this License along with the Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion of
|
||||
it, thus forming a work based on the Library, and copy and distribute
|
||||
such modifications or work under the terms of Section 1 above, provided
|
||||
that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library. b) You
|
||||
must cause the files modified to carry prominent notices stating
|
||||
that you changed the files and the date of any change. c) You
|
||||
must cause the whole of the work to be licensed at no charge to
|
||||
all third parties under the terms of this License. d) If a
|
||||
facility in the modified Library refers to a function or a table
|
||||
of data to be supplied by an application program that uses the
|
||||
facility, other than as an argument passed when the facility is
|
||||
invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the
|
||||
Library, and can be reasonably considered independent and
|
||||
separate works in themselves, then this License, and its terms,
|
||||
do not apply to those sections when you distribute them as
|
||||
separate works. But when you distribute the same sections as part
|
||||
of a whole which is a work based on the Library, the distribution
|
||||
of the whole must be on the terms of this License, whose
|
||||
permissions for other licensees extend to the entire whole, and
|
||||
thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or
|
||||
contest your rights to work written entirely by you; rather, the
|
||||
intent is to exercise the right to control the distribution of
|
||||
derivative or collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the
|
||||
Library with the Library (or with a work based on the Library) on
|
||||
a volume of a storage or distribution medium does not bring the
|
||||
other work under the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so that
|
||||
they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in these
|
||||
notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for that
|
||||
copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of the
|
||||
Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or derivative
|
||||
of it, under Section 2) in object code or executable form under the
|
||||
terms of Sections 1 and 2 above provided that you accompany it with the
|
||||
complete corresponding machine-readable source code, which must be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy from a
|
||||
designated place, then offering equivalent access to copy the source
|
||||
code from the same place satisfies the requirement to distribute the
|
||||
source code, even though third parties are not compelled to copy the
|
||||
source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the Library,
|
||||
but is designed to work with the Library by being compiled or linked
|
||||
with it, is called a "work that uses the Library". Such a work, in
|
||||
isolation, is not a derivative work of the Library, and therefore falls
|
||||
outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library creates
|
||||
an executable that is a derivative of the Library (because it contains
|
||||
portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License. Section 6
|
||||
states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is
|
||||
not. Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data structure
|
||||
layouts and accessors, and small macros and small inline functions (ten
|
||||
lines or less in length), then the use of the object file is
|
||||
unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section
|
||||
6. Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or link a
|
||||
"work that uses the Library" with the Library to produce a work
|
||||
containing portions of the Library, and distribute that work under terms
|
||||
of your choice, provided that the terms permit modification of the work
|
||||
for the customer's own use and reverse engineering for debugging such
|
||||
modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work during
|
||||
execution displays copyright notices, you must include the copyright
|
||||
notice for the Library among them, as well as a reference directing the
|
||||
user to the copy of this License. Also, you must do one of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in
|
||||
the Library will not necessarily be able to recompile the
|
||||
application to use the modified definitions.) b) Use a suitable
|
||||
shared library mechanism for linking with the Library. A suitable
|
||||
mechanism is one that (1) uses at run time a copy of the library
|
||||
already present on the user's computer system, rather than
|
||||
copying library functions into the executable, and (2) will
|
||||
operate properly with a modified version of the library, if the
|
||||
user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made
|
||||
with. c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials specified
|
||||
in Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution. d) If distribution of the work is
|
||||
made by offering access to copy from a designated place, offer
|
||||
equivalent access to copy the above specified materials from the
|
||||
same place. e) Verify that the user has already received a copy
|
||||
of these materials or that you have already sent this user a
|
||||
copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the Library"
|
||||
must include any data and utility programs needed for reproducing the
|
||||
executable from it. However, as a special exception, the materials to be
|
||||
distributed need not include anything that is normally distributed (in
|
||||
either source or binary form) with the major components (compiler,
|
||||
kernel, and so on) of the operating system on which the executable runs,
|
||||
unless that component itself accompanies the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license restrictions
|
||||
of other proprietary libraries that do not normally accompany the
|
||||
operating system. Such a contradiction means you cannot use both them
|
||||
and the Library together in an executable that you distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the Library
|
||||
side-by-side in a single library together with other library facilities
|
||||
not covered by this License, and distribute such a combined library,
|
||||
provided that the separate distribution of the work based on the Library
|
||||
and of the other library facilities is otherwise permitted, and provided
|
||||
that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above. b) Give prominent notice with the combined
|
||||
library of the fact that part of it is a work based on the
|
||||
Library, and explaining where to find the accompanying uncombined
|
||||
form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute the
|
||||
Library except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense, link with, or distribute the
|
||||
Library is void, and will automatically terminate your rights under this
|
||||
License. However, parties who have received copies, or rights, from you
|
||||
under this License will not have their licenses terminated so long as
|
||||
such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and all
|
||||
its terms and conditions for copying, distributing or modifying the
|
||||
Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted
|
||||
herein. You are not responsible for enforcing compliance by third
|
||||
parties with this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot distribute
|
||||
so as to satisfy simultaneously your obligations under this License and
|
||||
any other pertinent obligations, then as a consequence you may not
|
||||
distribute the Library at all. For example, if a patent license would
|
||||
not permit royalty-free redistribution of the Library by all those who
|
||||
receive copies directly or indirectly through you, then the only way you
|
||||
could satisfy both it and this License would be to refrain entirely from
|
||||
distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is implemented
|
||||
by public license practices. Many people have made generous
|
||||
contributions to the wide range of software distributed through that
|
||||
system in reliance on consistent application of that system; it is up to
|
||||
the author/donor to decide if he or she is willing to distribute
|
||||
software through any other system and a licensee cannot impose that
|
||||
choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to be
|
||||
a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may
|
||||
add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among countries
|
||||
not thus excluded. In such case, this License incorporates the
|
||||
limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new versions
|
||||
of the Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a license
|
||||
version number, you may choose any version ever published by the Free
|
||||
Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free Software
|
||||
Foundation; we sometimes make exceptions for this. Our decision will be
|
||||
guided by the two goals of preserving the free status of all derivatives
|
||||
of our free software and of promoting the sharing and reuse of software
|
||||
generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
|
||||
YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
||||
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY
|
||||
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
|
||||
THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR
|
||||
OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,23 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClAbstractVariable.cc
|
||||
|
||||
#include <cassowary/ClAbstractVariable.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
long ClAbstractVariable::iVariableNumber = 0;
|
||||
#ifdef CL_FIND_LEAK
|
||||
long ClAbstractVariable::cAbstractVariables = 0;
|
||||
#endif
|
||||
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
// $Id$
|
||||
|
||||
#include <cassowary/Cl.h>
|
||||
|
||||
/* This bug fixed --02/15/99 gjb
|
||||
Replaced the parallel vectors for edit constraints
|
||||
(the errorPlus..., errorMinus..., prevEditConstants vectors)
|
||||
with a ClEditInfo class that is the Value of the _editVarMap map.
|
||||
|
||||
Later I realized that I need to go to a _editVars list so that
|
||||
multiple edits on the same variable that nest are handled properly.
|
||||
--09/19/99 gjb
|
||||
*/
|
||||
|
||||
int main()
|
||||
{
|
||||
ClSimplexSolver solver;
|
||||
|
||||
ClVariable x("x",7);
|
||||
ClVariable y("y",8);
|
||||
ClVariable z("z",9);
|
||||
|
||||
solver
|
||||
.AddStay(x)
|
||||
.AddStay(y)
|
||||
.AddStay(z);
|
||||
|
||||
try {
|
||||
solver.AddEditVar(x);
|
||||
solver.AddEditVar(y);
|
||||
solver.AddEditVar(z);
|
||||
solver.BeginEdit();
|
||||
|
||||
solver.SuggestValue(x,1);
|
||||
solver.SuggestValue(z,2);
|
||||
|
||||
solver.RemoveEditVar(y);
|
||||
|
||||
solver.SuggestValue(x,3);
|
||||
solver.SuggestValue(z,4);
|
||||
|
||||
solver.EndEdit();
|
||||
|
||||
} catch (ExCLError &e) {
|
||||
cerr << e.description() << endl;
|
||||
}
|
||||
|
||||
cout << x << endl << y << endl << z <<endl;
|
||||
|
||||
}
|
||||
|
||||
#if 0 /* Message below */
|
||||
From: "Michael Kaufmann" <Michael.Kaufmann@ubs.com>
|
||||
To: <noth@cs.washington.edu>
|
||||
Subject: bugreport
|
||||
Date: Thu, 1 Oct 1998 11:40:55 +0200
|
||||
Message-Id: <000001bded1f$973a2060$230e1fac@itc_mk.sbcs.swissbank.com>
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain;
|
||||
charset="iso-8859-1"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Priority: 3 (Normal)
|
||||
X-Msmail-Priority: Normal
|
||||
X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0
|
||||
Importance: Normal
|
||||
X-Mimeole: Produced By Microsoft MimeOLE V4.72.2106.4
|
||||
|
||||
Dear Mr Noth,
|
||||
|
||||
I am currently working with the Java implementation of Cassowary and found
|
||||
the following bug:
|
||||
|
||||
If I Add several editConstraints, remove some of them again later and
|
||||
perform a 'ClSimplexSolver.SuggestValue()', the indices of
|
||||
'ClConstraintAndIndex' in the variable 'cai' are sometimes wrong (see
|
||||
ClSimplexSolver.SuggestValue(ClVariable v, double x), the 3rd line). This is
|
||||
because if you remove an element from a 'java.util.Vector', and the element
|
||||
is somewhere in the middle of the Vector, the indices of the Vector change.
|
||||
(see java.util.Vector.removeElementAt(int index):
|
||||
|
||||
public final synchronized void removeElementAt(int index) {
|
||||
if (index >= elementCount) {
|
||||
throw new ArrayIndexOutOfBoundsException(index + " >= " +
|
||||
elementCount);
|
||||
}
|
||||
else if (index < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException(index);
|
||||
}
|
||||
int j = elementCount - index - 1;
|
||||
if (j > 0) {
|
||||
System.arraycopy(elementData, index + 1, elementData, index, j);
|
||||
}
|
||||
elementCount--;
|
||||
elementData[elementCount] = null; /* to let gc do its work */
|
||||
}
|
||||
|
||||
|
||||
My workaround now is, that everytime when I remove an EditVariable from the
|
||||
Solver, I have to remove all the EditVariables and Add then the ones again,
|
||||
that I do not want to remove.
|
||||
|
||||
#endif
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#include <cassowary/Cl.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
ClVariable *var = new ClVariable();
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),1.0);
|
||||
|
||||
cout << *solver;
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
/*
|
||||
The result is a segmentation fault when the constraint is removed. I
|
||||
don't understand why.
|
||||
|
||||
Anthony Beurive'" <beurive@labri.u-bordeaux.fr>
|
||||
*/
|
||||
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
/* $Id$
|
||||
|
||||
From: "Anthony Beurive'" <beurive@labri.u-bordeaux.fr>
|
||||
Subject: cassowary
|
||||
To: gjb@cs.washington.edu
|
||||
Date: Tue, 9 Mar 1999 12:42:24 +0100 (CET)
|
||||
|
||||
I believe there's a bug in cassowary. It seems to be related to the
|
||||
previous one I encountered a while ago, concerning the removal of
|
||||
constraints.
|
||||
|
||||
The three following examples may help you to track the bug, I hope.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
#include "Cl.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClVariable *var = new ClVariable();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),1.0);
|
||||
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
This works fine.
|
||||
|
||||
|
||||
Now, the factor of the stay constraint is changed.
|
||||
--------------------------------------------------------------------------------
|
||||
#include "Cl.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClVariable *var = new ClVariable();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0);
|
||||
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
The result is:
|
||||
test2: ClSimplexSolver.cc:1199: void ClSimplexSolver::Optimize(class ClVariable): Assertion \
|
||||
`pzRow != __null' failed.
|
||||
Aborted
|
||||
|
||||
|
||||
Now, the solver is created after the variable.
|
||||
--------------------------------------------------------------------------------
|
||||
#include "Cl.h"
|
||||
|
||||
void main()
|
||||
{
|
||||
ClVariable *var = new ClVariable();
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0);
|
||||
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
This works again.
|
||||
|
||||
|
||||
Can you reproduce the same results? Maybe the cause is my c++
|
||||
compiler (egcs-2.90.29 980515 (egcs-1.0.3 release)). I don't know.
|
||||
|
||||
*/
|
||||
|
||||
#include <cassowary/Cl.h>
|
||||
|
||||
void foo1()
|
||||
{
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClVariable *var = new ClVariable();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),1.0);
|
||||
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
|
||||
|
||||
void foo2()
|
||||
{
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClVariable *var = new ClVariable();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0);
|
||||
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
|
||||
|
||||
void foo3()
|
||||
{
|
||||
ClVariable *var = new ClVariable();
|
||||
ClSimplexSolver *solver = new ClSimplexSolver();
|
||||
ClStayConstraint *stcn = new ClStayConstraint(*var,ClsWeak(),2.0);
|
||||
|
||||
solver->AddConstraint(*stcn);
|
||||
cout << *solver;
|
||||
solver->RemoveConstraint(*stcn);
|
||||
cout << *solver;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
cerr << "Test1: " << endl;
|
||||
foo1();
|
||||
|
||||
cerr << "\nTest2: " << endl;
|
||||
foo2();
|
||||
|
||||
cerr << "\nTest3: " << endl;
|
||||
foo3();
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClConstraint.cc
|
||||
|
||||
#include <cassowary/ClConstraint.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
#include <cassowary/ClTableau.h> // for VarSet printing
|
||||
|
||||
ostream &
|
||||
ClConstraint::PrintOn(ostream &xo) const
|
||||
{
|
||||
// Note that the trailing "= 0)" or ">= 0)" is missing, as derived classes will
|
||||
// print the right thing after calling this function
|
||||
xo << strength() << " w{" << weight() << "} ta{"
|
||||
<< _times_added << "} RO" << _readOnlyVars << " " << "(" << Expression();
|
||||
return xo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// $Id$
|
||||
|
||||
#include <cassowary/ClDummyVariable.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifdef CL_FIND_LEAK
|
||||
long ClDummyVariable::cDummyVariables = 0;
|
||||
#endif
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDBinaryOneWayConstraint.cc
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cassowary/ClFDBinaryOneWayConstraint.h>
|
||||
#include <cassowary/ClLinearConstraint.h>
|
||||
#include <cassowary/ClTypedefs.h>
|
||||
#include <cassowary/ClLinearExpression.h>
|
||||
|
||||
|
||||
void
|
||||
ClFDBinaryOneWayConstraint::EnsurePreconditionsForCn(const ClConstraint &cn)
|
||||
{
|
||||
ClVarSet setRO = cn.ReadOnlyVars();
|
||||
if (setRO.size() > 1)
|
||||
throw ExCLTooDifficultSpecial("Only 0 or 1 read only variables are allowed");
|
||||
const ClLinearExpression &expr = cn.Expression();
|
||||
const ClVarToNumberMap &terms = expr.Terms();
|
||||
if (terms.size() > 2)
|
||||
throw ExCLTooDifficultSpecial("Cannot have more than 2 variables");
|
||||
if (terms.size() == 0)
|
||||
throw ExCLTooDifficultSpecial("Must have at least 1 variable");
|
||||
if (terms.size() == 2 && setRO.size() == 0)
|
||||
throw ExCLTooDifficultSpecial("Both variables cannot be read-write, one must be read-only");
|
||||
if (terms.size() == 1 && setRO.size() == 1)
|
||||
throw ExCLTooDifficultSpecial("Single read-only variable in LinearConstraint -- must not be read-only.");
|
||||
ClVariable clv = (*terms.begin()).first;
|
||||
/* GJB:FIXME:: iterate over all the variables */
|
||||
if (!clv->IsFDVariable()) {
|
||||
throw ExCLTooDifficultSpecial("FD constraint contains non-FD variables");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ClFDBinaryOneWayConstraint::FCanConvertCn(const ClConstraint &cn)
|
||||
{
|
||||
try {
|
||||
EnsurePreconditionsForCn(cn);
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ClFDBinaryOneWayConstraint::ClFDBinaryOneWayConstraint(const ClConstraint &cn)
|
||||
:ClFDConstraint(cn.strength(), cn.weight())
|
||||
{
|
||||
EnsurePreconditionsForCn(cn);
|
||||
list<FDNumber> l;
|
||||
/* GJB:FIXME:: varargs inteface, with sentinel as first arg? */
|
||||
l.push_back(9);
|
||||
l.push_back(10);
|
||||
l.push_back(12);
|
||||
l.push_back(14);
|
||||
l.push_back(20);
|
||||
|
||||
ClVarSet setRO = cn.ReadOnlyVars();
|
||||
|
||||
ClVariable clvRO = clvNil;
|
||||
ClVariable clvROLinear = clvNil;
|
||||
Number coeffRO = 0;
|
||||
|
||||
ClVariable clvRW = clvNil;
|
||||
Number coeffRW = 0;
|
||||
|
||||
if (setRO.size() == 1) {
|
||||
const ClVariable &clv = *(setRO.begin());
|
||||
if (clv->IsFDVariable())
|
||||
clvRO = clv;
|
||||
else
|
||||
clvRO = new ClFDVariable(clv.Name(),clv.IntValue(),l);
|
||||
clvROLinear = clv;
|
||||
}
|
||||
const ClLinearExpression &expr = cn.Expression();
|
||||
const ClVarToNumberMap &terms = expr.Terms();
|
||||
|
||||
for (ClVarToNumberMap::const_iterator it = terms.begin();
|
||||
it != terms.end();
|
||||
++it) {
|
||||
ClVariable clv = (*it).first;
|
||||
if (clv == clvROLinear) {
|
||||
coeffRO = (*it).second;
|
||||
} else {
|
||||
if (clv->IsFDVariable())
|
||||
clvRW = clv;
|
||||
else
|
||||
clvRW = new ClFDVariable(clv.Name(),clv.Value(),l);
|
||||
coeffRW = (*it).second;
|
||||
}
|
||||
}
|
||||
assert(!clvRW.IsNil());
|
||||
if (coeffRW == 0) {
|
||||
throw ExCLTooDifficultSpecial("RW variable's coefficient must be non-zero");
|
||||
}
|
||||
|
||||
bool fInequality = cn.IsInequality();
|
||||
bool fStrictInequality = cn.IsStrictInequality();
|
||||
double rhs_constant = expr.Constant();
|
||||
|
||||
// now we have:
|
||||
// coeffRW * clvRW + coeffRO * clvRO <REL> rhs_constant
|
||||
// where <REL> is >= if fInequality, or = if !fInequality
|
||||
//
|
||||
// need:
|
||||
// clvRW <REL> coefficient * clvRO + constant
|
||||
//
|
||||
// so:
|
||||
// coefficient = -coeffRO/coeffRW
|
||||
// constant = rhs_constant/coeffRW
|
||||
|
||||
if (fStrictInequality)
|
||||
_rel = cnGT;
|
||||
else if (fInequality)
|
||||
_rel = cnGEQ;
|
||||
else
|
||||
_rel = cnEQ;
|
||||
|
||||
if (coeffRW < 0)
|
||||
_rel = ReverseInequality(_rel);
|
||||
|
||||
_coefficient = -coeffRO/coeffRW;
|
||||
_constant = -rhs_constant/coeffRW;
|
||||
_vRW = clvRW;
|
||||
_vRO = clvRO;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDConnectorVariable.cc
|
||||
|
||||
#include <cassowary/ClFDConnectorVariable.h>
|
||||
#include <cassowary/ClSolver.h> // for list<FDNumber> printing
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
// Use < > for ClFDConnector-s, instead of [ ]
|
||||
#ifndef CL_NO_IO
|
||||
ostream &ClFDConnectorVariable::PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "<" << Name() << "=" << Value()
|
||||
<< "{" << _clvFloat << "}"
|
||||
<< ":" << *PlfdnDomain() << ">";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDSolver.cc
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cassowary/Cassowary.h>
|
||||
#include <cassowary/ClFDSolver.h>
|
||||
#include <cassowary/ClFDBinaryOneWayConstraint.h>
|
||||
#include <cassowary/ClVariable.h>
|
||||
#include <cassowary/debug.h>
|
||||
#include <GTL/topsort.h>
|
||||
#include <pair.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static int fDebugFDSolve;
|
||||
|
||||
ClFDSolver &
|
||||
ClFDSolver::AddConstraint(ClConstraint *const pcn)
|
||||
{
|
||||
AddConstraintInternal(pcn);
|
||||
if (_fAutosolve) Solve();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClFDSolver &
|
||||
ClFDSolver::RemoveConstraint(ClConstraint *const pcn)
|
||||
{
|
||||
RemoveConstraintInternal(pcn);
|
||||
if (_fAutosolve) Solve();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClFDSolver &
|
||||
ClFDSolver::AddConstraintInternal(ClConstraint *const pcn)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << *pcn << ")" << endl;
|
||||
#endif
|
||||
|
||||
ClFDBinaryOneWayConstraint *const pcnfd =
|
||||
dynamic_cast<ClFDBinaryOneWayConstraint *const>(pcn);
|
||||
if (!pcnfd) {
|
||||
throw ExCLTooDifficultSpecial("Can only add ClFDBinaryOneWayConstraint-s to ClFDSolvers");
|
||||
}
|
||||
ClVariable rw = pcnfd->ClvRW();
|
||||
ClVariable ro = pcnfd->ClvRO();
|
||||
if (!rw.IsFDVariable()) {
|
||||
throw ExCLTooDifficultSpecial("RW variable must be an FDVariable");
|
||||
}
|
||||
if (!(ro.IsNil() || ro.IsFDVariable())) {
|
||||
throw ExCLTooDifficultSpecial("RO variable must be an FDVariable or clvNil");
|
||||
}
|
||||
// add the constraint to our set of cns
|
||||
_setCns.insert(pcn);
|
||||
// and add the constraint to the cns that affect var rw
|
||||
assert(!rw.IsNil());
|
||||
_mapClvToCns[rw].insert(pcn);
|
||||
|
||||
|
||||
node nRw = GetVarNode(rw);
|
||||
if (!ro.IsNil()) {
|
||||
node nRo = GetVarNode(ro);
|
||||
edge e = G.new_edge(nRo, nRw);
|
||||
|
||||
_mapCnToEdge[pcn] = e;
|
||||
|
||||
if (!G.is_acyclic()) {
|
||||
/* there is a cycle... give up after cleaning up */
|
||||
RemoveConstraint(pcn);
|
||||
throw ExCLCycleNotAllowed();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClFDSolver &
|
||||
ClFDSolver::RemoveConstraintInternal(ClConstraint *const pcn)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << *pcn << ")" << endl;
|
||||
#endif
|
||||
|
||||
ClFDBinaryOneWayConstraint *const pcnfd =
|
||||
dynamic_cast<ClFDBinaryOneWayConstraint *const>(pcn);
|
||||
|
||||
if (!pcnfd) {
|
||||
throw ExCLInternalError("Could not downcast to a ClFDBinaryOneWayConstraint");
|
||||
}
|
||||
|
||||
ClConstraintSet::iterator itCn = _setCns.find(pcnfd);
|
||||
if (itCn == _setCns.end()) {
|
||||
throw ExCLConstraintNotFound();
|
||||
}
|
||||
_setCns.erase(itCn);
|
||||
|
||||
ClVariable rw = pcnfd->ClvRW();
|
||||
ClVariable ro = pcnfd->ClvRO();
|
||||
ClConstraintSet &_cnsAffectingRW = _mapClvToCns[rw];
|
||||
ClConstraintSet::iterator it = _cnsAffectingRW.find(pcnfd);
|
||||
if (it == _cnsAffectingRW.end()) {
|
||||
throw ExCLInternalError("Cannot find pcnfd");
|
||||
}
|
||||
_cnsAffectingRW.erase(it);
|
||||
|
||||
if (!ro.IsNil()) {
|
||||
edge e = _mapCnToEdge[pcn];
|
||||
G.del_edge(e);
|
||||
_mapCnToEdge.erase(pcn);
|
||||
|
||||
if (_mapVarToNode.find(ro) != _mapVarToNode.end() &&
|
||||
_mapVarToNode[ro].degree() == 0) {
|
||||
G.del_node(_mapVarToNode[ro]);
|
||||
_mapVarToNode.erase(ro);
|
||||
}
|
||||
}
|
||||
if (_mapVarToNode.find(rw) != _mapVarToNode.end() &&
|
||||
_mapVarToNode[rw].degree() == 0) {
|
||||
G.del_node(_mapVarToNode[rw]);
|
||||
_mapVarToNode.erase(rw);
|
||||
}
|
||||
if (_mapClvToCns[rw].size() == 0) {
|
||||
_mapClvToCns.erase(rw);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClFDSolver &
|
||||
ClFDSolver::Solve()
|
||||
{
|
||||
topsort t;
|
||||
t.run(G);
|
||||
topsort::topsort_iterator it = t.top_order_begin();
|
||||
topsort::topsort_iterator end = t.top_order_end();
|
||||
ClSymbolicWeight errorTotal;
|
||||
ResetSetFlagsOnVariables();
|
||||
for (; it != end; ++it) {
|
||||
ClVariable clv = nodeToVar[*it];
|
||||
ClFDVariable *pcldv = dynamic_cast<ClFDVariable*>(clv.get_pclv());
|
||||
#ifndef NO_FDSOLVE_DEBUG
|
||||
if (fDebugFDSolve) {
|
||||
if (!clv.IsNil()) cout << "node " << (*it) << " is " << clv << endl;
|
||||
cerr << "Set from: " << endl;
|
||||
for (ClConstraintSet::iterator itCns = _mapClvToCns[clv].begin();
|
||||
itCns != _mapClvToCns[clv].end();
|
||||
++itCns) {
|
||||
const ClConstraint *pcn = *itCns;
|
||||
cerr << *pcn << endl;
|
||||
}
|
||||
cerr << endl;
|
||||
}
|
||||
#endif
|
||||
pair<ClSymbolicWeight,FDNumber> p = ComputeBest(pcldv);
|
||||
ClSymbolicWeight e = p.first;
|
||||
FDNumber v = p.second;
|
||||
if (v == FDN_NOTSET)
|
||||
throw ExCLRequiredFailure();
|
||||
pcldv->ChangeValue(v);
|
||||
pcldv->SetFIsSet(true);
|
||||
errorTotal += e;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* return the best (lowest) incremental error and the value
|
||||
at which that error occurs */
|
||||
pair<ClSymbolicWeight,FDNumber>
|
||||
ClFDSolver::ComputeBest(ClFDVariable *pcldv)
|
||||
{
|
||||
assert(pcldv);
|
||||
// assert(!pcldv->FIsSet()); //GJB:FIXME::
|
||||
ClSymbolicWeight minError = ClsRequired().symbolicWeight();
|
||||
FDNumber bestValue = FDN_NOTSET;
|
||||
// ClVariable clv(pcldv);
|
||||
// for each domain value
|
||||
for (list<FDNumber>::const_iterator itVal= pcldv->PlfdnDomain()->begin();
|
||||
itVal != pcldv->PlfdnDomain()->end();
|
||||
++itVal) {
|
||||
FDNumber value = *itVal;
|
||||
ClSymbolicWeight error;
|
||||
const ClConstraintSet &setCns = _mapClvToCns[pcldv];
|
||||
// for each constraint affecting *pcldv
|
||||
for (ClConstraintSet::const_iterator itCn = setCns.begin();
|
||||
itCn != setCns.end();
|
||||
++itCn) {
|
||||
const ClConstraint *pcn = *itCn;
|
||||
ClSymbolicWeight e = ErrorForClvAtValSubjectToCn(pcldv,value,*pcn);
|
||||
error += e;
|
||||
}
|
||||
// now error is the total error for binding clv <- value
|
||||
if (error < minError) {
|
||||
minError = error;
|
||||
bestValue = value;
|
||||
}
|
||||
}
|
||||
// now minError is the lowest error we can get for clv
|
||||
// and it occurs binding clv <- bestValue
|
||||
if (bestValue == FDN_NOTSET)
|
||||
throw ExCLRequiredFailure();
|
||||
return pair<ClSymbolicWeight,FDNumber>(minError,bestValue);
|
||||
}
|
||||
|
||||
ClSymbolicWeight
|
||||
ClFDSolver::ErrorForClvAtValSubjectToCn(ClFDVariable *pcldv,FDNumber value,const ClConstraint &cn)
|
||||
{
|
||||
const ClFDBinaryOneWayConstraint *pcnFd = dynamic_cast<const ClFDBinaryOneWayConstraint*>(&cn);
|
||||
if (!pcnFd) throw ExCLInternalError("Not a binary FD constraint.");
|
||||
ClCnRelation rel = pcnFd->Relation();
|
||||
double m = pcnFd->Coefficient();
|
||||
double b = pcnFd->Constant();
|
||||
ClVariable rw = pcnFd->ClvRW();
|
||||
ClVariable ro = pcnFd->ClvRO();
|
||||
assert(rw.get_pclv() == pcldv);
|
||||
double e;
|
||||
double x = ro.IsNil()? 0 : ro.Value();
|
||||
// return the error in satisfying:
|
||||
// value REL m*x + b
|
||||
double rhs = m*x + b;
|
||||
switch (rel) {
|
||||
case cnLEQ:
|
||||
if (value <= rhs) e = 0;
|
||||
else e = 1 + value-rhs;
|
||||
break;
|
||||
case cnLT:
|
||||
if (value < rhs) e = 0;
|
||||
else e = 1 + value-rhs;
|
||||
break;
|
||||
case cnGEQ:
|
||||
if (value >= rhs) e = 0;
|
||||
else e = 1+ rhs-value;
|
||||
break;
|
||||
case cnGT:
|
||||
if (value > rhs) e = 0;
|
||||
else e = 1 + rhs-value;
|
||||
break;
|
||||
case cnEQ:
|
||||
if (value == rhs) e = 0;
|
||||
else e = 1 + fabs(rhs-value);
|
||||
break;
|
||||
case cnNEQ:
|
||||
if (value != rhs) e = 0;
|
||||
else e = 1; /* GJB:FIXME:: what makes sense here? */
|
||||
break;
|
||||
default:
|
||||
e = 0; /* quiet warning */
|
||||
assert(false);
|
||||
}
|
||||
|
||||
ClSymbolicWeight err;
|
||||
if (cn.IsRequired() && e > 0)
|
||||
err = ClsRequired().symbolicWeight();
|
||||
else
|
||||
err = cn.symbolicWeight() * (e*cn._weight);
|
||||
#ifndef NO_FDSOLVE_DEBUG
|
||||
if (fDebugFDSolve) {
|
||||
cerr << "Error at " << value << " = " << err << endl;
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
ClFDSolver &
|
||||
ClFDSolver::ShowSolve()
|
||||
{
|
||||
topsort t;
|
||||
t.run(G);
|
||||
topsort::topsort_iterator it = t.top_order_begin();
|
||||
topsort::topsort_iterator end = t.top_order_end();
|
||||
for (; it != end; ++it) {
|
||||
ClVariable clv = nodeToVar[*it];
|
||||
if (!clv.IsNil()) cout << "Node " << (*it) << " is " << clv << endl;
|
||||
cout << "Set from: " << endl;
|
||||
for (ClConstraintSet::iterator itCns = _mapClvToCns[clv].begin();
|
||||
itCns != _mapClvToCns[clv].end();
|
||||
++itCns) {
|
||||
const ClConstraint *pcn = *itCns;
|
||||
cout << *pcn << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/* Turn all FDVariable FIsSet() flags to false */
|
||||
void
|
||||
ClFDSolver::ResetSetFlagsOnVariables()
|
||||
{
|
||||
for (ClVarToConstraintSetMap::iterator it = _mapClvToCns.begin();
|
||||
it != _mapClvToCns.end();
|
||||
++it) {
|
||||
ClVariable clv = (*it).first;
|
||||
ClFDVariable *pcldv = dynamic_cast<ClFDVariable*>(clv.get_pclv());
|
||||
assert(pcldv);
|
||||
pcldv->SetFIsSet(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ostream &
|
||||
ClFDSolver::PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "FDSolver: "
|
||||
<< _setCns
|
||||
<< "Graph nodes, edges = " << G.number_of_nodes() << ", " << G.number_of_edges()
|
||||
<< endl;
|
||||
return xo;
|
||||
}
|
||||
|
||||
ostream &
|
||||
ClFDSolver::PrintInternalInfo(ostream &xo) const
|
||||
{ return xo; }
|
||||
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClFDSolver &clfds)
|
||||
{ return clfds.PrintOn(xo); }
|
||||
|
||||
|
||||
//// protected member functions
|
||||
|
||||
/* Create node for v in G, if necessary,
|
||||
otherwise return the node we already created. */
|
||||
node
|
||||
ClFDSolver::GetVarNode(ClVariable v)
|
||||
{
|
||||
ClMap<ClVariable,node>::iterator it = _mapVarToNode.find(v);
|
||||
if (it == _mapVarToNode.end()) {
|
||||
node n = G.new_node();
|
||||
_mapVarToNode[v] = n;
|
||||
nodeToVar[n] = v;
|
||||
return n;
|
||||
} else {
|
||||
return (*it).second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ListPushOnto(list<FDNumber> *pl, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, pl);
|
||||
FDNumber n;
|
||||
while ( (n = va_arg(ap, FDNumber)) != FDN_EOL) {
|
||||
pl->push_back(n);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDVariable.cc
|
||||
|
||||
#include <cassowary/ClFDVariable.h>
|
||||
#include <cassowary/ClSolver.h> // for list<FDNumber> printing
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
// Use < > for ClFDVariable-s, instead of [ ]
|
||||
#ifndef CL_NO_IO
|
||||
ostream &ClFDVariable::PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "<" << Name() << "=" << Value() << ":" << *PlfdnDomain() << ">";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFloatVariable.cc
|
||||
|
||||
#include <cassowary/ClFloatVariable.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
ostream &ClFloatVariable::PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "[" << Name() << ":" << _value << "]";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,473 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClLinearExpression.cc
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <cassowary/ClLinearExpression.h>
|
||||
#include <cassowary/ClSymbolicWeight.h> /// needed only to instantiate with T=ClSymbolicWeight
|
||||
#include <cassowary/ClVariable.h>
|
||||
#include <cassowary/ClTableau.h>
|
||||
#include <cassowary/ClErrors.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>::ClGenericLinearExpression(T num) :
|
||||
_constant(num)
|
||||
{ }
|
||||
|
||||
// Convert from ClVariable to a ClLinearExpression
|
||||
// this replaces ClVariable::asLinearExpression
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>::ClGenericLinearExpression(ClVariable clv, T value,
|
||||
T Constant) :
|
||||
_constant(Constant)
|
||||
{
|
||||
_terms[clv] = value;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>::~ClGenericLinearExpression()
|
||||
{ }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
template <class T>
|
||||
ostream &
|
||||
ClGenericLinearExpression<T>::PrintOn(ostream &xo) const
|
||||
{
|
||||
typename ClVarToCoeffMap::const_iterator i = _terms.begin();
|
||||
|
||||
if (!ClApprox(_constant,0.0) || i == _terms.end())
|
||||
{
|
||||
xo << _constant;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == _terms.end())
|
||||
return xo;
|
||||
xo << (*i).second << "*" << (*i).first;
|
||||
++i;
|
||||
}
|
||||
for ( ; i != _terms.end(); ++i)
|
||||
{
|
||||
xo << " + " << (*i).second << "*" << (*i).first;
|
||||
}
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Destructively multiply self by x.
|
||||
// (private memfn)
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T> &
|
||||
ClGenericLinearExpression<T>::MultiplyMe(T x)
|
||||
{
|
||||
_constant *= x;
|
||||
|
||||
typename ClVarToCoeffMap::const_iterator i = _terms.begin();
|
||||
for ( ; i != _terms.end(); ++i)
|
||||
{
|
||||
_terms[(*i).first] = (*i).second * x;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return a new linear expression formed by multiplying self by x.
|
||||
// (Note that this result must be linear.)
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::Times(Number x) const
|
||||
{
|
||||
ClGenericLinearExpression<T> result = *this;
|
||||
return result.MultiplyMe(x);
|
||||
}
|
||||
|
||||
// Return a new linear expression formed by multiplying self by x.
|
||||
// (Note that this result must be linear.)
|
||||
// The above function optimizes the specific case of multiplying
|
||||
// by a Constant, here is the more general case
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::Times(const ClGenericLinearExpression<T> &expr) const
|
||||
{
|
||||
if (IsConstant())
|
||||
{
|
||||
return expr.Times(_constant);
|
||||
}
|
||||
else if (!expr.IsConstant())
|
||||
{
|
||||
// neither are constants, so we'd introduce non-linearity
|
||||
throw ExCLNonlinearExpression();
|
||||
}
|
||||
return Times(expr._constant);
|
||||
}
|
||||
|
||||
|
||||
// Return a new linear expression formed by adding x to self.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::Plus(const ClGenericLinearExpression<T> &expr) const
|
||||
{
|
||||
ClGenericLinearExpression<T> result = *this;
|
||||
result.AddExpression(expr,1.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return a new linear expression formed by subtracting x from self.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::Minus(const ClGenericLinearExpression<T> &expr) const
|
||||
{
|
||||
ClGenericLinearExpression<T> result = *this;
|
||||
result.AddExpression(expr,-1.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return a new linear expression formed by dividing self by x.
|
||||
// (Note that this result must be linear.)
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::Divide(Number x) const
|
||||
{
|
||||
if (ClApprox(x,0.0))
|
||||
{
|
||||
throw ExCLNonlinearExpression();
|
||||
}
|
||||
return Times(1.0/x);
|
||||
}
|
||||
|
||||
// Return a new linear expression formed by dividing self by x.
|
||||
// (Note that this result must be linear.)
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::Divide(const ClGenericLinearExpression<T> &expr) const
|
||||
{
|
||||
if (!expr.IsConstant())
|
||||
{
|
||||
throw ExCLNonlinearExpression();
|
||||
}
|
||||
return Divide(expr._constant);
|
||||
}
|
||||
|
||||
|
||||
// Return a new linear expression (expr/this). Since the result
|
||||
// must be linear, this is permissible only if 'this' is a Constant.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T>
|
||||
ClGenericLinearExpression<T>::DivFrom(const ClGenericLinearExpression<T> &expr) const
|
||||
{
|
||||
if (!IsConstant() || ClApprox(_constant,0.0))
|
||||
{
|
||||
throw ExCLNonlinearExpression();
|
||||
}
|
||||
return expr.Divide(_constant);
|
||||
}
|
||||
|
||||
// Add n*expr to this expression for another expression expr.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T> &
|
||||
ClGenericLinearExpression<T>::AddExpression(const ClGenericLinearExpression<T> &expr, Number n)
|
||||
{
|
||||
IncrementConstant(expr.Constant()*n);
|
||||
|
||||
typename ClVarToCoeffMap::const_iterator i = expr._terms.begin();
|
||||
for ( ; i != expr._terms.end(); ++i)
|
||||
{
|
||||
AddVariable((*i).first, (*i).second * n);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add n*expr to this expression for another expression expr.
|
||||
// Notify the solver if a variable is added or deleted from this
|
||||
// expression.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T> &
|
||||
ClGenericLinearExpression<T>::AddExpression(const ClGenericLinearExpression<T> &expr, Number n,
|
||||
ClVariable subject,
|
||||
ClTableau &solver)
|
||||
{
|
||||
IncrementConstant(expr.Constant() * n);
|
||||
|
||||
typename ClVarToCoeffMap::const_iterator i = expr._terms.begin();
|
||||
for ( ; i != expr._terms.end(); ++i)
|
||||
{
|
||||
AddVariable((*i).first, (*i).second * n, subject, solver);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add a term c*v to this expression. If the expression already
|
||||
// contains a term involving v, Add c to the existing coefficient.
|
||||
// If the new coefficient is approximately 0, delete v.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T> &
|
||||
ClGenericLinearExpression<T>::AddVariable(ClVariable v, T c)
|
||||
{ // body largely duplicated below
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << v << ", " << c << ")" << endl;
|
||||
#endif
|
||||
typename ClVarToCoeffMap::iterator i = _terms.find(v);
|
||||
if (i != _terms.end())
|
||||
{
|
||||
// expression already contains that variable, so Add to it
|
||||
T new_coefficient = 0;
|
||||
new_coefficient = (*i).second + c;
|
||||
if (ClApprox(new_coefficient,0.0))
|
||||
{
|
||||
// new coefficient is Zero, so erase it
|
||||
_terms.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*i).second = new_coefficient;
|
||||
}
|
||||
}
|
||||
else // expression did not contain that variable
|
||||
{
|
||||
if (!ClApprox(c,0.0))
|
||||
{
|
||||
_terms[v] = c;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Add a term c*v to this expression. If the expression already
|
||||
// contains a term involving v, Add c to the existing coefficient.
|
||||
// If the new coefficient is approximately 0, delete v. Notify the
|
||||
// solver if v appears or disappears from this expression.
|
||||
template <class T>
|
||||
ClGenericLinearExpression<T> &
|
||||
ClGenericLinearExpression<T>::AddVariable(ClVariable v, T c,
|
||||
ClVariable subject,
|
||||
ClTableau &solver)
|
||||
{ // body largely duplicated above
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << v << ", " << c << ", " << subject << ", ...)" << endl;
|
||||
#endif
|
||||
typename ClVarToCoeffMap::iterator i = _terms.find(v);
|
||||
if (i != _terms.end())
|
||||
{
|
||||
// expression already contains that variable, so Add to it
|
||||
T new_coefficient = (*i).second + c;
|
||||
if (ClApprox(new_coefficient,0.0))
|
||||
{
|
||||
// new coefficient is Zero, so erase it
|
||||
solver.NoteRemovedVariable((*i).first,subject);
|
||||
_terms.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*i).second = new_coefficient;
|
||||
}
|
||||
}
|
||||
else // expression did not contain that variable
|
||||
{
|
||||
if (!ClApprox(c,0.0))
|
||||
{
|
||||
_terms[v] = c;
|
||||
solver.NoteAddedVariable(v,subject);
|
||||
}
|
||||
}
|
||||
#ifdef CL_TRACE
|
||||
cerr << "Now *this == " << *this << endl;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return a variable in this expression. (It is an error if this
|
||||
// expression is Constant -- signal ExCLInternalError in that case).
|
||||
template <class T>
|
||||
ClVariable
|
||||
ClGenericLinearExpression<T>::AnyPivotableVariable() const
|
||||
{
|
||||
if (IsConstant())
|
||||
{
|
||||
throw ExCLInternalError("(ExCLInternalError) No pivotable variables in Constant expression");
|
||||
}
|
||||
typename ClVarToCoeffMap::const_iterator i = _terms.begin();
|
||||
for ( ; i != _terms.end(); ++i)
|
||||
{
|
||||
ClVariable v = (*i).first;
|
||||
if (v.IsPivotable())
|
||||
return v;
|
||||
}
|
||||
return clvNil;
|
||||
}
|
||||
|
||||
// Replace var with a symbolic expression expr that is equal to it.
|
||||
// If a variable has been added to this expression that wasn't there
|
||||
// before, or if a variable has been dropped from this expression
|
||||
// because it now has a coefficient of 0, inform the solver.
|
||||
// PRECONDITIONS:
|
||||
// var occurs with a non-Zero coefficient in this expression.
|
||||
template <class T>
|
||||
void
|
||||
ClGenericLinearExpression<T>::SubstituteOut(ClVariable var,
|
||||
const ClGenericLinearExpression<T> &expr,
|
||||
ClVariable subject,
|
||||
ClTableau &solver)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
cerr << "* ClGenericLinearExpression::";
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << var << ", " << expr << ", " << subject << ", "
|
||||
<< solver << ")" << endl;
|
||||
cerr << "*this == " << *this << endl;
|
||||
#endif
|
||||
|
||||
typename ClVarToCoeffMap::iterator pv = _terms.find(var);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (pv == _terms.end())
|
||||
{
|
||||
#ifndef CL_NO_IO
|
||||
cerr << "SubstituteOut: pv != _terms.end()" << endl;
|
||||
cerr << "(" << var << ", " << expr << ", " << subject << ", "
|
||||
<< ")" << endl;
|
||||
cerr << "*this == " << *this << endl;
|
||||
#endif
|
||||
throw "SubstituteOut: pv != _terms.end()";
|
||||
}
|
||||
#endif
|
||||
assert(pv != _terms.end());
|
||||
// FIXGJB: this got thrown! assert(!ClApprox((*pv).second,0.0));
|
||||
|
||||
T multiplier = (*pv).second;
|
||||
_terms.erase(pv);
|
||||
IncrementConstant(multiplier * expr._constant);
|
||||
typename ClVarToCoeffMap::const_iterator i = expr._terms.begin();
|
||||
for ( ; i != expr._terms.end(); ++i)
|
||||
{
|
||||
ClVariable v = (*i).first;
|
||||
T c = (*i).second;
|
||||
typename ClVarToCoeffMap::iterator poc = _terms.find(v);
|
||||
if (poc != _terms.end())
|
||||
{ // if oldCoeff is not nil
|
||||
#ifdef CL_TRACE
|
||||
cerr << "Considering (*poc) == " << (*poc).second << "*" << (*poc).first << endl;
|
||||
#endif
|
||||
// found it, so new coefficient is old one Plus what is in *i
|
||||
T newCoeff = (*poc).second + (multiplier*c);
|
||||
if (ClApprox(newCoeff,0.0))
|
||||
{
|
||||
solver.NoteRemovedVariable((*poc).first,subject);
|
||||
_terms.erase(poc);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*poc).second = newCoeff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // did not have that variable already (oldCoeff == nil)
|
||||
#ifdef CL_TRACE
|
||||
cerr << "Adding (*i) == " << (*i).second << "*" << (*i).first << endl;
|
||||
#endif
|
||||
_terms[v] = multiplier * c;
|
||||
solver.NoteAddedVariable(v,subject);
|
||||
}
|
||||
}
|
||||
#ifdef CL_TRACE
|
||||
cerr << "Now (*this) is " << *this << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This linear expression currently represents the equation
|
||||
// oldSubject=self. Destructively modify it so that it represents
|
||||
// the equation NewSubject=self.
|
||||
//
|
||||
// Precondition: NewSubject currently has a nonzero coefficient in
|
||||
// this expression.
|
||||
//
|
||||
// NOTES
|
||||
// Suppose this expression is c + a*NewSubject + a1*v1 + ... + an*vn.
|
||||
//
|
||||
// Then the current equation is
|
||||
// oldSubject = c + a*NewSubject + a1*v1 + ... + an*vn.
|
||||
// The new equation will be
|
||||
// NewSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn.
|
||||
// Note that the term involving NewSubject has been dropped.
|
||||
//
|
||||
// Basically, we consider the expression to be an equation with oldSubject
|
||||
// equal to the expression, then Resolve the equation for NewSubject,
|
||||
// and destructively make the expression what NewSubject is then equal to
|
||||
template <class T>
|
||||
void
|
||||
ClGenericLinearExpression<T>::ChangeSubject(ClVariable old_subject,
|
||||
ClVariable new_subject)
|
||||
{
|
||||
_terms[old_subject] = NewSubject(new_subject);
|
||||
}
|
||||
|
||||
inline double ReciprocalOf(double n)
|
||||
{ return 1.0/n; }
|
||||
|
||||
// This linear expression currently represents the equation self=0. Destructively modify it so
|
||||
// that subject=self represents an equivalent equation.
|
||||
//
|
||||
// Precondition: subject must be one of the variables in this expression.
|
||||
// NOTES
|
||||
// Suppose this expression is
|
||||
// c + a*subject + a1*v1 + ... + an*vn
|
||||
// representing
|
||||
// c + a*subject + a1*v1 + ... + an*vn = 0
|
||||
// The modified expression will be
|
||||
// subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
|
||||
// representing
|
||||
// subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn = 0
|
||||
//
|
||||
// Note that the term involving subject has been dropped.
|
||||
//
|
||||
// Returns the reciprocal, so that NewSubject can be used by ChangeSubject
|
||||
template <class T>
|
||||
T
|
||||
ClGenericLinearExpression<T>::NewSubject(ClVariable subject)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << subject << ")" << endl;
|
||||
#endif
|
||||
typename ClVarToCoeffMap::iterator pnewSubject = _terms.find(subject);
|
||||
assert(pnewSubject != _terms.end());
|
||||
// assert(!ClApprox((*pnewSubject).second,0.0));
|
||||
T reciprocal = ReciprocalOf((*pnewSubject).second);
|
||||
_terms.erase(pnewSubject);
|
||||
MultiplyMe(-reciprocal);
|
||||
return reciprocal;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T
|
||||
ClGenericLinearExpression<T>::Evaluate() const
|
||||
{
|
||||
T answer = _constant;
|
||||
typename ClVarToCoeffMap::const_iterator i = _terms.begin();
|
||||
|
||||
for ( ; i != _terms.end(); ++i)
|
||||
{
|
||||
ClVariable v = (*i).first;
|
||||
answer += (*i).second * v.Value();
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
template class ClGenericLinearExpression<Number>;
|
||||
// template class ClGenericLinearExpression<ClSymbolicWeight>;
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/* $Id$
|
||||
Cassowary Incremental Constraint Solver
|
||||
Original Smalltalk Implementation by Alan Borning
|
||||
This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
http://www.cs.washington.edu/homes/gjb
|
||||
(C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
See ../LICENSE for legal details regarding this software
|
||||
|
||||
ClReader.l - Scanner for constraint parsing.
|
||||
By Greg J. Badros
|
||||
*/
|
||||
|
||||
%{
|
||||
/* Get the token numbers that bison created for us
|
||||
(uses the -d option of bison) */
|
||||
|
||||
#include <cassowary/ClReader.h>
|
||||
#include "ClReader.cc.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
/* global variable for the istream we are reading from;
|
||||
gets set by PcnParseConstraint */
|
||||
istream *pxi_lexer;
|
||||
|
||||
/* Pass in an extra variable (ClParseData *) to cllex so that
|
||||
it can look up variable names */
|
||||
#define YY_DECL int cllex(YYSTYPE *lvalp, void *YYLEX_PARAM)
|
||||
|
||||
/* Make lexer reader from the global variable */
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
do { if (pxi_lexer->get(buf[0]) && buf[0] > 0) result = 1; \
|
||||
else result = YY_NULL; } while (0)
|
||||
|
||||
%}
|
||||
|
||||
%option noyywrap
|
||||
|
||||
DIGIT [0-9]
|
||||
ALPHA [A-Za-z]
|
||||
ALPHANUM [A-Za-z0-9]
|
||||
ID_OK_PUNC [-_\[\]]
|
||||
RO_ANNOTATION "?"
|
||||
ID {ALPHA}({ALPHANUM}|{ID_OK_PUNC})*({RO_ANNOTATION})?
|
||||
NUMID "{"{DIGIT}+"}"
|
||||
ws [ \t\n]+
|
||||
|
||||
%%
|
||||
{ws} /* skip whitespace */
|
||||
\n|";" { return 0; }
|
||||
">=" { return GEQ; }
|
||||
">" { return GT; }
|
||||
"<=" { return LEQ; }
|
||||
"<" { return LT; }
|
||||
"==" { return '='; }
|
||||
"="|"-"|"+"|"*"|"/"|"("|")" { return yytext[0]; }
|
||||
|
||||
{DIGIT}+("."{DIGIT}*)? |
|
||||
"."{DIGIT}+ { lvalp->num = strtod(yytext,0); return NUM; }
|
||||
|
||||
{ID} { /* Lookup the variable name */
|
||||
ClParseData *pclpd = ((ClParseData *) YYLEX_PARAM);
|
||||
int cch = strlen(yytext);
|
||||
ClVariable *pclv = NULL;
|
||||
bool fReadOnly = false;
|
||||
if (yytext[cch-1] == '?') {
|
||||
yytext[cch-1] = '\0';
|
||||
fReadOnly = true;
|
||||
}
|
||||
const string str = string(yytext);
|
||||
pclv = pclpd->_lookup_func(str);
|
||||
if (!pclv->IsNil()) {
|
||||
lvalp->pclv = pclv;
|
||||
return fReadOnly?RO_VAR:VAR;
|
||||
} else {
|
||||
pxi_lexer = NULL;
|
||||
yy_flush_buffer(YY_CURRENT_BUFFER);
|
||||
throw ExCLParseErrorBadIdentifier(str);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
. { pxi_lexer = NULL; throw ExCLParseErrorMisc("Unrecognized character"); }
|
||||
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
$Id$
|
||||
|
||||
Cassowary Incremental Constraint Solver
|
||||
Original Smalltalk Implementation by Alan Borning
|
||||
This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
http://www.cs.washington.edu/homes/gjb
|
||||
(C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
See ../LICENSE for legal details regarding this software
|
||||
|
||||
ClReader.y
|
||||
Original implementation contributed by Steve Wolfman
|
||||
Subsequently largely revised by Greg J. Badros
|
||||
|
||||
Supports parsing of read-only variables in constraints via "?" suffix
|
||||
annotations on variables. If a variable is followed by "?" in any of
|
||||
its occurrences in the constraint, that variable is deemed read-only
|
||||
and entered into the constraint object as such. E.g.,
|
||||
|
||||
x = 2*y?
|
||||
|
||||
is a one-way constraint that sets x from y's value.
|
||||
|
||||
x = y + y?
|
||||
and
|
||||
x = y? + y
|
||||
|
||||
are identical one-way constraints with y read-only. One would prefer
|
||||
to have it written like so:
|
||||
|
||||
x = y? + y?
|
||||
|
||||
but it need not be, and no warning or error is raised.
|
||||
*/
|
||||
|
||||
|
||||
%{
|
||||
/* C Declarations */
|
||||
|
||||
#include <cassowary/Cl.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRUMMY_LEXER
|
||||
string current; /* Global to help in debugging/error messages */
|
||||
#endif
|
||||
|
||||
/* Get yyparse, yylex to have an extra argument (type void *) */
|
||||
#define YYPARSE_PARAM cl_parse_data
|
||||
#define YYLEX_PARAM cl_parse_data
|
||||
#ifndef YYERROR_VERBOSE
|
||||
#define YYERROR_VERBOSE
|
||||
#endif
|
||||
#define YYDEBUG 1
|
||||
|
||||
%}
|
||||
|
||||
|
||||
/* Bison Declarations */
|
||||
|
||||
%pure_parser
|
||||
|
||||
%union {
|
||||
double num;
|
||||
const ClVariable *pclv;
|
||||
ClLinearExpression *pcle;
|
||||
ClConstraint *pcn;
|
||||
}
|
||||
|
||||
%{
|
||||
int yylex(YYSTYPE *lvalp, void *YYLEX_PARAM);
|
||||
void yyerror(const char *sz);
|
||||
%}
|
||||
|
||||
%start constraint
|
||||
|
||||
%token <num> NUM
|
||||
%token <pclv> VAR
|
||||
%token <pclv> RO_VAR
|
||||
|
||||
%token GEQ
|
||||
%token GT
|
||||
%token LEQ
|
||||
%token LT
|
||||
|
||||
%type <pcle> expr
|
||||
%type <pcn> constraint equation inequality
|
||||
|
||||
%left '-' '+'
|
||||
%left '*' '/'
|
||||
%left NEG
|
||||
|
||||
%%
|
||||
/* Grammar Rules */
|
||||
|
||||
constraint: equation { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; }
|
||||
| inequality { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; }
|
||||
;
|
||||
|
||||
equation: expr '=' expr { $$ = new ClLinearEquation(*$1, *$3); }
|
||||
;
|
||||
|
||||
inequality: expr GEQ expr { $$ = new ClLinearInequality(*$1, cnGEQ, *$3); }
|
||||
| expr LEQ expr { $$ = new ClLinearInequality(*$1, cnLEQ, *$3); }
|
||||
| expr LT expr { $$ = new ClLinearInequality(*$1, cnLT, *$3); }
|
||||
| expr GT expr { $$ = new ClLinearInequality(*$1, cnGT, *$3); }
|
||||
;
|
||||
|
||||
expr: NUM { $$ = new ClLinearExpression($1); }
|
||||
| VAR { $$ = new ClLinearExpression(*$1); }
|
||||
| RO_VAR { $$ = new ClLinearExpression(*$1);
|
||||
((ClParseData*)YYPARSE_PARAM)->_readOnlyVarsSoFar.insert(*$1); }
|
||||
| expr '+' expr { $$ = new ClLinearExpression(*$1 + *$3); }
|
||||
| expr '-' expr { $$ = new ClLinearExpression(*$1 - *$3); }
|
||||
| expr '*' expr { $$ = new ClLinearExpression(*$1 * *$3); }
|
||||
| expr '/' expr { $$ = new ClLinearExpression(*$1 / *$3); }
|
||||
| '-' expr %prec NEG { $$ = new ClLinearExpression(-1 * *$2); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void clerror(const char *sz)
|
||||
{
|
||||
throw ExCLParseErrorMisc(sz);
|
||||
}
|
||||
|
||||
extern istream *pxi_lexer;
|
||||
|
||||
// xi is the stream from which to read the constraint.
|
||||
// aVars is an array of variables large enough to account for
|
||||
// each one that might be mentioned in a constraint
|
||||
ClConstraint *PcnParseConstraint(istream &xi, const ClVarLookupFunction &lookup_func,
|
||||
const ClStrength &strength)
|
||||
{
|
||||
ClParseData cl_parse_data(xi, lookup_func);
|
||||
pxi_lexer = ξ
|
||||
if (yyparse(&cl_parse_data) == 0) { // success
|
||||
#ifdef DEBUG_PARSER
|
||||
cerr << *cl_parse_data.Pcn() << endl;
|
||||
#endif
|
||||
cl_parse_data.Pcn()->ChangeStrength(strength);
|
||||
cl_parse_data.Pcn()->AddROVars(cl_parse_data._readOnlyVarsSoFar);
|
||||
return cl_parse_data.Pcn();
|
||||
}
|
||||
else { // failed
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,12 +0,0 @@
|
|||
// $Id$
|
||||
|
||||
#include <cassowary/ClSlackVariable.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifdef CL_FIND_LEAK
|
||||
long ClSlackVariable::cSlackVariables = 0;
|
||||
#endif
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// $Id$
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cassowary/Cassowary.h>
|
||||
#include <cassowary/ClSolver.h>
|
||||
#include <cassowary/ClConstraint.h>
|
||||
#include <cassowary/ClErrors.h>
|
||||
#include <cassowary/ClTypedefs.h>
|
||||
|
||||
|
||||
ClSolver &
|
||||
ClSolver::AddConstraint(ClConstraint *const )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
ostream &
|
||||
PrintTo(ostream &xo, const ClConstraintSet &setCn)
|
||||
{
|
||||
ClConstraintSet::const_iterator it = setCn.begin();
|
||||
for (; it != setCn.end(); ++it) {
|
||||
const ClConstraint *pcn = *it;
|
||||
xo << *pcn << endl;
|
||||
}
|
||||
return xo;
|
||||
}
|
||||
|
||||
ostream &
|
||||
PrintTo(ostream &xo, const list<FDNumber> &listFDN)
|
||||
{
|
||||
list<FDNumber>::const_iterator it = listFDN.begin();
|
||||
for (; it != listFDN.end(); ) {
|
||||
FDNumber n = *it;
|
||||
xo << n;
|
||||
++it;
|
||||
if (it != listFDN.end())
|
||||
xo << ",";
|
||||
}
|
||||
return xo;
|
||||
}
|
||||
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClConstraintSet &setCn)
|
||||
{ return PrintTo(xo,setCn); }
|
||||
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClSolver &solver)
|
||||
{ return solver.PrintOn(xo); }
|
||||
|
||||
ostream &operator<<(ostream &xo, const list<FDNumber> &listFDN)
|
||||
{ return PrintTo(xo,listFDN); }
|
||||
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClStrength.cc
|
||||
|
||||
#include <cassowary/ClStrength.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
// Use the singleton pattern for the strength objects
|
||||
const ClStrength &ClsRequired()
|
||||
{
|
||||
// required is distinct by equality to this static object,
|
||||
// but I still use an especially high symbolic weight, just in case
|
||||
// FIXGJB: hack?
|
||||
static ClStrength required_strength("<Required>", 1000, 1000, 1000);
|
||||
return required_strength;
|
||||
}
|
||||
|
||||
const ClStrength &ClsStrong()
|
||||
{
|
||||
static ClStrength strong_strength("strong", 1.0, 0.0, 0.0);
|
||||
return strong_strength;
|
||||
}
|
||||
|
||||
const ClStrength &ClsMedium()
|
||||
{
|
||||
static ClStrength medium_strength("medium", 0.0, 1.0, 0.0);
|
||||
return medium_strength;
|
||||
}
|
||||
|
||||
|
||||
const ClStrength &ClsWeak()
|
||||
{
|
||||
static ClStrength weak_strength("weak", 0.0, 0.0, 1.0);
|
||||
return weak_strength;
|
||||
}
|
||||
|
||||
// special case for when nLevels = 3, should assert nLevels() == 3
|
||||
ClStrength::ClStrength(const string &Name, double w1, double w2, double w3) :
|
||||
_name(Name), _symbolicWeight(w1, w2, w3)
|
||||
{
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClSymbolicWeight.cc
|
||||
|
||||
#include <cassowary/Cassowary.h>
|
||||
#include <cassowary/ClSymbolicWeight.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
// Help g++ out, tell it to instantiate this
|
||||
//template vector<double> &vector<double>::operator =(const vector<double> &);
|
||||
|
||||
ClSymbolicWeight::ClSymbolicWeight(unsigned int CLevels, double value) :
|
||||
_values(CLevels, value)
|
||||
{
|
||||
assert(_values.size() == CLevels);
|
||||
}
|
||||
|
||||
ClSymbolicWeight::ClSymbolicWeight(double w1, double w2, double w3)
|
||||
{
|
||||
_values.push_back(w1);
|
||||
_values.push_back(w2);
|
||||
_values.push_back(w3);
|
||||
assert(_values.size() == 3);
|
||||
}
|
||||
|
||||
ClSymbolicWeight::ClSymbolicWeight(const vector<double> &weights) :
|
||||
_values(weights)
|
||||
{ }
|
||||
|
||||
ClSymbolicWeight &
|
||||
ClSymbolicWeight::Zero()
|
||||
{
|
||||
static ClSymbolicWeight Zero(0.0, 0.0, 0.0);
|
||||
return Zero;
|
||||
}
|
||||
|
||||
|
||||
ClSymbolicWeight &
|
||||
ClSymbolicWeight::negated()
|
||||
{
|
||||
vector<double>::iterator it = _values.begin();
|
||||
for (; it != _values.end(); ++it)
|
||||
{
|
||||
*it = -*it;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClSymbolicWeight &
|
||||
ClSymbolicWeight::MultiplyMe(Number n)
|
||||
{
|
||||
vector<double>::iterator it = _values.begin();
|
||||
for (; it != _values.end(); ++it)
|
||||
{
|
||||
*it *= n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
ClSymbolicWeight
|
||||
ClSymbolicWeight::DivideBy(Number n) const
|
||||
{
|
||||
assert(n!=0);
|
||||
ClSymbolicWeight clsw(0);
|
||||
vector<double>::const_iterator i = _values.begin();
|
||||
for (; i != _values.end(); ++i)
|
||||
{
|
||||
clsw.push_back(*i / n);
|
||||
}
|
||||
return clsw;
|
||||
}
|
||||
|
||||
ClSymbolicWeight &
|
||||
ClSymbolicWeight::addtoMe(const ClSymbolicWeight &cl)
|
||||
{
|
||||
assert(cl.CLevels() == CLevels());
|
||||
|
||||
vector<double>::iterator i1 = _values.begin();
|
||||
vector<double>::const_iterator i2 = cl._values.begin();
|
||||
for (; i1 != _values.end(); ++i1, ++i2)
|
||||
{
|
||||
*i1 += *i2;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClSymbolicWeight
|
||||
ClSymbolicWeight::Subtract(const ClSymbolicWeight &cl) const
|
||||
{
|
||||
assert(cl.CLevels() == CLevels());
|
||||
|
||||
ClSymbolicWeight clsw(0);
|
||||
vector<double>::const_iterator i1 = _values.begin();
|
||||
vector<double>::const_iterator i2 = cl._values.begin();
|
||||
for (; i1 != _values.end(); ++i1, ++i2)
|
||||
{
|
||||
clsw.push_back(*i1 - *i2);
|
||||
}
|
||||
return clsw;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClSymbolicWeight::lessThan(const ClSymbolicWeight &cl) const
|
||||
{
|
||||
return _values < cl._values;
|
||||
}
|
||||
|
||||
bool
|
||||
ClSymbolicWeight::lessThanOrEqual(const ClSymbolicWeight &cl) const
|
||||
{
|
||||
return _values <= cl._values;
|
||||
}
|
||||
|
||||
bool
|
||||
ClSymbolicWeight::equal(const ClSymbolicWeight &cl) const
|
||||
{
|
||||
return _values == cl._values;
|
||||
}
|
||||
|
||||
bool
|
||||
ClSymbolicWeight::greaterThan(const ClSymbolicWeight &cl) const
|
||||
{
|
||||
return _values > cl._values;
|
||||
}
|
||||
|
||||
bool
|
||||
ClSymbolicWeight::greaterThanOrEqual(const ClSymbolicWeight &cl) const
|
||||
{
|
||||
return _values >= cl._values;
|
||||
}
|
||||
|
||||
bool
|
||||
ClSymbolicWeight::isNegative() const
|
||||
{
|
||||
return _values < Zero()._values;
|
||||
}
|
||||
|
|
@ -1,297 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClTableau.cc
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <cassowary/ClTableau.h>
|
||||
#include <cassowary/debug.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
|
||||
// delete the linear expressions
|
||||
// let ClSimplexSolver worry about deleting the variables
|
||||
ClTableau::~ClTableau()
|
||||
{
|
||||
ClTableauRowsMap::iterator it = _rows.begin();
|
||||
for (; it != _rows.end(); ++it)
|
||||
{
|
||||
// free the ClLinearExpression that we new-ed
|
||||
#ifdef CL_TRACE
|
||||
cerr << "Deleting row delete@ " << ((*it).second) << endl;
|
||||
#endif
|
||||
delete (*it).second;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
// Some extra debugging info
|
||||
ostream &
|
||||
ClTableau::PrintInternalInfo(ostream &xo) const
|
||||
{
|
||||
xo << "ncns:" << _rows.size() -1
|
||||
<< "; cols:" << _columns.size()
|
||||
<< "; infrows:" << _infeasibleRows.size()
|
||||
<< "; ebvars:" << _externalRows.size()
|
||||
<< "; epvars:" << _externalParametricVars.size();
|
||||
return xo;
|
||||
}
|
||||
|
||||
|
||||
ostream &
|
||||
ClTableau::printExternalVariablesTo(ostream &xo) const
|
||||
{
|
||||
xo << "Parametric: ";
|
||||
ClVarSet::iterator itParVars = _externalParametricVars.begin();
|
||||
for ( ; itParVars != _externalParametricVars.end(); ++itParVars ) {
|
||||
ClVariable v = *itParVars;
|
||||
xo << v << " ";
|
||||
}
|
||||
xo << "\nBasic: ";
|
||||
ClVarSet::iterator itRowVars = _externalRows.begin();
|
||||
for ( ; itRowVars != _externalRows.end() ; ++itRowVars ) {
|
||||
ClVariable v = *itRowVars;
|
||||
xo << v << " ";
|
||||
}
|
||||
return xo << endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Add v, update column cross indices
|
||||
// v becomes a basic variable
|
||||
// expr is now owned by ClTableau class,
|
||||
// and ClTableauis responsible for deleting it
|
||||
// (also, expr better be allocated on the heap!)
|
||||
void
|
||||
ClTableau::addRow(ClVariable var, const ClLinearExpression &expr)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << var << ", " << expr << ")" << endl;
|
||||
#endif
|
||||
_rows[var] = const_cast<ClLinearExpression *>(&expr);
|
||||
ClVarToNumberMap::const_iterator it = expr.Terms().begin();
|
||||
// for each variable in expr, Add var to the set of rows which have that variable
|
||||
// in their Expression
|
||||
for (; it != expr.Terms().end(); ++it)
|
||||
{
|
||||
ClVariable v = (*it).first;
|
||||
_columns[v].insert(var);
|
||||
if (v.IsExternal() && !FIsBasicVar(v))
|
||||
{
|
||||
_externalParametricVars.insert(v);
|
||||
}
|
||||
}
|
||||
if (var.IsExternal())
|
||||
{
|
||||
_externalRows.insert(var);
|
||||
}
|
||||
#ifdef CL_TRACE
|
||||
cerr << *this << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remove var from the tableau -- remove the column cross indices for var
|
||||
// and remove var from every Expression in rows in which v occurs
|
||||
// Remove the parametric variable var, updating the appropriate column and row entries.
|
||||
// (Renamed from Smalltalk implementation's `removeParametricVar')
|
||||
ClVariable
|
||||
ClTableau::RemoveColumn(ClVariable var)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << var << ")" << endl;
|
||||
#endif
|
||||
ClTableauColumnsMap::iterator it_var = _columns.find(var);
|
||||
if (it_var == _columns.end())
|
||||
return var; // nothing to do
|
||||
|
||||
ClVarSet &varset = (*it_var).second;
|
||||
// remove the rows with the variables in varset
|
||||
ClVarSet::iterator it = varset.begin();
|
||||
for (; it != varset.end(); ++it)
|
||||
{
|
||||
ClVariable v = (*it);
|
||||
ClVarToNumberMap &Terms = _rows[v]->Terms();
|
||||
Terms.erase(Terms.find(var));
|
||||
}
|
||||
if (var.IsExternal())
|
||||
{
|
||||
_externalRows.erase(var);
|
||||
_externalParametricVars.erase(var);
|
||||
}
|
||||
_columns.erase(it_var);
|
||||
return var;
|
||||
}
|
||||
|
||||
// Remove the basic variable v from the tableau row v=expr
|
||||
// Then update column cross indices
|
||||
ClLinearExpression *
|
||||
ClTableau::RemoveRow(ClVariable var)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << var << ")" << endl;
|
||||
#endif
|
||||
ClTableauRowsMap::iterator it = _rows.find(var);
|
||||
assert(it != _rows.end());
|
||||
ClLinearExpression *pexpr = (*it).second;
|
||||
ClVarToNumberMap &Terms = pexpr->Terms();
|
||||
ClVarToNumberMap::iterator it_term = Terms.begin();
|
||||
for (; it_term != Terms.end(); ++it_term)
|
||||
{
|
||||
ClVariable v = (*it_term).first;
|
||||
_columns[v].erase(var);
|
||||
if (_columns[v].size() == 0)
|
||||
{
|
||||
_columns.erase(v);
|
||||
_externalParametricVars.erase(v);
|
||||
}
|
||||
}
|
||||
|
||||
_infeasibleRows.erase(var);
|
||||
|
||||
if (var.IsExternal())
|
||||
{
|
||||
_externalRows.erase(var);
|
||||
_externalParametricVars.erase(var);
|
||||
}
|
||||
|
||||
_rows.erase(it);
|
||||
#ifdef CL_TRACE
|
||||
cerr << "- returning " << *pexpr << endl;
|
||||
#endif
|
||||
return pexpr;
|
||||
}
|
||||
|
||||
// Replace all occurrences of oldVar with expr, and update column cross indices
|
||||
// oldVar should now be a basic variable
|
||||
// Uses the Columns data structure and calls SubstituteOut on each
|
||||
// row that has oldVar in it
|
||||
// oldVar is leaving the basis, and becoming parametric
|
||||
void
|
||||
ClTableau::SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
cerr << "* ClTableau::";
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
cerr << "(" << oldVar << ", " << expr << ")" << endl;
|
||||
cerr << (*this) << endl;
|
||||
#endif
|
||||
|
||||
ClTableauColumnsMap::iterator it_oldVar = _columns.find(oldVar);
|
||||
if (it_oldVar == _columns.end())
|
||||
return;
|
||||
|
||||
ClVarSet &varset = (*it_oldVar).second;
|
||||
ClVarSet::iterator it = varset.begin();
|
||||
for (; it != varset.end(); ++it)
|
||||
{
|
||||
ClVariable v = (*it);
|
||||
ClLinearExpression *prow = _rows[v];
|
||||
prow->SubstituteOut(oldVar,expr,v,*this);
|
||||
if (v.IsRestricted() && prow->Constant() < 0.0)
|
||||
{
|
||||
_infeasibleRows.insert(v);
|
||||
}
|
||||
}
|
||||
_columns.erase(it_oldVar);
|
||||
if (oldVar.IsExternal())
|
||||
{
|
||||
if (_columns[oldVar].size() > 0)
|
||||
{
|
||||
_externalRows.insert(oldVar);
|
||||
}
|
||||
_externalParametricVars.erase(oldVar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
|
||||
ostream &
|
||||
PrintTo(ostream &xo, const ClVarSet & varset)
|
||||
{
|
||||
ClVarSet::const_iterator it = varset.begin();
|
||||
xo << "{ ";
|
||||
if (it != varset.end())
|
||||
{
|
||||
xo << *it;
|
||||
++it;
|
||||
}
|
||||
for (; it != varset.end(); ++it)
|
||||
{
|
||||
xo << ", " << *it;
|
||||
}
|
||||
xo << " }";
|
||||
return xo;
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClVarSet & varset)
|
||||
{ return PrintTo(xo,varset); }
|
||||
|
||||
ostream &
|
||||
PrintTo(ostream &xo, const ClTableauColumnsMap & varmap)
|
||||
{
|
||||
ClTableauColumnsMap::const_iterator it = varmap.begin();
|
||||
for (; it != varmap.end(); ++it)
|
||||
{
|
||||
xo << (*it).first << " -> " << (*it).second << endl;
|
||||
}
|
||||
return xo;
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClTableauColumnsMap & varmap)
|
||||
{ return PrintTo(xo,varmap); }
|
||||
|
||||
ostream &
|
||||
PrintTo(ostream &xo, const ClTableauRowsMap & rows)
|
||||
{
|
||||
ClTableauRowsMap::const_iterator it = rows.begin();
|
||||
for (; it != rows.end(); ++it)
|
||||
{
|
||||
ClVariable v = it->first;
|
||||
const ClLinearExpression *pe = it->second;
|
||||
xo << v << " <-=-> ";
|
||||
if (pe) xo << *pe; else xo << "NilExpr";
|
||||
xo << endl;
|
||||
}
|
||||
return xo;
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClTableauRowsMap & rows)
|
||||
{ return PrintTo(xo,rows); }
|
||||
|
||||
ostream &
|
||||
ClTableau::PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "Tableau:\n"
|
||||
<< _rows << endl;
|
||||
xo << "Columns:\n"
|
||||
<< _columns << endl;
|
||||
xo << "Infeasible rows: "
|
||||
<< _infeasibleRows << endl;
|
||||
xo << "External basic variables: "
|
||||
<< _externalRows << endl;
|
||||
xo << "External parametric variables: "
|
||||
<< _externalParametricVars << endl;
|
||||
return xo;
|
||||
}
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClTableau &clt)
|
||||
{ return clt.PrintOn(xo); }
|
||||
|
||||
#endif
|
||||
|
|
@ -1,884 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClTests.cc
|
||||
|
||||
#include <cassowary/Cl.h>
|
||||
#include <stdlib.h>
|
||||
#include <cassowary/timer.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
inline
|
||||
double UniformRandom()
|
||||
{ return double(rand())/RAND_MAX; }
|
||||
|
||||
|
||||
bool
|
||||
simple1()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
ClVariable x(167);
|
||||
ClVariable y(2);
|
||||
ClSimplexSolver solver;
|
||||
|
||||
ClLinearEquation eq(x,y+0.0);
|
||||
solver.AddStay(x);
|
||||
solver.AddStay(y);
|
||||
solver.AddConstraint(eq);
|
||||
cout << "x = " << x.Value() << endl
|
||||
<< "y = " << y.Value() << endl;
|
||||
fOkResult = (x.Value() == y.Value());
|
||||
return fOkResult;
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add an edit variable to an empty solver */
|
||||
bool
|
||||
simple2()
|
||||
{
|
||||
try
|
||||
{
|
||||
ClVariable x(167);
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver.AddEditVar(x);
|
||||
solver.BeginEdit();
|
||||
solver.SuggestValue(x,100);
|
||||
solver.EndEdit();
|
||||
|
||||
cout << "x = " << x.Value() << endl;
|
||||
}
|
||||
catch (ExCLEditMisuse &error)
|
||||
{
|
||||
cout << "Success: got the exception" << endl;
|
||||
return true;
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
cerr << "Should have gotten an exception!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
justStay1()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
ClVariable x(5);
|
||||
ClVariable y(10);
|
||||
ClSimplexSolver solver;
|
||||
|
||||
#if 0
|
||||
solver.AddPointStay(x,y,1);
|
||||
#else
|
||||
solver.AddStay(x);
|
||||
solver.AddStay(y);
|
||||
#endif
|
||||
fOkResult = fOkResult && ClApprox(x,5);
|
||||
fOkResult = fOkResult && ClApprox(y,10);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
cout << "y == " << y.Value() << endl;
|
||||
|
||||
return(fOkResult);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
addDelete1()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
ClVariable x("x");
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver.AddConstraint(new ClLinearEquation( x, 100, ClsWeak() ));
|
||||
|
||||
ClLinearInequality c10(x,cnLEQ,10.0);
|
||||
ClLinearInequality c20(x,cnLEQ,20.0);
|
||||
solver
|
||||
.AddConstraint(c10)
|
||||
.AddConstraint(c20);
|
||||
|
||||
fOkResult = fOkResult && ClApprox(x,10.0);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
|
||||
cout << endl << solver << endl;
|
||||
|
||||
solver.RemoveConstraint(c10);
|
||||
|
||||
cout << endl << solver << endl;
|
||||
|
||||
fOkResult = fOkResult && ClApprox(x,20.0);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
|
||||
solver.RemoveConstraint(c20);
|
||||
fOkResult = fOkResult && ClApprox(x,100.0);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
|
||||
ClLinearInequality c10again(x,cnLEQ,10.0);
|
||||
|
||||
solver
|
||||
.AddConstraint(c10)
|
||||
.AddConstraint(c10again);
|
||||
|
||||
fOkResult = fOkResult && ClApprox(x,10.0);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
|
||||
solver.RemoveConstraint(c10);
|
||||
fOkResult = fOkResult && ClApprox(x,10.0);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
|
||||
solver.RemoveConstraint(c10again);
|
||||
fOkResult = fOkResult && ClApprox(x,100.0);
|
||||
cout << "x == " << x.Value() << endl;
|
||||
|
||||
return(fOkResult);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
addDelete2()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
ClVariable x("x");
|
||||
ClVariable y("y");
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver
|
||||
.AddConstraint(new ClLinearEquation(x, 100.0, ClsWeak()))
|
||||
.AddConstraint(new ClLinearEquation(y, 120.0, ClsStrong()));
|
||||
|
||||
ClLinearInequality c10(x,cnLEQ,10.0);
|
||||
ClLinearInequality c20(x,cnLEQ,20.0);
|
||||
|
||||
solver
|
||||
.AddConstraint(c10)
|
||||
.AddConstraint(c20);
|
||||
fOkResult = fOkResult && ClApprox(x,10.0) && ClApprox(y,120.0);
|
||||
cout << "x == " << x.Value() << ", y == " << y.Value() << endl;
|
||||
|
||||
solver.RemoveConstraint(c10);
|
||||
fOkResult = fOkResult && ClApprox(x,20.0) && ClApprox(y,120.0);
|
||||
cout << "x == " << x.Value() << ", y == " << y.Value() << endl;
|
||||
|
||||
ClLinearEquation cxy( 2*x, y);
|
||||
solver.AddConstraint(cxy);
|
||||
fOkResult = fOkResult && ClApprox(x,20.0) && ClApprox(y,40.0);
|
||||
cout << "x == " << x.Value() << ", y == " << y.Value() << endl;
|
||||
|
||||
solver.RemoveConstraint(c20);
|
||||
fOkResult = fOkResult && ClApprox(x,60.0) && ClApprox(y,120.0);
|
||||
cout << "x == " << x.Value() << ", y == " << y.Value() << endl;
|
||||
|
||||
solver.RemoveConstraint(cxy);
|
||||
fOkResult = fOkResult && ClApprox(x,100.0) && ClApprox(y,120.0);
|
||||
cout << "x == " << x.Value() << ", y == " << y.Value() << endl;
|
||||
|
||||
|
||||
return(fOkResult);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
casso1()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
ClVariable x("x");
|
||||
ClVariable y("y");
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver
|
||||
.AddConstraint(new ClLinearInequality(x,cnLEQ,y))
|
||||
.AddConstraint(new ClLinearEquation(y, x+3.0))
|
||||
.AddConstraint(new ClLinearEquation(x,10.0,ClsWeak()))
|
||||
.AddConstraint(new ClLinearEquation(y,10.0,ClsWeak()))
|
||||
;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
( ClApprox(x,10.0) && ClApprox(y,13.0) ||
|
||||
ClApprox(x,7.0) && ClApprox(y,10.0) );
|
||||
|
||||
cout << "x == " << x.Value() << ", y == " << y.Value() << endl;
|
||||
|
||||
return(fOkResult);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
inconsistent1()
|
||||
{
|
||||
ClSimplexSolver solver;
|
||||
ClVariable x("x");
|
||||
ClLinearEquation eq1(x,10.0);
|
||||
ClLinearEquation eq2(x,5.0);
|
||||
try
|
||||
{
|
||||
|
||||
solver.AddConstraint( eq1 );
|
||||
solver.AddConstraint( eq2 );
|
||||
|
||||
// no exception, we failed!
|
||||
return(false);
|
||||
}
|
||||
catch (ExCLRequiredFailure)
|
||||
{
|
||||
// we want this exception to get thrown
|
||||
cout << "Success -- got the exception" << endl;
|
||||
// solver.RemoveConstraint(eq2); this would throw a constraint not found exception
|
||||
// cout << solver << endl;
|
||||
return(true);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
inconsistent2()
|
||||
{
|
||||
try
|
||||
{
|
||||
ClVariable x("x");
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver
|
||||
.AddConstraint(new ClLinearInequality(x,cnGEQ,10.0))
|
||||
.AddConstraint(new ClLinearInequality(x,cnLEQ, 5.0));
|
||||
|
||||
// no exception, we failed!
|
||||
return(false);
|
||||
}
|
||||
catch (ExCLRequiredFailure &)
|
||||
{
|
||||
// we want this exception to get thrown
|
||||
cout << "Success -- got the exception" << endl;
|
||||
// cout << solver << endl;
|
||||
return(true);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
inconsistent3()
|
||||
{
|
||||
try
|
||||
{
|
||||
ClVariable w("w");
|
||||
ClVariable x("x");
|
||||
ClVariable y("y");
|
||||
ClVariable z("z");
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver
|
||||
.AddConstraint(new ClLinearInequality(w,cnGEQ,10.0))
|
||||
.AddConstraint(new ClLinearInequality(x,cnGEQ,w))
|
||||
.AddConstraint(new ClLinearInequality(y,cnGEQ,x))
|
||||
.AddConstraint(new ClLinearInequality(z,cnGEQ,y))
|
||||
.AddConstraint(new ClLinearInequality(z,cnLEQ,4.0));
|
||||
|
||||
// no exception, we failed!
|
||||
return(false);
|
||||
}
|
||||
catch (ExCLRequiredFailure &)
|
||||
{
|
||||
// we want this exception to get thrown
|
||||
cout << "Success -- got the exception" << endl;
|
||||
// cout << solver << endl;
|
||||
return(true);
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
multiedit()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
|
||||
ClVariable x("x",0);
|
||||
ClVariable y("y",0);
|
||||
ClVariable w("w",0);
|
||||
ClVariable h("h",0);
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver
|
||||
.AddStay(x)
|
||||
.AddStay(y)
|
||||
.AddStay(w)
|
||||
.AddStay(h);
|
||||
|
||||
solver
|
||||
.AddEditVar(x)
|
||||
.AddEditVar(y)
|
||||
.BeginEdit();
|
||||
|
||||
solver
|
||||
.SuggestValue(x,10)
|
||||
.SuggestValue(y,20)
|
||||
.Resolve();
|
||||
|
||||
cout << "x = " << x.Value() << "; y = " << y.Value() << endl
|
||||
<< "w = " << w.Value() << "; h = " << h.Value() << endl;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,0) && ClApprox(h,0);
|
||||
|
||||
solver
|
||||
.AddEditVar(w)
|
||||
.AddEditVar(h)
|
||||
.BeginEdit();
|
||||
|
||||
solver
|
||||
.SuggestValue(w,30)
|
||||
.SuggestValue(h,40)
|
||||
.EndEdit();
|
||||
|
||||
cout << "x = " << x.Value() << "; y = " << y.Value() << endl
|
||||
<< "w = " << w.Value() << "; h = " << h.Value() << endl;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,30) && ClApprox(h,40);
|
||||
|
||||
solver
|
||||
.SuggestValue(x,50)
|
||||
.SuggestValue(y,60)
|
||||
.EndEdit();
|
||||
|
||||
cout << "x = " << x.Value() << "; y = " << y.Value() << endl
|
||||
<< "w = " << w.Value() << "; h = " << h.Value() << endl;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
ClApprox(x,50) && ClApprox(y,60) && ClApprox(w,30) && ClApprox(h,40);
|
||||
|
||||
return fOkResult;
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
cerr << "Should have gotten an exception!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
multiedit2()
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fOkResult = true;
|
||||
|
||||
ClVariable x("x",0);
|
||||
ClVariable y("y",0);
|
||||
ClVariable w("w",0);
|
||||
ClVariable h("h",0);
|
||||
ClSimplexSolver solver;
|
||||
|
||||
solver
|
||||
.AddStay(x)
|
||||
.AddStay(y)
|
||||
.AddStay(w)
|
||||
.AddStay(h);
|
||||
|
||||
solver
|
||||
.AddEditVar(x)
|
||||
.AddEditVar(y)
|
||||
.BeginEdit();
|
||||
|
||||
solver
|
||||
.SuggestValue(x,10)
|
||||
.SuggestValue(y,20)
|
||||
.Resolve();
|
||||
|
||||
cout << "x = " << x.Value() << "; y = " << y.Value() << endl
|
||||
<< "w = " << w.Value() << "; h = " << h.Value() << endl;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,0) && ClApprox(h,0);
|
||||
|
||||
solver
|
||||
.AddEditVar(x)
|
||||
.AddEditVar(y)
|
||||
.AddEditVar(w)
|
||||
.AddEditVar(h)
|
||||
.BeginEdit();
|
||||
|
||||
solver
|
||||
.SuggestValue(w,30)
|
||||
.SuggestValue(h,40)
|
||||
.EndEdit();
|
||||
|
||||
cout << "x = " << x.Value() << "; y = " << y.Value() << endl
|
||||
<< "w = " << w.Value() << "; h = " << h.Value() << endl;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
ClApprox(x,10) && ClApprox(y,20) && ClApprox(w,30) && ClApprox(h,40);
|
||||
|
||||
solver
|
||||
.SuggestValue(x,50)
|
||||
.SuggestValue(y,60)
|
||||
.EndEdit();
|
||||
|
||||
cout << "x = " << x.Value() << "; y = " << y.Value() << endl
|
||||
<< "w = " << w.Value() << "; h = " << h.Value() << endl;
|
||||
|
||||
fOkResult = fOkResult &&
|
||||
ClApprox(x,50) && ClApprox(y,60) && ClApprox(w,30) && ClApprox(h,40);
|
||||
|
||||
return fOkResult;
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
cerr << "Should have gotten an exception!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// From a bug report from Steve Wolfman on his
|
||||
// SAT project using "blackbox"
|
||||
bool
|
||||
blackboxsat()
|
||||
{
|
||||
try
|
||||
{
|
||||
ClSimplexSolver solver;
|
||||
|
||||
ClVariable r1("r1");
|
||||
ClVariable r2("r2");
|
||||
ClVariable r3("r3");
|
||||
ClVariable r4("r4");
|
||||
ClVariable r5("r5");
|
||||
ClVariable r6("r6");
|
||||
ClVariable r7("r7");
|
||||
ClVariable r8("r8");
|
||||
|
||||
ClConstraint *rgpcn[30];
|
||||
for (int i=0; i<int(sizeof(rgpcn)/sizeof(rgpcn[0])); ++i)
|
||||
rgpcn[i] = NULL;
|
||||
|
||||
rgpcn[1] = new ClLinearEquation(r1,60);
|
||||
rgpcn[2] = new ClLinearEquation(r2,30);
|
||||
rgpcn[12] = new ClLinearEquation(r3,2.5);
|
||||
rgpcn[13] = new ClLinearEquation(r6,0);
|
||||
rgpcn[14] = new ClLinearInequality(r5, cnGEQ, 0);
|
||||
rgpcn[15] = new ClLinearInequality(r8, cnLEQ, 2.5);
|
||||
rgpcn[16] = new ClLinearInequality(r7, cnGEQ, r6);
|
||||
rgpcn[17] = new ClLinearInequality(r8, cnGEQ, r7);
|
||||
rgpcn[18] = new ClLinearEquation(r4, r3 - r2/60.0);
|
||||
rgpcn[19] = new ClLinearEquation(r5, r4 - r1/60.0);
|
||||
rgpcn[20] = new ClLinearInequality(r4, cnGEQ, 0);
|
||||
rgpcn[21] = new ClLinearInequality(r5, cnGEQ, 0);
|
||||
rgpcn[22] = new ClLinearEquation(r7, r6 + r2/20.0);
|
||||
rgpcn[23] = new ClLinearEquation(r8, r7 + r1/20.0);
|
||||
rgpcn[24] = new ClLinearEquation(r4, r3 - r2/30.0);
|
||||
rgpcn[25] = new ClLinearEquation(r5, r4 - r1/30.0);
|
||||
rgpcn[26] = new ClLinearInequality(r4, cnGEQ, 0);
|
||||
rgpcn[27] = new ClLinearInequality(r5, cnGEQ, 0);
|
||||
rgpcn[28] = new ClLinearEquation(r7, r6 + r2/60.0);
|
||||
rgpcn[29] = new ClLinearEquation(r8, r7 + r1/60.0);
|
||||
|
||||
while (true)
|
||||
{
|
||||
char szCmd[1000];
|
||||
int i;
|
||||
cin >> szCmd;
|
||||
if (!cin)
|
||||
break;
|
||||
if (szCmd[0] == '#')
|
||||
{
|
||||
cin.getline(szCmd,900);
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(szCmd,"Add") == 0)
|
||||
{
|
||||
cin >> i;
|
||||
cout << "eq" << i << ": " << solver.AddConstraintNoException(rgpcn[i])
|
||||
<< "\t" << *(rgpcn[i]) << endl;
|
||||
cout << r1 << " = " << r1.Value() << endl;
|
||||
}
|
||||
else if (strcasecmp(szCmd,"del") == 0)
|
||||
{
|
||||
cin >> i;
|
||||
cout << "REMeq" << i << ": " << solver.RemoveConstraintNoException(rgpcn[i])
|
||||
<< "\t" << *(rgpcn[i]) << endl;
|
||||
cout << r1 << " = " << r1.Value() << endl;
|
||||
}
|
||||
else if (strcasecmp(szCmd,"dump") == 0)
|
||||
{
|
||||
cout << solver << endl;
|
||||
}
|
||||
else if (strcasecmp(szCmd,"val") == 0)
|
||||
{
|
||||
cout << r1 << " = " << r1.Value() << endl;
|
||||
}
|
||||
else if (strcasecmp(szCmd,"solve") == 0)
|
||||
{
|
||||
cout << solver.Solve() << endl;
|
||||
}
|
||||
else if (strcasecmp(szCmd,"autosolve") == 0)
|
||||
{
|
||||
solver.SetAutosolve(true);
|
||||
}
|
||||
else if (strcasecmp(szCmd,"noautosolve") == 0)
|
||||
{
|
||||
solver.SetAutosolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
cout << r1 << " = " << r1.Value() << endl
|
||||
<< r2 << " = " << r2.Value() << endl
|
||||
<< r3 << " = " << r3.Value() << endl
|
||||
<< r4 << " = " << r4.Value() << endl
|
||||
<< r5 << " = " << r5.Value() << endl
|
||||
<< r6 << " = " << r6.Value() << endl
|
||||
<< r7 << " = " << r7.Value() << endl
|
||||
<< r8 << " = " << r8.Value() << endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (ExCLError &error)
|
||||
{
|
||||
cerr << "Exception! " << error.description() << endl;
|
||||
return(true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception" << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
typedef ClVariable *PClVariable;
|
||||
|
||||
bool
|
||||
addDel(const int nCns = 900, const int nVars = 900, const int nResolves = 10000)
|
||||
//addDel(int nCns = 300, int nVars = 300, int nResolves = 1000)
|
||||
//addDel(int nCns = 30, int nVars = 30, int nResolves = 100)
|
||||
{
|
||||
Timer timer;
|
||||
// FIXGJB: from where did .12 come?
|
||||
static const double ineqProb = 0.12;
|
||||
static const int maxVars = 3;
|
||||
|
||||
cout << "starting timing test. nCns = " << nCns
|
||||
<< ", nVars = " << nVars << ", nResolves = " << nResolves << endl;
|
||||
|
||||
timer.Start();
|
||||
ClSimplexSolver solver;
|
||||
solver.SetAutosolve(false);
|
||||
|
||||
ClVariable **rgpclv = new PClVariable[nVars];
|
||||
for (int i = 0; i < nVars; i++)
|
||||
{
|
||||
rgpclv[i] = new ClVariable(i,"x");
|
||||
solver.AddStay(*rgpclv[i]);
|
||||
}
|
||||
|
||||
ClConstraint **rgpcns = new PClConstraint[nCns];
|
||||
int nvs = 0;
|
||||
int k;
|
||||
int j;
|
||||
double coeff;
|
||||
for (j = 0; j < nCns; j++)
|
||||
{
|
||||
// number of variables in this constraint
|
||||
nvs = int(UniformRandom()*maxVars) + 1;
|
||||
ClLinearExpression expr = UniformRandom()*20.0 - 10.0;
|
||||
for (k = 0; k < nvs; k++)
|
||||
{
|
||||
coeff = UniformRandom()*10 - 5;
|
||||
expr.AddExpression(*(rgpclv[int(UniformRandom()*nVars)]) * coeff);
|
||||
}
|
||||
if (UniformRandom() < ineqProb)
|
||||
{
|
||||
rgpcns[j] = new ClLinearInequality(expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
rgpcns[j] = new ClLinearEquation(expr);
|
||||
}
|
||||
#ifdef CL_SHOW_CNS_IN_BENCHMARK
|
||||
cout << "Cn[" << j << "]: " << *rgpcns[j] << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
cout << "done building data structures" << endl;
|
||||
cout << "time = " << timer.ElapsedTime() << "\n" << endl;
|
||||
timer.Start();
|
||||
int cExceptions = 0;
|
||||
#ifdef CL_SHOW_CNS_IN_BENCHMARK
|
||||
cout << "Exceptions on: ";
|
||||
#endif
|
||||
for (j = 0; j < nCns; j++)
|
||||
{
|
||||
// Add the constraint -- if it's incompatible, just ignore it
|
||||
try
|
||||
{
|
||||
solver.AddConstraint(rgpcns[j]);
|
||||
}
|
||||
catch (ExCLRequiredFailure &)
|
||||
{
|
||||
cExceptions++;
|
||||
rgpcns[j] = NULL;
|
||||
#ifdef CL_SHOW_CNS_IN_BENCHMARK
|
||||
cout << j << " ";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef CL_SHOW_CNS_IN_BENCHMARK
|
||||
cout << "\n" << endl;
|
||||
#endif
|
||||
solver.Solve();
|
||||
cout << "done adding constraints [" << cExceptions << " exceptions]" << endl;
|
||||
cout << "time = " << timer.ElapsedTime() << "\n" << endl;
|
||||
cout << "time per cn = " << timer.ElapsedTime()/nCns << "\n" << endl;
|
||||
cout << "time per actual cn = " << timer.ElapsedTime()/(nCns - cExceptions) << "\n" <<endl;
|
||||
timer.Start();
|
||||
|
||||
int e1Index = int(UniformRandom()*nVars);
|
||||
int e2Index = int(UniformRandom()*nVars);
|
||||
|
||||
ClVariable e1 = *(rgpclv[e1Index]);
|
||||
ClVariable e2 = *(rgpclv[e2Index]);
|
||||
|
||||
solver
|
||||
.AddEditVar(e1)
|
||||
.AddEditVar(e2);
|
||||
|
||||
cout << "done creating edit constraints -- about to start resolves" << endl;
|
||||
cout << "time = " << timer.ElapsedTime() << "\n" << endl;
|
||||
timer.Start();
|
||||
|
||||
solver.BeginEdit();
|
||||
// FIXGJB start = Timer.now();
|
||||
for (int m = 0; m < nResolves; ++m)
|
||||
{
|
||||
solver
|
||||
.SuggestValue(e1,e1->Value()*1.001)
|
||||
.SuggestValue(e2,e2->Value()*1.001)
|
||||
.Resolve();
|
||||
}
|
||||
solver.EndEdit();
|
||||
// cout << "run time: " <<
|
||||
|
||||
cout << "done resolves -- now removing constraints" << endl;
|
||||
cout << "time = " << timer.ElapsedTime() << "\n" <<endl;
|
||||
cout << "time per Resolve = " << timer.ElapsedTime()/nResolves << "\n" <<endl;
|
||||
|
||||
timer.Start();
|
||||
|
||||
for (j = 0; j < nCns; j++)
|
||||
{
|
||||
if (rgpcns[j])
|
||||
{
|
||||
solver.RemoveConstraint(rgpcns[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXGJB end = Timer.now();
|
||||
// cout << "Total remove time: "
|
||||
// << "remove time per cn"
|
||||
cout << "done removing constraints and addDel timing test" << endl;
|
||||
cout << "time = " << timer.ElapsedTime() << "\n" <<endl;
|
||||
cout << "time per cn = " << timer.ElapsedTime()/nCns << "\n" <<endl;
|
||||
cout << "time per actual cn = " << timer.ElapsedTime()/(nCns - cExceptions) << "\n" <<endl;
|
||||
|
||||
for (int i = 0; i < nVars; i++)
|
||||
{
|
||||
delete rgpclv[i];
|
||||
}
|
||||
|
||||
for (int j = 0; j < nCns; j++)
|
||||
{
|
||||
delete rgpcns[j];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
try
|
||||
{
|
||||
bool fAllOkResult = true;
|
||||
bool fResult;
|
||||
|
||||
// seed the random number generator for reproducible results
|
||||
srand(123456789);
|
||||
|
||||
cout << "Cassowary version: " << szCassowaryVersion << endl;
|
||||
|
||||
#define RUN_TEST(x) \
|
||||
cout << #x << ":" << endl; \
|
||||
fResult = x(); fAllOkResult &= fResult; \
|
||||
if (!fResult) cout << "Failed!" << endl;
|
||||
|
||||
RUN_TEST(simple1);
|
||||
RUN_TEST(simple2);
|
||||
RUN_TEST(justStay1);
|
||||
RUN_TEST(addDelete1);
|
||||
RUN_TEST(addDelete2);
|
||||
RUN_TEST(casso1);
|
||||
RUN_TEST(inconsistent1);
|
||||
RUN_TEST(inconsistent2);
|
||||
RUN_TEST(inconsistent3);
|
||||
RUN_TEST(multiedit);
|
||||
RUN_TEST(multiedit2);
|
||||
// RUN_TEST(blackboxsat);
|
||||
|
||||
int cns = 90, vars = 90, resolves = 100;
|
||||
|
||||
if (argc > 1)
|
||||
cns = atoi(argv[1]);
|
||||
|
||||
if (argc > 2)
|
||||
vars = atoi(argv[2]);
|
||||
|
||||
if (argc > 3)
|
||||
resolves = atoi(argv[3]);
|
||||
|
||||
if (cns > 0)
|
||||
{
|
||||
cout << "addDel" << ":" << endl;
|
||||
fResult = addDel(cns,vars,resolves); fAllOkResult &= fResult;
|
||||
if (!fResult) cout << "Failed!" << endl;
|
||||
}
|
||||
|
||||
#undef RUN_TEST
|
||||
|
||||
#ifdef CL_FIND_LEAK
|
||||
cout << "ClAbstractVariables: " << ClAbstractVariable::cAbstractVariables
|
||||
<< "\nClDummyVariables: " << ClDummyVariable::cDummyVariables
|
||||
<< "\nClSlackVariables: " << ClSlackVariable::cSlackVariables
|
||||
<< endl;
|
||||
#endif
|
||||
|
||||
|
||||
return (fAllOkResult? 0 : 255);
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "exception!" << endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClVariable.cc
|
||||
|
||||
#include <cassowary/ClVariable.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#define CONFIG_H_INCLUDED
|
||||
#endif
|
||||
|
||||
StringToVarMap *ClVariable::pmapStrPclv = NULL;
|
||||
ClVariable clvNil(static_cast<ClAbstractVariable*>(0));
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
Cassowary/C++ needs to be compiled using a modern C++ compiler.
|
||||
At one time or another, it has compiled using:
|
||||
o egcs-1.0.1, egcs-1.0.3, egcs-1.1b, gcc-2.8.1, gcc-2.95.2
|
||||
o Visual C++ 5.0
|
||||
|
||||
Cassowary/Java was developed using Sun's JDK-1.1.3, ported to Linux
|
||||
More recent versions should work fine, and it has been tested
|
||||
with JDK-1.2pre2.
|
||||
|
||||
The included Makefiles depend upon features of GNU Make. See:
|
||||
|
||||
ftp://ftp.gnu.org/pub/gnu/
|
||||
|
||||
for a version that you can build.
|
||||
|
||||
|
||||
To build the c++/qdemos/QuadDemo application, you'll need TrollTech's Qt
|
||||
widget set for X11, available from:
|
||||
|
||||
http://www.troll.no/dl/qtfree-dl.html
|
||||
|
||||
|
||||
See also the Scwm (Scheme Constraints Window Manager) web page for a use
|
||||
of Cassowary in a substantial application:
|
||||
|
||||
http://scwm.mit.edu/scwm/
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
Cassowary Constraint Solving Toolkit
|
||||
Copyright (C) 1998-200 Greg J. Badros
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
See COPYING.LGPL
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
Cassowary NEWS -- history of user-visible changes. -*- text -*-
|
||||
|
||||
Cassowary Constraint Solving Toolkit was
|
||||
Implemented by:
|
||||
|
||||
Greg J. Badros <gjb@cs.washington.edu> and
|
||||
Alan Borning <borning@cs.washington.edu>
|
||||
University of Washington
|
||||
Computer Science and Engineering
|
||||
Seattle, WA 98195-2350
|
||||
|
||||
with Constraint Drawing Applet (CDA) by Michael Noth <noth@cs.washington.edu>
|
||||
|
||||
12-March-2000: Version 0.60 released.
|
||||
* Changed license to LGPL!!!
|
||||
* Added SetAutoResetStayConstants(), FIsAutoResetStayConstants(), make ResetStayConstants() public
|
||||
|
||||
29-Jan-2000: Version 0.55 released.
|
||||
* Some bug fixes
|
||||
* Added ClSimplexSolver::{ChangeStrength,ChangeStrengthAndWeight,ChangeWeight,
|
||||
DisplayObjective,ExternalResetStayConstants} fns
|
||||
From A. Beurivé.
|
||||
|
||||
16-Dec-1999: Version 0.54a released.
|
||||
* Include correct version of OTI Smalltalk .dat file
|
||||
(the source in the *.app files was right, the .dat file was old)
|
||||
* Fix java build bug
|
||||
|
||||
15-Dec-1999: Version 0.54 released.
|
||||
* Bug fixes
|
||||
* auto-configuration improvements
|
||||
* Support Java 2 (jdk-1.2)
|
||||
* Improved ease of building Java demos
|
||||
* Build guile wrapper as long as guile-config works, use new --disable-guile-build to force off
|
||||
* Alpha-version of Java constraint parser contributed by Will Portnoy
|
||||
|
||||
24-October-1999: Version 0.53 released.
|
||||
* Bug fixes
|
||||
* License exception for linking with Scwm.
|
||||
|
||||
25-September-1999: Version 0.52 released.
|
||||
* Bug fix for nested edits where a later edit includes an already-being-edited variable
|
||||
|
||||
14-September-1999: Version 0.51 released.
|
||||
* Minor bug fixes
|
||||
* Much better packaging, RPMs, etc. more forced reliance on GTL
|
||||
|
||||
26-August-1999: Version 0.51 pre-releases begin
|
||||
|
||||
12-July-1999: Version 0.50 released.
|
||||
* Made only C++ version build by default, --enable-java-build is needed to turn java on
|
||||
* Added restricted finite domain solver
|
||||
** needs --with-gtl configure option, and libGTL.{a,so*} to be installed
|
||||
* Added ClSolver base class, and use its type for pointers in callbacks
|
||||
|
||||
14-Apr-1999: Version 0.43 released.
|
||||
* DEBUG_PARSE turned off by default
|
||||
* Added cassowary.spec for RPM building
|
||||
|
||||
31-Mar-1999: Version 0.42 released.
|
||||
* Fixed autoconf bugs (.41 was a buggy release)
|
||||
* Added --disable-cpp-build,--disable-java-build, and disable Python/Guile builds
|
||||
automatically if directories cannot be found
|
||||
|
||||
20-Mar-1999: Version 0.41 released.
|
||||
* Fixed bug in autoconf support -- config.sub, config.guess to the
|
||||
distribution so configure should actually work (they were symlinks
|
||||
before, in error).
|
||||
|
||||
18-Mar-1999: Version 0.4 released.
|
||||
|
||||
18-Mar-1999: Changes since Cassowary v0.32 (for release v0.4)
|
||||
* MUCH improved autoconf/automake support including numerous configure
|
||||
options, added libtool support.
|
||||
* Renamed many identifiers in the public API; this will break old code
|
||||
using Cassowary. See the scripts/convert-ids script for help converting
|
||||
your code (beware false positives; i.e., improper or unnecessary
|
||||
changes).
|
||||
|
||||
|
||||
10-Mar-1999: Changes since Cassowary v0.31 (for release v0.32)
|
||||
* Added automake/autoconf support. Old Makefiles are now
|
||||
Makefile.linux. This is not yet fully tested or correct, but I need to
|
||||
make a release now for the bug fixes. Consider compiling with "make -f
|
||||
Makefile.linux all" if you have problems running autoconf and/or
|
||||
automake.
|
||||
|
||||
* Changes to C++
|
||||
** Bug fix for problem Anthony Beurivé noticed regarding removing non-1
|
||||
weight stay constraints.
|
||||
** Minor bug fix for parser. Also renamed the creader files to ClReader.
|
||||
|
||||
* Changes to Java
|
||||
** Bug fix for problem Emmanuel Pietriga reported regarding edit
|
||||
constraints.
|
||||
** Improved debugging support a bit by adding descriptions to
|
||||
ExCLInternalError-s and assert()s
|
||||
|
||||
* Changes to guile wrapper
|
||||
** changed name of library to libcassowaryguile.a from libconstraints.a
|
||||
|
||||
|
||||
1-Mar-1999: Changes since Cassowary v0.3 (for release v0.31)
|
||||
* Changes to C++
|
||||
** Some bug fixes -- pass ClVariable-s around by value instead of const
|
||||
& since they are now a handle class.
|
||||
** Changed output format for ClEditConstraint, ClStayConstraint instances
|
||||
** Use a function-object for controlling lookup/creation of variables in PcnParseConstraint
|
||||
** Fix bugs in creader.y parser (did not accept parens or division
|
||||
before). Introduced "==" as a a synonym for "="
|
||||
** Added szCassowaryVersion id string as a public char *.
|
||||
** Added ChangeStrength, ChangeWeight to ClConstraint's public
|
||||
interface, and have it valid only when the constraint is not in a solver
|
||||
** Added ClConstraint::FIsInSolver()
|
||||
|
||||
* Changes to Guile wrapper
|
||||
** Fix bugs
|
||||
** Wrap parsing functionality, including a lambda for lookup/creation of
|
||||
variables
|
||||
** Build a dynamically-loadable guile module, update cltests.scm to use it
|
||||
|
||||
|
||||
23-Feb-1999: Version 0.3 released.
|
||||
|
||||
19-Feb-1999, Changes since Cassowary v0.23 (for release v0.3)
|
||||
|
||||
* Changes to Java and C++
|
||||
** Bug fix for Michael Kaufmann's report (see ChangeLog for details)
|
||||
** resolve(Vector..) procedure is now depracated; preferred interface is
|
||||
suggestValue(...) calls followed by resolve() (the one taking no
|
||||
arguments).
|
||||
** Added ClVariable::SetVarMap(..), ClVariable::VarMap() to permit
|
||||
ClVariable ctr to save the mapping between given name and actual object
|
||||
in a symbol table (used for parsing ascii expressions in C++ version)
|
||||
|
||||
* Changes to just C++ implementation
|
||||
** Use ClVariable as a handle class to a ClAbstractVariable-- old
|
||||
ClVariable is now a ClFloatVariable. SetChangeClvCallback now takes a
|
||||
function that takes a ClVariable handle, not a pointer.
|
||||
** Passing ClConstraints's by const & is now deprecated -- pass by
|
||||
pointer to the ClConstraint object
|
||||
** Added creader.y, creader.l and function PcnParseConstraint(..) for
|
||||
creating a constraint from an ASCII string.
|
||||
** Added CL_NO_IO compile-time option to C++ version for preventing need
|
||||
to link with the stream library (is not complete)
|
||||
** Added CL_FIND_LEAK compile-time option for counting ctrs/dtr
|
||||
invocations
|
||||
** Added CL_USE_HASH_MAP compile-time option to permit using the GNU
|
||||
hash_map class instead of the standard STL map (which is a sorted
|
||||
associative container whose performance for lookups is logarithmic
|
||||
rather than constant time). Still does not work for me --02/16/99 gjb.
|
||||
|
||||
* Changes to just Java implementation (updated to match changes to C++
|
||||
version for .2)
|
||||
** Added {get,set}AttachedObject for ClVariable, ClConstant
|
||||
** Permit access to ClSimplexSolver.ConstraintMap()
|
||||
** Permit nested beginEdit()s and handle them correctly
|
||||
|
||||
* Miscellaneous changes
|
||||
** Updated copyright to include 1999
|
||||
** Fixed wrappers/Makefile for building Python wrapper
|
||||
** Reference Anthony Beurivé's STk wrapper
|
||||
** Fix Scwm URL
|
||||
|
||||
|
||||
30-Jan-1999, Changes since Cassowary v0.22 (for release v0.23)
|
||||
* Bug fix (see ChangeLog for details)
|
||||
|
||||
|
||||
23-Jan-1999, Changes since Cassowary v0.21 (for release v0.22)
|
||||
* Minor code cleanup, additions of comments.
|
||||
|
||||
|
||||
14-Sep-98, Changes since Cassowary v0.2 (for release v0.21)
|
||||
|
||||
* Make compile cleanly using egcs-1.1b -- use typename, and drop
|
||||
unused templated instantiation
|
||||
|
||||
* Improved guile interface: add a void pointer to the solver objects,
|
||||
and let the guile wrapper use it to keep a pointer to the scheme-level
|
||||
object; also added clv-attach! and clv-attached-object for attaching
|
||||
an object to a cl-variable (somewhat redundant with guile's
|
||||
object properties)
|
||||
|
||||
* Wrap ClStayConstraints so they can be managed explicitly
|
||||
|
||||
* cl-add-stay, cl-add-editvar now take strength and factor arguments,
|
||||
instead of a list of cl-vars
|
||||
|
||||
* Added weight option to addEditVar
|
||||
|
||||
|
||||
6-Aug-98, Changes since Cassowary v0.1 (for release v0.2):
|
||||
|
||||
* Changes to the distribution for release v0.2
|
||||
|
||||
** added guile/scheme wrapper of C++ version
|
||||
|
||||
** mention SCWM in README
|
||||
|
||||
** mention non-maintenance of Smalltalk implementation unless we have users
|
||||
|
||||
* Changes to the C++ and Java implementations
|
||||
|
||||
** Fixed several bugs -- dummy variables were wrongly being pivoted into
|
||||
the basis, and constraints that threw required failure exceptions
|
||||
were mistakenly remaining in the tableau (now trying to remove an
|
||||
exception that was not added because of a required-failure exception
|
||||
will correctly throw a ConstraintNotFound exception); more -- see ChangeLog
|
||||
|
||||
** Added a virtual change_value function to permit applications to watch
|
||||
for changes made to external variables.
|
||||
|
||||
* Changes to only the C++ version (Java version will catch up in 0.3)
|
||||
|
||||
** Added new test cases to ClTests, fixed bugs in ClTestColumns
|
||||
|
||||
** Added _pv (void *) field hanging off of ClConstraint and ClVariable
|
||||
for associating arbitrary structs with those (needed by SCWM)
|
||||
|
||||
** Permit nested beginEdit()s, and do the right thing upon calling
|
||||
endEdit() -- i.e., not all the edit variables are removed, only the
|
||||
nested ones
|
||||
|
||||
** Permit access to ClSimplexSolver::ConstraintMap() (used by
|
||||
guile-wrapper to efficiently get at a list of constraints in the
|
||||
solver)
|
||||
|
||||
** Added ExCLEditMisuse exception
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
Cassowary Constraint Solving Toolkit for C++, Java, and Smalltalk
|
||||
Version 0.60
|
||||
|
||||
Web Page: http://www.cs.washington.edu/research/constraints/cassowary
|
||||
Contact: cassowary@cs.washington.edu
|
||||
|
||||
Greg J. Badros <gjb@cs.washington.edu> and
|
||||
Alan Borning <borning@cs.washington.edu>
|
||||
University of Washington
|
||||
Computer Science and Engineering
|
||||
Seattle, WA 98195-2350
|
||||
12-March-2000
|
||||
|
||||
with Constraint Drawing Applet (CDA) by Michael Noth <noth@cs.washington.edu>
|
||||
|
||||
See ANNOUNCE for a brief description and announcement of this distribution.
|
||||
See NEWS for a history of user-visible changes.
|
||||
See ChangeLog for a detailed listing of the changes to each source file.
|
||||
See LICENSE for legalese regarding use of this distribution.
|
||||
|
||||
The Smalltalk implementation is in the public domain -- see smalltalk/README.
|
||||
|
||||
Please send bug reports to cassowary@cs.washington.edu
|
||||
|
||||
Also, send mail to cassowary@cs.washington.edu if you would like to be
|
||||
informed about bug fixes, feature enhancements, etc. Let us know what
|
||||
implementation(s) you are using, too.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
HOW TO GET STARTED
|
||||
|
||||
The Cassowary library uses GNU autoconf to permit easy building on
|
||||
various platforms. You should be able to do:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
and everything will work. A more complex, but realistic example is:
|
||||
|
||||
./configure --with-prefix=/usr/contrib \
|
||||
--with-guile-prefix=/usr/contrib \
|
||||
--with-python-headers=/usr/include/python1.5 \
|
||||
--enable-java-build \
|
||||
--with-gtl=/usr/contrib \
|
||||
--with-java-class-path=/usr/contrib/share/java/site \
|
||||
--enable-warnings
|
||||
make -k
|
||||
|
||||
Be sure to give the extra --enable-permissive flag to configure if
|
||||
you are building with gcc-2.95 or more recent.
|
||||
|
||||
As yet another data point, I build Cassowary with:
|
||||
|
||||
./configure --with-guile-exec-prefix=/uns/bin \
|
||||
--with-guile-prefix=/uns/share --prefix=/uns/share \
|
||||
--exec-prefix=/uns --enable-maintainer-mode
|
||||
|
||||
See the file "INSTALL" for more details about
|
||||
autoconf support and the options that the "configure" takes. You can
|
||||
also do "./configure --help" for the list of the options that configure
|
||||
accepts.
|
||||
|
||||
If the make in any of the subdirectories fails, you can turn on the "-k"
|
||||
option to make, or just do make in the subdirectories that you want
|
||||
build. E.g., if you do not have the JDK installed, the Java version of
|
||||
Cassowary might not compile; if you still want the guile version, just
|
||||
"cd guile; make -k".
|
||||
|
||||
Be sure that configure detects the validity of using the "-fpermissive"
|
||||
flag of more recent g++/egcs compilers to work around some
|
||||
const-discrepancies between the const-challenged guile header files and
|
||||
Cassowary's more const-correct usage. You should get a message like:
|
||||
|
||||
checking whether gcc understands -fpermissive option... yes
|
||||
|
||||
when running configure if you're using, e.g., gcc-2.95 or later.
|
||||
|
||||
You need to apply GTL.h.patch to the installed GTL.h header file for
|
||||
Cassowary to compile with recent versions of egcs/gcc (e.g., gcc-2.95).
|
||||
|
||||
Also, you may need to change libguile/gsubr.h from:
|
||||
|
||||
extern SCM scm_make_gsubr SCM_P ((char *name, int req, int opt,
|
||||
int rst, SCM (*fcn)()));
|
||||
to
|
||||
|
||||
extern SCM scm_make_gsubr SCM_P ((char *name, int req, int opt,
|
||||
int rst, void*));
|
||||
|
||||
or patch guile's snarf.h to insert the appropriate case at each call to
|
||||
SCM_PROC and SCM_PROC1. (Thanks to Alexandre Duret-Lutz for the above
|
||||
information about more recent g++/egcs compilers).
|
||||
|
||||
Note that the generated Makefiles depend upon features of GNU Make. See:
|
||||
|
||||
ftp://ftp.gnu.org/pub/gnu/
|
||||
|
||||
for a version of make that you can build first to then build Cassowary.
|
||||
|
||||
Example applications exist in subdirectories of the top-level
|
||||
implementation subdirectories (e.g., c++/qdemos contains demos for C++
|
||||
that use the Qt Widget toolkit).
|
||||
|
||||
Please send mail to cassowary@cs.washington.edu if you are using this
|
||||
toolkit so we know how to reach you for bug fixes, updates, etc.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
WHAT THE DISTRIBUTION CONTAINS
|
||||
|
||||
This distribution contains 3 implementations of the Cassowary constraint
|
||||
solving toolkit:
|
||||
|
||||
o C++
|
||||
o Java
|
||||
o Smalltalk
|
||||
|
||||
For each implementation language, there is at least one example program;
|
||||
for some there are many.
|
||||
|
||||
There is a wrapping of the C++ solver in Guile-Scheme -- see the guile/
|
||||
subdirectory. Also, Anthony Beurivé has wrapped Cassowary for
|
||||
STk/Scheme. His code is available at:
|
||||
|
||||
http://dept-info.labri.u-bordeaux.fr/~beurive/Code
|
||||
|
||||
and the STk Scheme system is available at:
|
||||
|
||||
http://kaolin.unice.fr/STk/
|
||||
|
||||
There is also a SWIG-generated wrapper of the C++ library making the
|
||||
solver available from the Python language.
|
||||
|
||||
A technical report describing the solver, its interface, and its
|
||||
implementation is in cassowary-tr.ps (pdf version in cassowary-tr.pdf).
|
||||
This paper is required reading if you intend to use the solver in your
|
||||
own project(s).
|
||||
|
||||
See also the Scwm (Scheme Constraints Window Manager) web page:
|
||||
|
||||
http://scwm.mit.edu/scwm/
|
||||
|
||||
Scwm, also by Greg Badros (and Maciej Stachowiak), is the most
|
||||
substantial application using this toolkit that we are aware of.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
VARIOUS IMPLEMENTATION NOTES
|
||||
|
||||
Cassowary/C++ needs to be compiled using a modern C++ compiler.
|
||||
At one time or another, it has compiled using:
|
||||
o egcs-1.0.1
|
||||
o egcs-1.0.3a
|
||||
o egcs-1.1b
|
||||
o egcs-1.1.1
|
||||
o gcc-2.8.1 (needs libstdc++-2.8.x, too)
|
||||
o Visual C++ 5.0 (not tried recently)
|
||||
|
||||
In particular, Cassowary will *not* build with gcc-2.7.x.x!
|
||||
|
||||
See c++/README for more details about building the C++ version.
|
||||
|
||||
The C++ implementation of the toolkit also has an optional finite domain
|
||||
subsolver. You need to build and install the GTL -- the Graph Template
|
||||
Library -- and use the "--with-gtl=DIR" configure option for the finite
|
||||
domain subsolver to be built. GTL is available from:
|
||||
|
||||
http://www.fmi.uni-passau.de/Graphlet/GTL/
|
||||
|
||||
Cassowary was tested against GTL-0.3.1; it may work with later
|
||||
versions, but I have not tried it. You need to apply GTL.h.patch to
|
||||
the installed GTL.h header file for Cassowary to compile with recent
|
||||
versions of egcs/gcc (e.g., gcc-2.95).
|
||||
|
||||
Cassowary/Java was developed using Sun's JDK-1.1.x, ported to Linux
|
||||
More recent versions should work fine.
|
||||
|
||||
See java/README for more details about building the Java version.
|
||||
|
||||
|
||||
Cassowary/Smalltalk was written under OTI Smalltalk-- other versions of
|
||||
smalltalk will likely require (possibly significant) changes.
|
||||
|
||||
See smalltalk/README for more details about the Smalltalk version.
|
||||
|
||||
See guile/README for details about the Guile Scheme wrapper of the C++
|
||||
implementation, and for a pointer to SCWM, the Scheme Constraints Window
|
||||
Manager which uses Cassowary.
|
||||
|
||||
The Python bindings (by Tessa Lau) bindings for the Cassowary library
|
||||
are in the wrappers/ subdirectory. SWIG was used in wrapping the
|
||||
library. These bindings may no longer work, and are provided only for
|
||||
your hacking pleasure (please send back useful patches if you do get the
|
||||
code working).
|
||||
|
||||
For more information about SWIG, see:
|
||||
|
||||
http://www.swig.org/
|
||||
|
||||
|
||||
For more information about the Python language, see:
|
||||
|
||||
http://www.python.org/
|
||||
|
||||
|
||||
For more information about the Guile-Scheme language, see:
|
||||
|
||||
http://www.red-bean.com/guile/
|
||||
http://www.fsf.org/software/guile/guile.html
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
DEMONSTRATION APPLICATION
|
||||
|
||||
A standard demonstration application is included for each implementation
|
||||
of the Cassowary solver. The application builds a quadrilateral and
|
||||
connects the neighboring midpoints of each of the outer edges to form an
|
||||
interior quadrilateral which is provably a parallelogram. The
|
||||
constraint solver manages the constraints to keep the outer
|
||||
quadrilateral inside the window, keep the midpoints properly positioned,
|
||||
and keep the outer quadrilateral from turning "inside out."
|
||||
|
||||
The user is able to select points (draggable boxes) and move them around
|
||||
within the window (both midpoints and endpoints can be selected, of
|
||||
course). The solver updates the figure, and redraws.
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
FUNDING ACKNOWLEDGEMENTS
|
||||
|
||||
This work has been funded in part by the National Science Foundation under
|
||||
Grants IRI-9302249 and CCR-9402551, by Object Technology International, and
|
||||
by a Fulbright Award from the Australian-American Educational
|
||||
Foundation.
|
||||
|
||||
Additionally, Greg Badros is supported by a National Science Foundation
|
||||
Graduate Research Fellowship. Parts of this material are based upon
|
||||
work supported under that fellowship.
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# -*- python -*-
|
||||
Import('env libraries')
|
||||
|
||||
cassowary = env.Copy(YACCFLAGS="-d")
|
||||
|
||||
domain = 'libcassowary'
|
||||
cassowary.Append(DOMAIN=domain,MAJOR=0,MINOR=60,MICRO=3)
|
||||
|
||||
cassowary_files = Split("""
|
||||
ClAbstractVariable.cc
|
||||
ClConstraint.cc
|
||||
ClLinearExpression.cc
|
||||
ClSolver.cc
|
||||
ClSimplexSolver.cc
|
||||
ClStrength.cc
|
||||
ClSymbolicWeight.cc
|
||||
ClTableau.cc
|
||||
ClVariable.cc
|
||||
ClFloatVariable.cc
|
||||
ClSlackVariable.cc
|
||||
ClDummyVariable.cc
|
||||
ClReader.cc
|
||||
ClReader-lex.cc
|
||||
""")
|
||||
|
||||
cassowary.Append(CCFLAGS="-D_REENTRANT")
|
||||
|
||||
cassowary.CXXFile(target = ['ClReader.cc', 'ClReader.cc.h'], source = 'ClReader.yy')
|
||||
cassowary.CXXFile(target = 'ClReader-lex.cc', source = 'ClReader.ll')
|
||||
|
||||
libcassowary = cassowary.SharedLibrary('cassowary', cassowary_files)
|
||||
Default(libcassowary)
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
Cassowary Constraint Solving Toolkit was
|
||||
Implemented by:
|
||||
|
||||
Greg J. Badros <gjb@cs.washington.edu> and
|
||||
Alan Borning <borning@cs.washington.edu>
|
||||
University of Washington
|
||||
Computer Science and Engineering
|
||||
Seattle, WA 98195-2350
|
||||
|
||||
with Constraint Drawing Applet (CDA) by Michael Noth <noth@cs.washington.edu>
|
||||
|
||||
Please send bug reports to cassowary@cs.washington.edu
|
||||
|
||||
|
||||
Bug reports, helpful testing, and/or code from:
|
||||
|
||||
Spencer Allain
|
||||
Anthony Beurivé
|
||||
Robert Chassell
|
||||
Alexandre 'Pollux' Duret-Lutz
|
||||
Michael Kaufmann
|
||||
Brian Grant
|
||||
Pengling He
|
||||
Tessa Lau
|
||||
John MacPhail
|
||||
Larry Melia
|
||||
Michael Noth
|
||||
Emmanuel Pietriga
|
||||
Will Portnoy
|
||||
Steve Wolfman
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Modified from gtk-config
|
||||
# --09/07/99 gjb
|
||||
|
||||
# gotten from LDADD in c++/Makefile.am
|
||||
cassowary_gtllibs="@GTL_LIB@"
|
||||
cassowary_libs="-L@prefix@/lib $cassowary_gtllibs"
|
||||
cassowary_cflags="@GUILE_INCLUDES@ @GTL_INCLUDES@"
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
exec_prefix_set=no
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: cassowary-config [OPTIONS]
|
||||
Options:
|
||||
[--prefix[=DIR]]
|
||||
[--exec-prefix[=DIR]]
|
||||
[--version]
|
||||
[--libs]
|
||||
[--gtllibs]
|
||||
[--cflags]
|
||||
EOF
|
||||
exit $1
|
||||
}
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage 1 1>&2
|
||||
fi
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) optarg= ;;
|
||||
esac
|
||||
|
||||
case $1 in
|
||||
--prefix=*)
|
||||
prefix=$optarg
|
||||
if test $exec_prefix_set = no ; then
|
||||
exec_prefix=$optarg
|
||||
fi
|
||||
;;
|
||||
--prefix)
|
||||
echo_prefix=yes
|
||||
;;
|
||||
--exec-prefix=*)
|
||||
exec_prefix=$optarg
|
||||
exec_prefix_set=yes
|
||||
;;
|
||||
--exec-prefix)
|
||||
echo_exec_prefix=yes
|
||||
;;
|
||||
--version)
|
||||
echo @CASSOWARY_VERSION@
|
||||
;;
|
||||
--cflags)
|
||||
echo_cflags=yes
|
||||
;;
|
||||
--libs)
|
||||
echo_libs=yes
|
||||
;;
|
||||
--gtllibs)
|
||||
echo_gtllibs=yes
|
||||
;;
|
||||
*)
|
||||
usage 1 1>&2
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test "$echo_prefix" = "yes"; then
|
||||
echo $prefix
|
||||
fi
|
||||
|
||||
if test "$echo_exec_prefix" = "yes"; then
|
||||
echo $exec_prefix
|
||||
fi
|
||||
|
||||
|
||||
if test "$echo_cflags" = "yes"; then
|
||||
if test @includedir@ != /usr/include ; then
|
||||
includes=-I@includedir@
|
||||
for i in $cassowary_cflags ; do
|
||||
if test $i = -I@includedir@ ; then
|
||||
includes=""
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo $includes $cassowary_cflags
|
||||
fi
|
||||
|
||||
if test "$echo_libs" = "yes"; then
|
||||
echo -L@libdir@ -lcassowary -lstdc++ $cassowary_libs
|
||||
fi
|
||||
|
||||
if test "$echo_gtllibs" = "yes"; then
|
||||
echo $cassowary_gtllibs
|
||||
fi
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
# Note that this is NOT a relocatable package
|
||||
%define ver @VERSION@
|
||||
%define rel 2
|
||||
%define prefix /usr
|
||||
|
||||
Name: cassowary-nofd
|
||||
Summary: A Linear Arithmetic Constraint Solving Library.
|
||||
Version: %ver
|
||||
Release: %rel
|
||||
# This source just has a different top-level directory name
|
||||
Source: http://www.cs.washington.edu/research/constraints/cassowary/cassowary-nofd-%ver.tar.gz
|
||||
Group: Development/Libraries
|
||||
BuildRoot: /tmp/cassowary-%ver-build
|
||||
Copyright: Copyright (C) 1998,1999 Greg J. Badros
|
||||
Packager: Greg J. Badros <gjb@cs.washington.edu>
|
||||
URL: http://www.cs.washington.edu/research/constraints/cassowary
|
||||
Requires: guile >= 1.3.2
|
||||
Provides: cassowary-constraint-solver
|
||||
|
||||
%description
|
||||
|
||||
Cassowary is an advanced incremental constraint solving toolkit that
|
||||
efficiently solves systems of linear equalities and inequalities.
|
||||
Constraints may be either requirements or preferences. Client code
|
||||
specifies the constraints to be maintained, and the solver updates the
|
||||
constrained variables to have values that satisfy the constraints.
|
||||
|
||||
This package lacks the finite domain subsolver. The cassowary RPM
|
||||
contains that solver as well, but also requires the GTL (Graph
|
||||
Template Library) package.
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Sep 7 1999 Greg J. Badros <gjb@cs.washington.edu)
|
||||
- Added cassowary-nofd package to remove GTL dependence, added provides
|
||||
virtual package "cassowary-constraint-solver" so that both this .spec
|
||||
and cassowary.spec can provide it
|
||||
|
||||
* Sat Sep 4 1999 Greg J. Badros <gjb@cs.washington.edu)
|
||||
- Use -fpermissive if it is available, fix --enable-warnings
|
||||
|
||||
* Wed Aug 25 1999 Greg J. Badros <gjb@cs.washington.edu>
|
||||
- Rework spec file.
|
||||
|
||||
* Wed Apr 14 1999 Greg J. Badros <gjb@cs.washington.edu>
|
||||
|
||||
- Initial release of this package.
|
||||
|
||||
%prep
|
||||
|
||||
%setup
|
||||
|
||||
%build
|
||||
ln -sf . ./c++/cassowary
|
||||
|
||||
%ifarch alpha
|
||||
./configure --host=alpha-linux --prefix=%prefix --enable-guile-build --enable-fsstd --enable-permissive
|
||||
%else
|
||||
./configure --prefix=%prefix --enable-guile-build --enable-fsstd --enable-permissive
|
||||
%endif
|
||||
|
||||
make
|
||||
|
||||
%install
|
||||
make prefix=$RPM_BUILD_ROOT%{prefix} install-strip
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
|
||||
%postun
|
||||
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
|
||||
%{prefix}/bin/*
|
||||
%{prefix}/lib/*
|
||||
%{prefix}/include/*
|
||||
|
||||
%doc ANNOUNCE AUTHORS COPYING IMPORTANT INSTALL LICENSE NEWS README THANKS
|
||||
%doc ChangeLog docs/cassowary-tr.pdf docs/cassowary-tr.ps.gz
|
||||
%doc guile/cassowary_scm-procedures.txt guile/cassowary_scm-variables.txt
|
||||
%doc guile/cassowary_scm.sgml
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
# Note that this is NOT a relocatable package
|
||||
%define ver @VERSION@
|
||||
%define rel 1
|
||||
%define prefix /usr
|
||||
|
||||
Name: cassowary
|
||||
Summary: A Linear Arithmetic Constraint Solving Library.
|
||||
Version: %ver
|
||||
Release: %rel
|
||||
Source: http://www.cs.washington.edu/research/constraints/cassowary/cassowary-%ver.tar.gz
|
||||
Group: Development/Libraries
|
||||
BuildRoot: /tmp/cassowary-%ver-build
|
||||
Copyright: Copyright (C) 1998,1999 Greg J. Badros
|
||||
Packager: Greg J. Badros <gjb@cs.washington.edu>
|
||||
URL: http://www.cs.washington.edu/research/constraints/cassowary
|
||||
Requires: guile >= 1.3.4
|
||||
Requires: GTL >= 0.3.1
|
||||
Provides: cassowary-constraint-solver
|
||||
|
||||
%description
|
||||
|
||||
Cassowary is an advanced incremental constraint solving toolkit that
|
||||
efficiently solves systems of linear equalities and inequalities.
|
||||
Constraints may be either requirements or preferences. Client code
|
||||
specifies the constraints to be maintained, and the solver updates the
|
||||
constrained variables to have values that satisfy the constraints.
|
||||
|
||||
%changelog
|
||||
* Tue Sep 7 1999 Greg J. Badros <gjb@cs.washington.edu)
|
||||
- added provides virtual package "cassowary-constraint-solver" so that
|
||||
both this .spec and cassowary.spec can provide it
|
||||
|
||||
* Sat Sep 4 1999 Greg J. Badros <gjb@cs.washington.edu)
|
||||
- Use -fpermissive if it is available, fix --enable-warnings
|
||||
|
||||
* Wed Aug 25 1999 Greg J. Badros <gjb@cs.washington.edu>
|
||||
- Rework spec file.
|
||||
|
||||
* Wed Apr 14 1999 Greg J. Badros <gjb@cs.washington.edu>
|
||||
|
||||
- Initial release of this package.
|
||||
|
||||
%prep
|
||||
|
||||
%setup
|
||||
|
||||
%build
|
||||
ln -sf . ./c++/cassowary
|
||||
|
||||
%ifarch alpha
|
||||
fake_root_for_install=$RPM_BUILD_ROOT ./configure --host=alpha-linux --prefix=%prefix --with-gtl=%prefix --enable-fd-solver --enable-fsstd --enable-permissive
|
||||
%else
|
||||
fake_root_for_install=$RPM_BUILD_ROOT ./configure --prefix=%prefix --with-gtl=%prefix --enable-fd-solver --enable-fsstd --enable-permissive
|
||||
%endif
|
||||
|
||||
make
|
||||
|
||||
%install
|
||||
make prefix=$RPM_BUILD_ROOT%{prefix} fake_root_for_install=$RPM_BUILD_ROOT install-strip
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
|
||||
%postun
|
||||
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
|
||||
%{prefix}/bin/*
|
||||
%{prefix}/lib/*
|
||||
%{prefix}/include/*
|
||||
|
||||
%doc ANNOUNCE AUTHORS COPYING IMPORTANT INSTALL LICENSE NEWS README THANKS
|
||||
%doc ChangeLog docs/cassowary-tr.pdf docs/cassowary-tr.ps.gz
|
||||
%doc guile/cassowary_scm-procedures.txt guile/cassowary_scm-variables.txt
|
||||
%doc guile/cassowary_scm.sgml
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// Cassowary.h
|
||||
|
||||
#ifndef Cassowary_H
|
||||
#define Cassowary_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifndef CL_PTR_HASH_DIVISOR
|
||||
#define CL_PTR_HASH_DIVISOR 4
|
||||
#endif
|
||||
|
||||
#include "ClConstraintHash.h"
|
||||
#include <climits>
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
typedef double Number;
|
||||
|
||||
typedef long FDNumber;
|
||||
|
||||
enum { FDN_NOTSET = LONG_MIN };
|
||||
|
||||
#define NEWVAR(x) do { cerr << "line " << __LINE__ << ": new " << x << endl; } while (0)
|
||||
#define DELVAR(x) do { cerr << "line " << __LINE__ << ": del " << x << endl; } while (0)
|
||||
|
||||
#endif // Cassowary_H
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// Cl.h
|
||||
// This is the top level include file for external clients
|
||||
|
||||
#ifndef CL_H
|
||||
#define CL_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifdef CL_NO_IO
|
||||
#undef CL_TRACE
|
||||
#undef CL_SOLVER_STATS
|
||||
#undef CL_DEBUG_FAILURES
|
||||
#undef CL_TRACE_VERBOSE
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "cassowary/ClVariable.h"
|
||||
#include "cassowary/ClSimplexSolver.h"
|
||||
#include "cassowary/ClLinearEquation.h"
|
||||
#include "cassowary/ClLinearInequality.h"
|
||||
#include "cassowary/ClErrors.h"
|
||||
#include "cassowary/ClEditConstraint.h"
|
||||
#include "cassowary/ClStayConstraint.h"
|
||||
#include "cassowary/ClReader.h"
|
||||
#include "cassowary/ClConstraint.h"
|
||||
#if defined(CL_HAVE_GTL) && defined(CL_BUILD_FD_SOLVER)
|
||||
#include "cassowary/ClFDBinaryOneWayConstraint.h"
|
||||
#include "cassowary/ClFDSolver.h"
|
||||
#endif
|
||||
|
||||
extern const char *szCassowaryVersion;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClAbstractVariable.h
|
||||
|
||||
#ifndef ClAbstractVariable_H
|
||||
#define ClAbstractVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cstdio> /* for sprintf */
|
||||
#include "Cassowary.h"
|
||||
#include "ClErrors.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "cl_auto_ptr.h"
|
||||
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
|
||||
class ClAbstractVariable {
|
||||
public:
|
||||
ClAbstractVariable(string Name = "") :
|
||||
_name(Name), _pv(0)
|
||||
{
|
||||
++iVariableNumber;
|
||||
#ifdef CL_FIND_LEAK
|
||||
++cAbstractVariables;
|
||||
#endif
|
||||
if (Name.length() == 0)
|
||||
{
|
||||
char sz[16];
|
||||
sprintf(sz,"v%ld",iVariableNumber);
|
||||
_name = string(sz);
|
||||
}
|
||||
}
|
||||
|
||||
ClAbstractVariable(long varnumber, char *prefix) :
|
||||
_pv(0)
|
||||
{
|
||||
cl_auto_ptr<char> pch (new char[16+strlen(prefix)]);
|
||||
iVariableNumber++;
|
||||
#ifdef CL_FIND_LEAK
|
||||
++cAbstractVariables;
|
||||
#endif
|
||||
sprintf(pch.get(),"%s%ld",prefix,varnumber);
|
||||
_name = string(pch.get());
|
||||
}
|
||||
|
||||
virtual ~ClAbstractVariable()
|
||||
#ifdef CL_FIND_LEAK
|
||||
{ --cAbstractVariables; }
|
||||
|
||||
static long cAbstractVariables;
|
||||
#else
|
||||
{ }
|
||||
#endif
|
||||
|
||||
// Return the Name of the variable
|
||||
string Name() const
|
||||
{ return _name; }
|
||||
|
||||
// Set the Name of the variable
|
||||
virtual void SetName(string const &Name)
|
||||
{ _name = Name; }
|
||||
|
||||
// Return true iff this variable is a ClFloatVariable
|
||||
virtual bool IsFloatVariable() const
|
||||
{ return false; }
|
||||
|
||||
// Return true iff this variable is a ClFDVariable
|
||||
virtual bool IsFDVariable() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this a dummy variable (used as a marker variable
|
||||
// for required equality constraints). Such variables aren't
|
||||
// allowed to enter the basis when pivoting.
|
||||
virtual bool IsDummy() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this a variable known outside the solver.
|
||||
// (We need to give such variables a Value after solving is complete.)
|
||||
virtual bool IsExternal() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if we can Pivot on this variable.
|
||||
virtual bool IsPivotable() const
|
||||
{ throw ExCLTooDifficultSpecial("Variable not usable inside SimplexSolver"); return false; }
|
||||
|
||||
// Return true if this is a restricted (or slack) variable. Such
|
||||
// variables are constrained to be non-negative and occur only
|
||||
// internally to the simplex solver.
|
||||
virtual bool IsRestricted() const
|
||||
{ throw ExCLTooDifficultSpecial("Variable not usable inside SimplexSolver"); return false; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
// Prints a semi-descriptive representation to the stream, using the
|
||||
// Name if there is one, and otherwise the hash number of this
|
||||
// object.
|
||||
// EXAMPLES
|
||||
// x[10.0] -- w/ Name
|
||||
// x[0.0,100] -- w/ Name, bounds but no Value yet
|
||||
// CV#345(10.0) -- w/o Name
|
||||
virtual ostream &PrintOn(ostream &xo) const = 0;
|
||||
|
||||
friend ostream& operator<<(ostream &xos, const ClAbstractVariable &clv)
|
||||
{ clv.PrintOn(xos); return xos; }
|
||||
|
||||
#endif // CL_NO_IO
|
||||
|
||||
friend bool operator<(const ClAbstractVariable &cl1, const ClAbstractVariable &cl2)
|
||||
{ return &cl1 < &cl2; }
|
||||
|
||||
friend bool operator==(const ClAbstractVariable &cl1, const ClAbstractVariable &cl2)
|
||||
{
|
||||
return &cl1 == &cl2;
|
||||
}
|
||||
|
||||
friend bool operator!=(const ClAbstractVariable &cl1, const ClAbstractVariable &cl2)
|
||||
{
|
||||
return !(cl1 == cl2);
|
||||
}
|
||||
|
||||
virtual Number Value() const { return 0; }
|
||||
virtual int IntValue() const { return 0; }
|
||||
|
||||
virtual void SetValue(Number)
|
||||
{ assert(false); }
|
||||
|
||||
virtual void ChangeValue(Number)
|
||||
{ assert(false); }
|
||||
|
||||
void SetPv(void *pv)
|
||||
{ _pv = pv; }
|
||||
|
||||
void *Pv() const
|
||||
{ return _pv; }
|
||||
|
||||
private:
|
||||
string _name;
|
||||
|
||||
static long iVariableNumber;
|
||||
|
||||
// C-style extension mechanism so I
|
||||
// don't have to wrap ScwmClVariables separately
|
||||
void *_pv;
|
||||
};
|
||||
|
||||
typedef ClAbstractVariable *PClAbstractVariable;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClConstraint.h
|
||||
|
||||
#ifndef ClConstraint_H
|
||||
#define ClConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClLinearExpression.h"
|
||||
#include "ClStrength.h"
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
class ClSimplexSolver;
|
||||
class ClFDSolver;
|
||||
class ClBlueSolver;
|
||||
|
||||
// enum setup so additive inverse flips the direction of the inequality
|
||||
enum ClCnRelation {cnEQ = 0, cnNEQ = 100, cnLEQ = 2, cnGEQ = -2, cnLT = 3, cnGT = -3 };
|
||||
|
||||
inline enum ClCnRelation
|
||||
ReverseInequality(enum ClCnRelation c)
|
||||
{
|
||||
if (c != cnNEQ)
|
||||
c = (enum ClCnRelation) (- int(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
inline string
|
||||
StrCnRelation(enum ClCnRelation rel) {
|
||||
switch (rel) {
|
||||
case cnEQ: return "=";
|
||||
case cnNEQ: return "=/=";
|
||||
case cnLEQ: return "<=";
|
||||
case cnGEQ: return ">=";
|
||||
case cnLT: return "<";
|
||||
case cnGT: return ">";
|
||||
default: assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ClConstraint {
|
||||
public:
|
||||
|
||||
ClConstraint(const ClStrength &strength = ClsRequired(), double weight = 1.0 ) :
|
||||
_strength(strength),
|
||||
_readOnlyVars(),
|
||||
_weight(weight),
|
||||
_pv(0),
|
||||
_times_added(0)
|
||||
{
|
||||
CtrTracer(__FUNCTION__,this);
|
||||
}
|
||||
|
||||
virtual ~ClConstraint()
|
||||
{
|
||||
DtrTracer(__FUNCTION__,this);
|
||||
}
|
||||
|
||||
// Return my linear Expression. (For linear equations, this
|
||||
// constraint represents Expression=0; for linear inequalities it
|
||||
// represents Expression>=0.)
|
||||
virtual ClLinearExpression Expression() const
|
||||
{ assert(false); }
|
||||
|
||||
// Returns true if this is an edit constraint
|
||||
virtual bool IsEditConstraint() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this is an inequality constraint and
|
||||
// false if it is an equality constraint. The default is
|
||||
// that it is not.
|
||||
virtual bool IsInequality() const
|
||||
{ return false; }
|
||||
|
||||
virtual bool IsStrictInequality() const
|
||||
{ return false; }
|
||||
|
||||
virtual bool IsRequired() const
|
||||
{ return _strength.IsRequired(); }
|
||||
|
||||
virtual bool isStayConstraint() const
|
||||
{ return false; }
|
||||
|
||||
virtual const ClStrength &strength() const
|
||||
{ return _strength; }
|
||||
|
||||
virtual double weight() const
|
||||
{ return _weight; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const = 0;
|
||||
|
||||
friend ostream& operator<<(ostream &xos, const ClConstraint &constraint)
|
||||
{ constraint.PrintOn(xos); return xos; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void SetPv(void *pv)
|
||||
{ _pv = pv; }
|
||||
|
||||
void *Pv() const
|
||||
{ return _pv; }
|
||||
|
||||
virtual bool FIsSatisfied() const { return false; }
|
||||
|
||||
virtual bool FIsInSolver() const { return _times_added != 0; }
|
||||
|
||||
virtual bool FIsOkayForSimplexSolver() const { return true; }
|
||||
|
||||
void ChangeStrength( const ClStrength &strength)
|
||||
{
|
||||
if (_times_added == 0) {
|
||||
setStrength(strength);
|
||||
} else {
|
||||
throw ExCLTooDifficult();
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeWeight( double weight )
|
||||
{
|
||||
if (_times_added == 0) {
|
||||
setWeight(weight);
|
||||
} else {
|
||||
throw ExCLTooDifficult();
|
||||
}
|
||||
}
|
||||
|
||||
bool FIsReadOnlyVar(ClVariable v) const {
|
||||
return !(_readOnlyVars.find(v) == _readOnlyVars.end());
|
||||
}
|
||||
|
||||
const ClVarSet &ReadOnlyVars() const {
|
||||
return _readOnlyVars;
|
||||
}
|
||||
|
||||
ClConstraint &AddROVars(const ClVarSet &setClv) {
|
||||
for ( ClVarSet::const_iterator it = setClv.begin();
|
||||
it != setClv.end(); ++it) {
|
||||
_readOnlyVars.insert(*it);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend class ClSimplexSolver;
|
||||
friend class ClFDSolver;
|
||||
friend class ClBlueSolver;
|
||||
private:
|
||||
|
||||
ClSymbolicWeight symbolicWeight() const {
|
||||
return _strength.symbolicWeight();
|
||||
}
|
||||
|
||||
void addedTo(const ClSimplexSolver &)
|
||||
{ ++_times_added; }
|
||||
|
||||
void removedFrom(const ClSimplexSolver &)
|
||||
{ --_times_added; }
|
||||
|
||||
void setStrength( const ClStrength &strength )
|
||||
{ _strength = strength; }
|
||||
|
||||
void setWeight( double weight )
|
||||
{ _weight = weight; }
|
||||
|
||||
/// instance variables
|
||||
ClStrength _strength;
|
||||
|
||||
ClVarSet _readOnlyVars;
|
||||
|
||||
double _weight;
|
||||
|
||||
void *_pv;
|
||||
|
||||
int _times_added;
|
||||
};
|
||||
|
||||
typedef ClConstraint* PClConstraint;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClHash.h
|
||||
|
||||
#ifndef CL_HASH_H__
|
||||
#define CL_HASH_H__
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#ifdef CL_USE_HASH_MAP_AND_SET
|
||||
|
||||
#include <hash_map>
|
||||
|
||||
class ClConstraint;
|
||||
|
||||
struct hash<const ClConstraint *> {
|
||||
size_t operator()(const ClConstraint * const p) const
|
||||
{ return size_t((unsigned long)p/CL_PTR_HASH_DIVISOR); }
|
||||
};
|
||||
|
||||
struct hash<ClConstraint *> {
|
||||
size_t operator()(ClConstraint * const p) const
|
||||
{ return size_t((unsigned long)p/CL_PTR_HASH_DIVISOR); }
|
||||
};
|
||||
|
||||
#endif // CL_USE_HASH_MAP_AND_SET
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClDummyVariable.h
|
||||
|
||||
#ifndef ClDummyVariable_H
|
||||
#define ClDummyVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClAbstractVariable.h"
|
||||
|
||||
class ClTableau;
|
||||
class ClSimplexSolver;
|
||||
|
||||
class ClDummyVariable : public ClAbstractVariable {
|
||||
|
||||
public:
|
||||
|
||||
#ifdef CL_FIND_LEAK
|
||||
~ClDummyVariable() { --cDummyVariables; };
|
||||
|
||||
static long cDummyVariables;
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class ClTableau;
|
||||
friend class ClSimplexSolver;
|
||||
|
||||
ClDummyVariable(string Name = "") :
|
||||
ClAbstractVariable(Name)
|
||||
{
|
||||
#ifdef CL_FIND_LEAK
|
||||
++cDummyVariables;
|
||||
#endif
|
||||
}
|
||||
|
||||
ClDummyVariable(long number, char *prefix) :
|
||||
ClAbstractVariable(number,prefix)
|
||||
{
|
||||
#ifdef CL_FIND_LEAK
|
||||
++cDummyVariables;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "[" << Name() << ":dummy]";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Return true if this a dummy variable (used as a marker variable
|
||||
// for required equality constraints). Such variables aren't
|
||||
// allowed to enter the basis when pivoting.
|
||||
virtual bool IsDummy() const
|
||||
{ return true; }
|
||||
|
||||
// Return true if this a variable known outside the solver.
|
||||
// (We need to give such variables a Value after solving is complete.)
|
||||
virtual bool IsExternal() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if we can Pivot on this variable.
|
||||
virtual bool IsPivotable() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this is a restricted (or slack) variable. Such
|
||||
// variables are constrained to be non-negative and occur only
|
||||
// internally to the simplex solver.
|
||||
virtual bool IsRestricted() const
|
||||
{ return true; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClEditConstraint.h
|
||||
|
||||
#ifndef ClEditConstraint_H
|
||||
#define ClEditConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClEditOrStayConstraint.h"
|
||||
|
||||
class ClEditConstraint : public ClEditOrStayConstraint {
|
||||
typedef ClEditOrStayConstraint super;
|
||||
public:
|
||||
|
||||
ClEditConstraint(const ClVariable var,
|
||||
const ClStrength &strength = ClsStrong(), double weight = 1.0 ) :
|
||||
ClEditOrStayConstraint(var,strength,weight)
|
||||
{ }
|
||||
|
||||
// Returns true if this is an edit constraint
|
||||
virtual bool IsEditConstraint() const
|
||||
{ return true; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{ super::PrintOn(xo); return xo << "= edit)"; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClEditOrStayConstraint.h
|
||||
|
||||
#ifndef ClEditOrStayConstraint_H
|
||||
#define ClEditOrStayConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "ClConstraint.h"
|
||||
#include "ClLinearExpression.h"
|
||||
|
||||
class ClVariable;
|
||||
|
||||
class ClEditOrStayConstraint : public ClConstraint {
|
||||
public:
|
||||
|
||||
ClEditOrStayConstraint(const ClVariable var,
|
||||
const ClStrength &strength = ClsRequired(), double weight = 1.0 ) :
|
||||
ClConstraint(strength,weight),
|
||||
_variable(var)
|
||||
{ }
|
||||
|
||||
const ClVariable variable() const
|
||||
{ return _variable; }
|
||||
|
||||
ClLinearExpression Expression() const
|
||||
{ return ClLinearExpression(_variable,-1,_variable.Value()); }
|
||||
|
||||
private:
|
||||
|
||||
void setVariable( const ClVariable v)
|
||||
{ _variable = v; }
|
||||
|
||||
/// instance variables
|
||||
ClVariable _variable;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClErrors.h
|
||||
|
||||
#ifndef ClErrors_H
|
||||
#define ClErrors_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClTypedefs.h"
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
using std::string;
|
||||
using std::exception;
|
||||
|
||||
class ExCLError : public exception {
|
||||
public:
|
||||
ExCLError() : _msg(0) { }
|
||||
virtual ~ExCLError() throw() {}
|
||||
virtual string description() const
|
||||
{ return "(ExCLError) An error has occured in CL"; }
|
||||
protected:
|
||||
char *_msg;
|
||||
};
|
||||
|
||||
class ExCLInternalError : public ExCLError {
|
||||
public:
|
||||
ExCLInternalError(const char *sz)
|
||||
{ _msg = strdup(sz); }
|
||||
virtual string description() const
|
||||
{
|
||||
if (_msg) return _msg;
|
||||
else return "(ExCLInternalError) An internal error has occurred";
|
||||
}
|
||||
};
|
||||
|
||||
class ExCLBadResolve : public ExCLError {
|
||||
public:
|
||||
ExCLBadResolve(const char *sz)
|
||||
{ _msg = strdup(sz); }
|
||||
virtual string description() const
|
||||
{
|
||||
if (_msg) return _msg;
|
||||
else return "(ExCLBadResolve) Number of resolve values did not match number of edit vars";
|
||||
}
|
||||
};
|
||||
|
||||
class ExCLEditMisuse : public ExCLError {
|
||||
public:
|
||||
ExCLEditMisuse(const char *sz)
|
||||
{ _msg = strdup(sz); }
|
||||
virtual string description() const
|
||||
{
|
||||
if (_msg) return _msg;
|
||||
return "(ExCLEditMisuse) Edit protocol usage violation";
|
||||
}
|
||||
};
|
||||
|
||||
class ExCLTooDifficult : public ExCLError {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLTooDifficult) The constraints are too difficult to solve"; }
|
||||
};
|
||||
|
||||
class ExCLTooDifficultSpecial : public ExCLTooDifficult {
|
||||
public:
|
||||
ExCLTooDifficultSpecial(const char *sz)
|
||||
{ _msg = strdup(sz); }
|
||||
virtual string description() const
|
||||
{
|
||||
if (_msg) return _msg;
|
||||
else return "(ExCLTooDifficultSpecial) Solver requirements are not satisfied";
|
||||
}
|
||||
};
|
||||
|
||||
class ExCLReadOnlyNotAllowed : public ExCLTooDifficult {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLReadOnlyNotAllowed) The read-only annotation is not permitted by the solver"; }
|
||||
};
|
||||
|
||||
class ExCLCycleNotAllowed : public ExCLTooDifficult {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLCycleNotAllowed) A cyclic constraint graph is not permitted by the solver"; }
|
||||
};
|
||||
|
||||
class ExCLStrictInequalityNotAllowed : public ExCLTooDifficult {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLStrictInequalityNotAllowed) The strict inequality is not permitted by the solver"; }
|
||||
};
|
||||
|
||||
class ExCLRequiredFailure : public ExCLError {
|
||||
public:
|
||||
virtual ~ExCLRequiredFailure() throw() {}
|
||||
virtual string description() const
|
||||
{ return "(ExCLRequiredFailure) A required constraint cannot be satisfied"; }
|
||||
};
|
||||
|
||||
class ExCLNotEnoughStays : public ExCLError {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLNotEnoughStays) There are not enough stays to give specific values to every variable"; }
|
||||
};
|
||||
|
||||
class ExCLNonlinearExpression : public ExCLError {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLNonlinearExpression) The resulting expression would be nonlinear"; }
|
||||
};
|
||||
|
||||
class ExCLConstraintNotFound : public ExCLError {
|
||||
public:
|
||||
virtual string description() const
|
||||
{ return "(ExCLConstraintNotFound) Tried to remove a constraint that was never added"; }
|
||||
};
|
||||
|
||||
class ExCLParseError : public ExCLError {
|
||||
public:
|
||||
virtual ~ExCLParseError() throw() {}
|
||||
virtual string description() const
|
||||
{ return "(ExCLParseError)"; }
|
||||
};
|
||||
|
||||
class ExCLParseErrorMisc : public ExCLParseError {
|
||||
public:
|
||||
ExCLParseErrorMisc(const string &s)
|
||||
: _msg("(ExCLParseError) ")
|
||||
{ _msg += s; }
|
||||
virtual ~ExCLParseErrorMisc() throw() {}
|
||||
virtual string description() const
|
||||
{ return _msg; }
|
||||
private:
|
||||
string _msg;
|
||||
};
|
||||
|
||||
class ExCLParseErrorBadIdentifier : public ExCLParseError {
|
||||
public:
|
||||
ExCLParseErrorBadIdentifier(const string &id)
|
||||
: _msg("(ExCLParseErrorBadIdentifier) Did not recognize identifier '")
|
||||
{
|
||||
_msg += id;
|
||||
_msg += "'";
|
||||
}
|
||||
virtual ~ExCLParseErrorBadIdentifier() throw() {}
|
||||
virtual string description() const
|
||||
{ return _msg; }
|
||||
private:
|
||||
string _msg;
|
||||
};
|
||||
|
||||
class ExCLRequiredFailureWithExplanation : public ExCLRequiredFailure
|
||||
{
|
||||
public:
|
||||
virtual ~ExCLRequiredFailureWithExplanation() throw() {}
|
||||
virtual string description() const
|
||||
{ return "(ExCLRequiredFailureWithExplanation) A required constraint cannot be satisfied"; }
|
||||
virtual void AddConstraint(const ClConstraint *cnExpl)
|
||||
{ _explanation.insert(cnExpl); }
|
||||
virtual const ClConstraintSet & explanation() const
|
||||
{ return _explanation; }
|
||||
protected:
|
||||
ClConstraintSet _explanation;
|
||||
};
|
||||
|
||||
#endif // ClErrors_H
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDBinaryOneWayConstraint.h
|
||||
|
||||
#ifndef ClFDBinaryOneWayConstraint_H
|
||||
#define ClFDBinaryOneWayConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClFDConstraint.h"
|
||||
|
||||
class ClLinearConstraint;
|
||||
|
||||
// Just a node in the class hierarchy for now
|
||||
class ClFDBinaryOneWayConstraint : public ClFDConstraint {
|
||||
private: typedef ClFDConstraint super;
|
||||
|
||||
public:
|
||||
|
||||
ClFDBinaryOneWayConstraint(ClVariable vRW, enum ClCnRelation rel, ClVariable vRO,
|
||||
double coefficient = 1.0, double constant = 0.0,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0)
|
||||
: ClFDConstraint(strength,weight), _vRW(vRW), _rel(rel), _vRO(vRO),
|
||||
_coefficient(coefficient), _constant(constant)
|
||||
{ }
|
||||
|
||||
ClFDBinaryOneWayConstraint(ClVariable vRW, enum ClCnRelation rel, double constant,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0)
|
||||
: ClFDConstraint(strength,weight), _vRW(vRW), _rel(rel), _vRO(clvNil),
|
||||
_coefficient(0), _constant(constant)
|
||||
{ }
|
||||
|
||||
ClFDBinaryOneWayConstraint(const ClConstraint &cn);
|
||||
|
||||
static void EnsurePreconditionsForCn(const ClConstraint &cn);
|
||||
|
||||
static bool FCanConvertCn(const ClConstraint &cn);
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "FDCn: " << _vRW << " " << StrCnRelation(_rel) << " ";
|
||||
if (_coefficient != 0) {
|
||||
if (_coefficient != 1) xo << _coefficient << "*";
|
||||
if (_vRO != clvNil) xo << _vRO;
|
||||
}
|
||||
if (_constant != 0) xo << " + " << _constant;
|
||||
return xo;
|
||||
}
|
||||
|
||||
friend ostream& operator<<(ostream &xos, const ClFDBinaryOneWayConstraint &constraint)
|
||||
{ return constraint.PrintOn(xos); }
|
||||
|
||||
#endif
|
||||
|
||||
ClVariable ClvRW() const
|
||||
{ return _vRW; }
|
||||
ClVariable ClvRO() const
|
||||
{ return _vRO; }
|
||||
enum ClCnRelation Relation() const
|
||||
{ return _rel; }
|
||||
double Coefficient() const
|
||||
{ return _coefficient; }
|
||||
double Constant() const
|
||||
{ return _constant; }
|
||||
|
||||
bool IsInequality() const
|
||||
{ return (_rel != cnEQ && _rel != cnNEQ); }
|
||||
|
||||
bool IsStrictInequality() const
|
||||
{ return (_rel == cnGT || _rel == cnLT); }
|
||||
|
||||
protected:
|
||||
ClVariable _vRW;
|
||||
enum ClCnRelation _rel;
|
||||
ClVariable _vRO;
|
||||
double _coefficient;
|
||||
double _constant;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDConnectorVariable.h
|
||||
|
||||
#ifndef ClFDConnectorVariable_H
|
||||
#define ClFDConnectorVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include "Cassowary.h"
|
||||
#include "ClVariable.h"
|
||||
#include "ClFDVariable.h"
|
||||
#include "ClLinearEquation.h"
|
||||
#include "ClSimplexSolver.h"
|
||||
|
||||
/* Creates a new variable in the FD region
|
||||
that sets clvFloat in solver (simplex region)
|
||||
when it changes */
|
||||
class ClFDConnectorVariable : public ClFDVariable {
|
||||
public:
|
||||
typedef ClFDVariable super;
|
||||
|
||||
ClFDConnectorVariable(string name, FDNumber Value, const list<FDNumber> &initial_domain,
|
||||
ClSimplexSolver &solver, ClVariable clvFloat) :
|
||||
ClFDVariable(name,Value,initial_domain),
|
||||
_solver(solver),
|
||||
_clvFloat(clvFloat),
|
||||
_pcnRequiredLink(new ClLinearEquation(clvFloat,Value))
|
||||
{ solver.AddConstraint(_pcnRequiredLink); }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
// Prints a semi-descriptive representation to the stream, using the
|
||||
// name if there is one, and otherwise the hash number of this
|
||||
// object.
|
||||
// EXAMPLE
|
||||
// [x:10.0] -- name = "x", Value = 10.0
|
||||
virtual ostream &PrintOn(ostream &xo) const;
|
||||
#endif
|
||||
|
||||
// permit overriding in subclasses in case something needs to be
|
||||
// done when the Value is changed by the solver
|
||||
// may be called when the Value hasn't actually changed -- just
|
||||
// means the solver is setting the external variable
|
||||
virtual void ChangeValue(FDNumber Value)
|
||||
{
|
||||
if (_value != Value) {
|
||||
_value = Value;
|
||||
cerr << "Updating " << _clvFloat << " now!" << endl;
|
||||
_solver.RemoveConstraint(_pcnRequiredLink);
|
||||
_pcnRequiredLink->ChangeConstant(_value);
|
||||
_solver.AddConstraint(_pcnRequiredLink);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// similar to SetValue -- see caveat above -- made private for now
|
||||
// since it's probably the wrong thing and is too easy to invoke
|
||||
FDNumber operator=(FDNumber Value)
|
||||
{ _value = Value; return Value; }
|
||||
|
||||
// Copy constructor left undefined since we want to
|
||||
// outlaw passing by Value! Will get a link error if you
|
||||
// try to use within ClFDConnectorVariable.c, compile-time error everywhere else
|
||||
ClFDConnectorVariable(const ClFDConnectorVariable &);
|
||||
|
||||
ClSimplexSolver &_solver;
|
||||
|
||||
ClVariable _clvFloat;
|
||||
|
||||
ClLinearEquation *_pcnRequiredLink;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDConstraint.h
|
||||
|
||||
#ifndef ClFDConstraint_H
|
||||
#define ClFDConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClConstraint.h"
|
||||
|
||||
|
||||
// Just a node in the class hierarchy for now
|
||||
class ClFDConstraint : public ClConstraint {
|
||||
private: typedef ClConstraint super;
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
ClFDConstraint(const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0)
|
||||
: ClConstraint(strength, weight) { }
|
||||
|
||||
virtual bool FIsOkayForSimplexSolver() const { return false; }
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClSolver.h
|
||||
|
||||
#ifndef ClFDSolver_H
|
||||
#define ClFDSolver_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClSolver.h"
|
||||
#include "ClVariable.h"
|
||||
#include "ClErrors.h"
|
||||
#include "ClTypedefs.h"
|
||||
#include "ClSymbolicWeight.h"
|
||||
#include <GTL/graph.h>
|
||||
#include <map>
|
||||
|
||||
using std::map;
|
||||
|
||||
class ClVariable;
|
||||
class ClFDBinaryOneWayConstraint;
|
||||
|
||||
// ClFDSolver is a concrete class
|
||||
// implementing a very restricted (for now --04/23/99 gjb)
|
||||
// finite-domain constraint solving algorithm
|
||||
class ClFDSolver: public ClSolver {
|
||||
public:
|
||||
ClFDSolver()
|
||||
: _setCns(), _mapClvToCns(), G(), nodeToVar(G)
|
||||
{ G.make_directed(); }
|
||||
|
||||
virtual ~ClFDSolver()
|
||||
{ }
|
||||
|
||||
virtual ClFDSolver &AddConstraint(ClConstraint *const pcn);
|
||||
|
||||
virtual ClFDSolver &RemoveConstraint(ClConstraint *const pcn);
|
||||
|
||||
virtual ClFDSolver &Solve();
|
||||
|
||||
virtual ClFDSolver &ShowSolve();
|
||||
|
||||
void ChangeClv(ClVariable clv, FDNumber n) {
|
||||
clv.ChangeValue(n);
|
||||
if (_pfnChangeClvCallback) {
|
||||
_pfnChangeClvCallback(&clv,this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
ostream &PrintOn(ostream &xo) const;
|
||||
|
||||
ostream &PrintInternalInfo(ostream &xo) const;
|
||||
|
||||
ostream &PrintOnVerbose(ostream &xo) const
|
||||
{ PrintOn(xo); PrintInternalInfo(xo); xo << endl; return xo; }
|
||||
|
||||
friend ostream &operator<<(ostream &xo, const ClFDSolver &solver);
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
virtual ClFDSolver &AddConstraintInternal(ClConstraint *const pcn);
|
||||
|
||||
virtual ClFDSolver &RemoveConstraintInternal(ClConstraint *const pcn);
|
||||
|
||||
/* Create node for v in G, if necessary,
|
||||
otherwise return the node we already created. */
|
||||
node GetVarNode(ClVariable v);
|
||||
|
||||
/* return the best (lowest) incremental error and the value
|
||||
at which that error occurs */
|
||||
pair<ClSymbolicWeight,FDNumber> ComputeBest(ClFDVariable *pcldv);
|
||||
|
||||
ClSymbolicWeight ErrorForClvAtValSubjectToCn(ClFDVariable *pcldv,
|
||||
FDNumber value,const ClConstraint &cn);
|
||||
|
||||
/* Turn all FDVariable FIsSet() flags to false */
|
||||
void ResetSetFlagsOnVariables();
|
||||
|
||||
/* all the constraints in the solver */
|
||||
ClConstraintSet _setCns;
|
||||
|
||||
/* _mapClvToCns maps variable to the constraints in which
|
||||
it is rw (it omits where it is ro) */
|
||||
ClVarToConstraintSetMap _mapClvToCns;
|
||||
|
||||
/* track what edges correspond to which constraints
|
||||
so we can update the constraint graph when
|
||||
removing a constraint */
|
||||
map<ClConstraint *, edge> _mapCnToEdge;
|
||||
|
||||
/* track what nodes correspond to which variables */
|
||||
map<ClVariable, node> _mapVarToNode;
|
||||
|
||||
/* directed graph that mirrors the structure of
|
||||
the relations of the added constraints */
|
||||
graph G;
|
||||
|
||||
node_map<ClVariable> nodeToVar;
|
||||
};
|
||||
|
||||
#define FDN_EOL LONG_MIN
|
||||
|
||||
void ListPushOnto(list<FDNumber> *pl, ...);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFDVariable.h
|
||||
|
||||
#ifndef ClFDVariable_H
|
||||
#define ClFDVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include "Cassowary.h"
|
||||
#include "ClAbstractVariable.h"
|
||||
|
||||
using std::map;
|
||||
using std::list;
|
||||
using std::string;
|
||||
|
||||
class ClFDVariable : public ClAbstractVariable {
|
||||
public:
|
||||
typedef ClAbstractVariable super;
|
||||
|
||||
#if 0 /* GJB:FIXME:: */
|
||||
ClFDVariable(string name, FDNumber Value) :
|
||||
ClAbstractVariable(name),
|
||||
_value(Value),
|
||||
_fSet(true),
|
||||
_desired_value(Value),
|
||||
_plfdnInitialDomain(0)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
ClFDVariable(string name, FDNumber Value, const list<FDNumber> &initial_domain) :
|
||||
ClAbstractVariable(name),
|
||||
_value(Value),
|
||||
_fSet(true),
|
||||
_desired_value(Value),
|
||||
_plfdnInitialDomain(new list<FDNumber>())
|
||||
{
|
||||
*_plfdnInitialDomain = initial_domain;
|
||||
}
|
||||
|
||||
virtual bool IsFDVariable() const
|
||||
{ return true; }
|
||||
|
||||
// Return true if this a variable known outside the solver.
|
||||
// (We need to give such variables a Value after solving is complete.)
|
||||
virtual bool IsExternal() const
|
||||
{ return true; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
// Prints a semi-descriptive representation to the stream, using the
|
||||
// name if there is one, and otherwise the hash number of this
|
||||
// object.
|
||||
// EXAMPLE
|
||||
// [x:10.0] -- name = "x", Value = 10.0
|
||||
virtual ostream &PrintOn(ostream &xo) const;
|
||||
#endif
|
||||
|
||||
// Return the current Value I hold.
|
||||
Number Value() const
|
||||
{ return _value; }
|
||||
|
||||
// Round the Value to an integer and return it
|
||||
int IntValue() const
|
||||
{ return _value; }
|
||||
|
||||
// change the Value held -- should *not* use this if the variable is
|
||||
// in a solver -- instead use AddEditVar() and SuggestValue() interface
|
||||
void SetValue(FDNumber Value)
|
||||
{ _value = Value; }
|
||||
|
||||
// permit overriding in subclasses in case something needs to be
|
||||
// done when the Value is changed by the solver
|
||||
// may be called when the Value hasn't actually changed -- just
|
||||
// means the solver is setting the external variable
|
||||
virtual void ChangeValue(FDNumber Value)
|
||||
{ _value = Value; }
|
||||
|
||||
virtual bool FIsSet()
|
||||
{ return _fSet; }
|
||||
|
||||
virtual void SetFIsSet(bool f)
|
||||
{ _fSet = f; }
|
||||
|
||||
virtual FDNumber DesiredValue() const
|
||||
{ return _desired_value; }
|
||||
|
||||
virtual const list<FDNumber> *PlfdnDomain() const
|
||||
{ return _plfdnInitialDomain; }
|
||||
|
||||
protected:
|
||||
|
||||
// similar to SetValue -- see caveat above -- made private for now
|
||||
// since it's probably the wrong thing and is too easy to invoke
|
||||
FDNumber operator=(FDNumber Value)
|
||||
{ _value = Value; return Value; }
|
||||
|
||||
// Copy constructor left undefined since we want to
|
||||
// outlaw passing by Value! Will get a link error if you
|
||||
// try to use within ClFDVariable.c, compile-time error everywhere else
|
||||
ClFDVariable(const ClFDVariable &);
|
||||
|
||||
FDNumber _value;
|
||||
|
||||
// has the _value been set? Used during solves.
|
||||
bool _fSet;
|
||||
|
||||
FDNumber _desired_value;
|
||||
|
||||
list<FDNumber> *_plfdnInitialDomain;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClFloatVariable.h
|
||||
|
||||
#ifndef ClFloatVariable_H
|
||||
#define ClFloatVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Cassowary.h"
|
||||
#include "ClAbstractVariable.h"
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
class ClFloatVariable : public ClAbstractVariable {
|
||||
public:
|
||||
typedef ClAbstractVariable super;
|
||||
|
||||
ClFloatVariable(string name, Number Value = 0.0) :
|
||||
ClAbstractVariable(name),
|
||||
_value(Value)
|
||||
{ }
|
||||
|
||||
ClFloatVariable(Number Value = 0.0) :
|
||||
ClAbstractVariable(""),
|
||||
_value(Value)
|
||||
{ }
|
||||
|
||||
ClFloatVariable(long number, char *prefix, Number Value = 0.0) :
|
||||
ClAbstractVariable(number,prefix),
|
||||
_value(Value)
|
||||
{ }
|
||||
|
||||
virtual bool IsFloatVariable() const
|
||||
{ return true; }
|
||||
|
||||
// Return true if this a dummy variable (used as a marker variable
|
||||
// for required equality constraints). Such variables aren't
|
||||
// allowed to enter the basis when pivoting.
|
||||
virtual bool IsDummy() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this a variable known outside the solver.
|
||||
// (We need to give such variables a Value after solving is complete.)
|
||||
virtual bool IsExternal() const
|
||||
{ return true; }
|
||||
|
||||
// Return true if we can Pivot on this variable.
|
||||
virtual bool IsPivotable() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this is a restricted (or slack) variable. Such
|
||||
// variables are constrained to be non-negative and occur only
|
||||
// internally to the simplex solver.
|
||||
virtual bool IsRestricted() const
|
||||
{ return false; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
// Prints a semi-descriptive representation to the stream, using the
|
||||
// name if there is one, and otherwise the hash number of this
|
||||
// object.
|
||||
// EXAMPLE
|
||||
// [x:10.0] -- name = "x", Value = 10.0
|
||||
virtual ostream &PrintOn(ostream &xo) const;
|
||||
#endif
|
||||
|
||||
// Return the current Value I hold.
|
||||
Number Value() const
|
||||
{ return _value; }
|
||||
|
||||
// Round the Value to an integer and return it
|
||||
int IntValue() const
|
||||
{ return int(_value + 0.5); }
|
||||
|
||||
// change the Value held -- should *not* use this if the variable is
|
||||
// in a solver -- instead use AddEditVar() and SuggestValue() interface
|
||||
void SetValue(Number Value)
|
||||
{ _value = Value; }
|
||||
|
||||
// permit overriding in subclasses in case something needs to be
|
||||
// done when the Value is changed by the solver
|
||||
// may be called when the Value hasn't actually changed -- just
|
||||
// means the solver is setting the external variable
|
||||
virtual void ChangeValue(Number Value)
|
||||
{ _value = Value; }
|
||||
|
||||
private:
|
||||
|
||||
// similar to SetValue -- see caveat above -- made private for now
|
||||
// since it's probably the wrong thing and is too easy to invoke
|
||||
Number operator=(Number Value)
|
||||
{ _value = Value; return Value; }
|
||||
|
||||
// Copy constructor left undefined since we want to
|
||||
// outlaw passing by Value! Will get a link error if you
|
||||
// try to use within ClFloatVariable.c, compile-time error everywhere else
|
||||
ClFloatVariable(const ClFloatVariable &);
|
||||
|
||||
Number _value;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClLinearConstraint.h
|
||||
|
||||
#ifndef ClLinearConstraint_H
|
||||
#define ClLinearConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClConstraint.h"
|
||||
#include "ClLinearExpression.h"
|
||||
|
||||
|
||||
// Add the ClLinearExpression member variable needed for both
|
||||
// ClLinearEquation and ClLinearInequality
|
||||
class ClLinearConstraint : public ClConstraint {
|
||||
private: typedef ClConstraint super;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
ClLinearConstraint(const ClLinearExpression &cle,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClConstraint(strength, weight),
|
||||
_expression(cle)
|
||||
{ }
|
||||
|
||||
virtual ~ClLinearConstraint() {}
|
||||
|
||||
// Return my linear Expression. (For linear equations, this
|
||||
// constraint represents Expression=0; for linear inequalities it
|
||||
// represents Expression>=0.)
|
||||
ClLinearExpression Expression() const
|
||||
{ return _expression; }
|
||||
|
||||
// do not do this if *this is inside a solver
|
||||
void ChangeConstant(Number constant)
|
||||
{ _expression.Set_constant(constant); }
|
||||
|
||||
protected:
|
||||
|
||||
ClLinearExpression _expression;
|
||||
|
||||
virtual void setExpression( const ClLinearExpression &expr)
|
||||
{ _expression = expr; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClLinearEquation.h
|
||||
|
||||
#ifndef ClLinearEquation_H
|
||||
#define ClLinearEquation_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClLinearConstraint.h"
|
||||
#include "ClLinearExpression.h"
|
||||
|
||||
class ClStrength;
|
||||
class ClVariable;
|
||||
|
||||
class ClLinearEquation : public ClLinearConstraint {
|
||||
private: typedef ClLinearConstraint super;
|
||||
|
||||
public:
|
||||
//// Constructors
|
||||
|
||||
// ClLinearEquation(expr,...) is expr == 0
|
||||
ClLinearEquation(const ClLinearExpression &cle,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint(cle,strength, weight)
|
||||
{ }
|
||||
|
||||
// ClLinearEquation(var,expr,...) is var == expr
|
||||
ClLinearEquation(ClVariable clv,
|
||||
const ClLinearExpression &cle,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint(cle,strength,weight)
|
||||
{ _expression.AddVariable(clv,-1.0); }
|
||||
|
||||
// ClLinearEquation(expr,var,...) is var == expr
|
||||
ClLinearEquation(const ClLinearExpression &cle,
|
||||
ClVariable clv,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint(cle,strength,weight)
|
||||
{ _expression.AddVariable(clv,-1.0); }
|
||||
|
||||
// ClLinearEquation(expr,expr,...) is expr == expr
|
||||
ClLinearEquation(const ClLinearExpression &cle1,
|
||||
const ClLinearExpression &cle2,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint(cle1,strength,weight)
|
||||
{ _expression.AddExpression(cle2,-1.0); }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{ super::PrintOn(xo); xo << " = 0 )"; return xo; }
|
||||
#endif
|
||||
|
||||
virtual bool FIsSatisfied() const
|
||||
{ return (_expression.Evaluate() == 0); }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClLinearExpression.h
|
||||
|
||||
#ifndef ClLinearExpression_H
|
||||
#define ClLinearExpression_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "debug.h"
|
||||
#include "ClVariable.h"
|
||||
#include "ClLinearExpression_fwd.h"
|
||||
|
||||
class ClSimplexSolver;
|
||||
class ClTableau;
|
||||
class ClSymbolicWeight;
|
||||
|
||||
ClLinearExpression &cleNil();
|
||||
|
||||
template <class T>
|
||||
class ClGenericLinearExpression {
|
||||
public:
|
||||
typedef std::map<ClVariable,T> ClVarToCoeffMap;
|
||||
|
||||
// convert Number-s into ClLinearExpression-s
|
||||
ClGenericLinearExpression(T num = 0.0);
|
||||
|
||||
// Convert from ClVariable to a ClLinearExpression
|
||||
// this replaces ClVariable::asLinearExpression
|
||||
ClGenericLinearExpression(ClVariable clv, T value = 1.0, T constant = 0.0);
|
||||
|
||||
// copy ctr
|
||||
ClGenericLinearExpression(const ClGenericLinearExpression<T> &expr) :
|
||||
_constant(expr._constant),
|
||||
_terms(expr._terms)
|
||||
{ }
|
||||
|
||||
virtual ~ClGenericLinearExpression();
|
||||
|
||||
// Return a new linear expression formed by multiplying self by x.
|
||||
// (Note that this result must be linear.)
|
||||
ClGenericLinearExpression<T> Times(Number x) const;
|
||||
|
||||
// Return a new linear expression formed by multiplying self by x.
|
||||
// (Note that this result must be linear.)
|
||||
ClGenericLinearExpression<T> Times(const ClGenericLinearExpression<T> &expr) const;
|
||||
|
||||
// Return a new linear expression formed by adding x to self.
|
||||
ClGenericLinearExpression<T> Plus(const ClGenericLinearExpression<T> &expr) const;
|
||||
|
||||
// Return a new linear expression formed by subtracting x from self.
|
||||
ClGenericLinearExpression<T> Minus(const ClGenericLinearExpression<T> &expr) const;
|
||||
|
||||
// Return a new linear expression formed by dividing self by x.
|
||||
// (Note that this result must be linear.)
|
||||
ClGenericLinearExpression<T> Divide(Number x) const;
|
||||
|
||||
|
||||
|
||||
// Return a new linear expression formed by multiplying self by x.
|
||||
// (Note that this result must be linear.)
|
||||
ClGenericLinearExpression<T> *P_times(Number x) const
|
||||
{ return new ClGenericLinearExpression<T>(Times(x)); }
|
||||
|
||||
// Return a new linear expression formed by adding x to self.
|
||||
ClGenericLinearExpression<T> *P_plus(const ClGenericLinearExpression<T> &expr) const
|
||||
{ return new ClGenericLinearExpression<T>(Plus(expr)); }
|
||||
|
||||
// Return a new linear expression formed by subtracting x from self.
|
||||
ClGenericLinearExpression<T> *P_minus(const ClGenericLinearExpression<T> &expr) const
|
||||
{ return new ClGenericLinearExpression<T>(Minus(expr)); }
|
||||
|
||||
// Return a new linear expression formed by dividing self by x.
|
||||
// (Note that this result must be linear.)
|
||||
ClGenericLinearExpression<T> *P_divide(Number x) const
|
||||
{ return new ClGenericLinearExpression<T>(Divide(x)); }
|
||||
|
||||
// Return a new linear expression formed by dividing self by x.
|
||||
// (Note that this result must be linear.)
|
||||
ClGenericLinearExpression<T> Divide(const ClGenericLinearExpression<T> &expr) const;
|
||||
|
||||
// Return a new linear expression (aNumber/this). Since the result
|
||||
// must be linear, this is permissible only if 'this' is a constant.
|
||||
ClGenericLinearExpression<T> DivFrom(const ClGenericLinearExpression<T> &expr) const;
|
||||
|
||||
// Return a new linear expression (aNumber-this).
|
||||
ClGenericLinearExpression<T> SubtractFrom(const ClGenericLinearExpression<T> &expr) const
|
||||
{ return expr.Minus(*this); }
|
||||
|
||||
// Add n*expr to this expression from another expression expr.
|
||||
ClGenericLinearExpression<T> &AddExpression(const ClGenericLinearExpression<T> &expr,
|
||||
Number n = 1.0);
|
||||
|
||||
// Add n*expr to this expression from another expression expr.
|
||||
// Notify the solver if a variable is added or deleted from this
|
||||
// expression.
|
||||
ClGenericLinearExpression<T> &AddExpression(const ClGenericLinearExpression<T> &expr, Number n,
|
||||
ClVariable subject,
|
||||
ClTableau &solver);
|
||||
|
||||
// Add a term c*v to this expression. If the expression already
|
||||
// contains a term involving v, Add c to the existing coefficient.
|
||||
// If the new coefficient is approximately 0, delete v.
|
||||
ClGenericLinearExpression<T> &AddVariable(ClVariable v, T c = 1.0);
|
||||
|
||||
// Add a term c*v to this expression. If the expression already
|
||||
// contains a term involving v, Add c to the existing coefficient.
|
||||
// If the new coefficient is approximately 0, delete v.
|
||||
ClGenericLinearExpression<T> &setVariable(ClVariable v, T c)
|
||||
{assert(c != 0.0); _terms[v] = c; return *this; }
|
||||
|
||||
// Add a term c*v to this expression. If the expression already
|
||||
// contains a term involving v, Add c to the existing coefficient.
|
||||
// If the new coefficient is approximately 0, delete v. Notify the
|
||||
// solver if v appears or disappears from this expression.
|
||||
ClGenericLinearExpression<T> &AddVariable(ClVariable v, T c,
|
||||
ClVariable subject,
|
||||
ClTableau &solver);
|
||||
|
||||
// Return a pivotable variable in this expression. (It is an error
|
||||
// if this expression is constant -- signal ExCLInternalError in
|
||||
// that case). Return NULL if no pivotable variables
|
||||
ClVariable AnyPivotableVariable() const;
|
||||
|
||||
// Replace var with a symbolic expression expr that is equal to it.
|
||||
// If a variable has been added to this expression that wasn't there
|
||||
// before, or if a variable has been dropped from this expression
|
||||
// because it now has a coefficient of 0, inform the solver.
|
||||
// PRECONDITIONS:
|
||||
// var occurs with a non-Zero coefficient in this expression.
|
||||
void SubstituteOut(ClVariable v,
|
||||
const ClGenericLinearExpression<T> &expr,
|
||||
ClVariable subject,
|
||||
ClTableau &solver);
|
||||
|
||||
// This linear expression currently represents the equation
|
||||
// oldSubject=self. Destructively modify it so that it represents
|
||||
// the equation NewSubject=self.
|
||||
//
|
||||
// Precondition: NewSubject currently has a nonzero coefficient in
|
||||
// this expression.
|
||||
//
|
||||
// NOTES
|
||||
// Suppose this expression is c + a*NewSubject + a1*v1 + ... + an*vn.
|
||||
//
|
||||
// Then the current equation is
|
||||
// oldSubject = c + a*NewSubject + a1*v1 + ... + an*vn.
|
||||
// The new equation will be
|
||||
// NewSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn.
|
||||
// Note that the term involving NewSubject has been dropped.
|
||||
void ChangeSubject(ClVariable old_subject,
|
||||
ClVariable new_subject);
|
||||
|
||||
// This linear expression currently represents the equation self=0. Destructively modify it so
|
||||
// that subject=self represents an equivalent equation.
|
||||
//
|
||||
// Precondition: subject must be one of the variables in this expression.
|
||||
// NOTES
|
||||
// Suppose this expression is
|
||||
// c + a*subject + a1*v1 + ... + an*vn
|
||||
// representing
|
||||
// c + a*subject + a1*v1 + ... + an*vn = 0
|
||||
// The modified expression will be
|
||||
// subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
|
||||
// representing
|
||||
// subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
|
||||
//
|
||||
// Note that the term involving subject has been dropped.
|
||||
// Returns the reciprocal, so ChangeSubject can use it, too
|
||||
T NewSubject(ClVariable subject);
|
||||
|
||||
// Return the value of the linear expression
|
||||
// given the current assignments of values to contained variables
|
||||
T Evaluate() const;
|
||||
|
||||
// Return the coefficient corresponding to variable var, i.e.,
|
||||
// the 'ci' corresponding to the 'vi' that var is:
|
||||
// v1*c1 + v2*c2 + .. + vn*cn + c
|
||||
T CoefficientFor(ClVariable var) const
|
||||
{
|
||||
typename ClVarToCoeffMap::const_iterator it = _terms.find(var);
|
||||
if (it != _terms.end())
|
||||
return (*it).second;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
T Constant() const
|
||||
{ return _constant; }
|
||||
|
||||
void Set_constant(T c)
|
||||
{ _constant = c; }
|
||||
|
||||
const ClVarToCoeffMap &Terms() const
|
||||
{ return _terms; }
|
||||
|
||||
ClVarToCoeffMap &Terms()
|
||||
{ return _terms; }
|
||||
|
||||
void IncrementConstant(T c)
|
||||
{ _constant += c; }
|
||||
|
||||
bool IsConstant() const
|
||||
{ return _terms.size() == 0; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const;
|
||||
|
||||
friend ostream &operator<<(ostream &xo,const ClGenericLinearExpression<T> &cle)
|
||||
{ return cle.PrintOn(xo); }
|
||||
#endif
|
||||
|
||||
friend ClGenericLinearExpression<T> operator+(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Plus(e2); }
|
||||
|
||||
friend ClGenericLinearExpression<T> operator-(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Minus(e2); }
|
||||
|
||||
friend ClGenericLinearExpression<T> operator*(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Times(e2); }
|
||||
|
||||
|
||||
friend ClGenericLinearExpression<T> operator/(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Divide(e2); }
|
||||
|
||||
// FIXGJB -- this may be wrong -- should test underlying expression for equality
|
||||
friend bool operator==(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return &e1 == &e2; }
|
||||
|
||||
/// Named versions of the operator functions for ease of
|
||||
/// wrapping, or expressing using prefix notation
|
||||
|
||||
friend ClGenericLinearExpression<T> Plus(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Plus(e2); }
|
||||
|
||||
friend ClGenericLinearExpression<T> Minus(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Minus(e2); }
|
||||
|
||||
friend ClGenericLinearExpression<T> Times(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return e1.Times(e2); }
|
||||
|
||||
|
||||
friend ClGenericLinearExpression<T> *Divide(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return new ClGenericLinearExpression<T>(e1.Divide(e2)); }
|
||||
|
||||
friend ClGenericLinearExpression<T> *p_Plus(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return new ClGenericLinearExpression<T>(e1.Plus(e2)); }
|
||||
|
||||
friend ClGenericLinearExpression<T> *p_Minus(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return new ClGenericLinearExpression<T>(e1.Minus(e2)); }
|
||||
|
||||
friend ClGenericLinearExpression<T> *p_Times(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return new ClGenericLinearExpression<T>(e1.Times(e2)); }
|
||||
|
||||
friend ClGenericLinearExpression<T> *p_Divide(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return new ClGenericLinearExpression<T>(e1.Divide(e2)); }
|
||||
|
||||
|
||||
// FIXGJB -- this may be wrong -- should test underlying expression for equality
|
||||
friend bool FEquals(const ClGenericLinearExpression<T> &e1,
|
||||
const ClGenericLinearExpression<T> &e2)
|
||||
{ return &e1 == &e2; }
|
||||
|
||||
ClGenericLinearExpression<T> &MultiplyMe(T x);
|
||||
|
||||
private:
|
||||
|
||||
T _constant;
|
||||
ClVarToCoeffMap _terms;
|
||||
|
||||
};
|
||||
|
||||
typedef ClGenericLinearExpression<Number>::ClVarToCoeffMap ClVarToNumberMap;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClLinearExpression.h
|
||||
|
||||
#ifndef ClLinearExpression_fwd_H
|
||||
#define ClLinearExpression_fwd_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
|
||||
template <class T> class ClGenericLinearExpression;
|
||||
typedef ClGenericLinearExpression<Number> ClLinearExpression;
|
||||
typedef ClLinearExpression* PClLinearExpression;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClLinearInequality.h
|
||||
|
||||
#ifndef ClLinearInequality_H
|
||||
#define ClLinearInequality_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "ClConstraint.h"
|
||||
#include "ClLinearConstraint.h"
|
||||
|
||||
class ClVariable;
|
||||
|
||||
class ClLinearInequality : public ClLinearConstraint {
|
||||
private: typedef ClLinearConstraint super;
|
||||
|
||||
public:
|
||||
//// Constructors
|
||||
// ClLinearInequality(expr,...) is expr >= 0
|
||||
ClLinearInequality(const ClLinearExpression &cle,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint(cle,strength, weight),
|
||||
_fStrictInequality(false)
|
||||
{ }
|
||||
|
||||
// ClLinearInequality(var,OP,expr) is var >= expr
|
||||
ClLinearInequality(const ClVariable clv,
|
||||
enum ClCnRelation op,
|
||||
const ClLinearExpression &cle,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint( cle, strength, weight),
|
||||
_fStrictInequality(false)
|
||||
{
|
||||
if (op == cnGEQ || op == cnGT)
|
||||
{
|
||||
_expression.MultiplyMe(-1.0);
|
||||
_expression.AddVariable(clv,1.0);
|
||||
}
|
||||
else if (op == cnLEQ || op == cnGEQ)
|
||||
{
|
||||
_expression.AddVariable(clv,-1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ExCLEditMisuse("Cannot use that operator for ClLinearInequality objects");
|
||||
}
|
||||
if (op == cnLT || op == cnGT) {
|
||||
_fStrictInequality = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIXGJB_AMBIGUOUS
|
||||
// ClLinearInequality(expr,OP,var) is var ?<>? expr
|
||||
ClLinearInequality(const ClLinearExpression &cle,
|
||||
enum ClCnRelation op,
|
||||
const ClVariable clv,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint( cle, strength, weight),
|
||||
_fStrictInequality(false)
|
||||
{
|
||||
if (op == cnLEQ || op == cnLT)
|
||||
{
|
||||
_expression.MultiplyMe(-1.0);
|
||||
_expression.AddVariable(clv,1.0);
|
||||
}
|
||||
else if (op == cnGEQ || op == cnGT)
|
||||
{
|
||||
_expression.AddVariable(clv,-1.0);
|
||||
}
|
||||
if (op == cnLT || op == cnGT) {
|
||||
_fStrictInequality = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ClLinearInequality(expr,OP,expr) is expr >= expr
|
||||
ClLinearInequality(const ClLinearExpression &cle1,
|
||||
enum ClCnRelation op,
|
||||
const ClLinearExpression &cle2,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint( cle2, strength, weight),
|
||||
_fStrictInequality(false)
|
||||
{
|
||||
if (op == cnGEQ || op == cnGT)
|
||||
{
|
||||
_expression.MultiplyMe(-1.0);
|
||||
_expression.AddExpression(cle1);
|
||||
}
|
||||
else if (op == cnLEQ || op == cnLT)
|
||||
{
|
||||
_expression.AddExpression(cle1,-1.0);
|
||||
}
|
||||
if (op == cnLT || op == cnGT) {
|
||||
_fStrictInequality = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIXGJB_AMBIGUOUS
|
||||
// ClLinearInequality(var,OP,var) is var ?<>? var
|
||||
ClLinearInequality(const ClVariable clv1,
|
||||
enum ClCnRelation op,
|
||||
const ClVariable clv2,
|
||||
const ClStrength &strength = ClsRequired(),
|
||||
double weight = 1.0) :
|
||||
ClLinearConstraint( clv2, strength, weight),
|
||||
_fStrictInequality(false)
|
||||
{
|
||||
if (op == cnGEQ || op == cnGT)
|
||||
{
|
||||
_expression.MultiplyMe(-1.0);
|
||||
_expression.AddVariable(clv1,1.0);
|
||||
}
|
||||
else if (op == cnLEQ || op == cnLT)
|
||||
{
|
||||
_expression.AddVariable(clv1,-1.0);
|
||||
}
|
||||
if (op == cnLT || op == cnGT) {
|
||||
_fStrictInequality = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Return true if this is an inequality constraint and
|
||||
// false if it is an equality constraint. The default is
|
||||
// that it is not.
|
||||
virtual bool IsInequality() const
|
||||
{ return true; }
|
||||
|
||||
virtual bool IsStrictInequality() const
|
||||
{ return _fStrictInequality; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{ super::PrintOn(xo); xo << " >= 0 )"; return xo; }
|
||||
#endif
|
||||
|
||||
virtual bool FIsSatisfied() const
|
||||
{
|
||||
Number v = _expression.Evaluate();
|
||||
if (_fStrictInequality)
|
||||
return (v > 0);
|
||||
else
|
||||
return (v >= 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool _fStrictInequality;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClObjectiveVariable.h
|
||||
|
||||
#ifndef ClObjectiveVariable_H
|
||||
#define ClObjectiveVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClAbstractVariable.h"
|
||||
|
||||
class ClTableau;
|
||||
class ClSimplexSolver;
|
||||
|
||||
class ClObjectiveVariable : public ClAbstractVariable {
|
||||
protected:
|
||||
friend class ClTableau;
|
||||
friend class ClSimplexSolver;
|
||||
|
||||
ClObjectiveVariable(string name = "") :
|
||||
ClAbstractVariable(name)
|
||||
{ }
|
||||
|
||||
ClObjectiveVariable(long number, char *prefix) :
|
||||
ClAbstractVariable(number,prefix)
|
||||
{ }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "[" << Name() << ":obj]";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We don't need to give such variables a Value after solving is complete.
|
||||
virtual bool IsExternal() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if we can Pivot on this variable.
|
||||
virtual bool IsPivotable() const
|
||||
{ return false; }
|
||||
|
||||
// Return true if this is a restricted (or slack) variable. Such
|
||||
// variables are constrained to be non-negative and occur only
|
||||
// internally to the simplex solver.
|
||||
virtual bool IsRestricted() const
|
||||
{ return false; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClPoint.h
|
||||
|
||||
#ifndef ClPoint_H
|
||||
#define ClPoint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClVariable.h"
|
||||
|
||||
// ClPoint is just a convenience class for pairs of
|
||||
// ClVariables -- often useful for coordinate pairs in 2-space
|
||||
class ClPoint {
|
||||
public:
|
||||
ClPoint(Number x, Number y)
|
||||
: _clv_x(x), _clv_y(y)
|
||||
{ }
|
||||
|
||||
ClPoint()
|
||||
{ }
|
||||
|
||||
ClVariable X()
|
||||
{ return _clv_x; }
|
||||
|
||||
ClVariable Y()
|
||||
{ return _clv_y; }
|
||||
|
||||
const ClVariable X() const
|
||||
{ return _clv_x; }
|
||||
|
||||
const ClVariable Y() const
|
||||
{ return _clv_y; }
|
||||
|
||||
void SetXY(Number x, Number y)
|
||||
{ _clv_x.SetValue(x); _clv_y.SetValue(y); }
|
||||
|
||||
Number Xvalue() const
|
||||
{ return X().Value(); }
|
||||
|
||||
Number Yvalue() const
|
||||
{ return Y().Value(); }
|
||||
|
||||
private:
|
||||
ClVariable _clv_x;
|
||||
ClVariable _clv_y;
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
friend ostream &operator<<(ostream &xo, const ClPoint &clp);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
inline ostream &
|
||||
operator<<(ostream &xo, const ClPoint &clp)
|
||||
{
|
||||
xo << "(" << clp._clv_x << ", " << clp._clv_y << ")";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClReader.h
|
||||
// Original implementation contributed by Steve Wolfman
|
||||
// Subsequently largely revised by Greg J. Badros
|
||||
|
||||
#ifndef CREADER_H
|
||||
#define CREADER_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include "ClErrors.h"
|
||||
#include "ClVariable.h"
|
||||
#include "ClStrength.h"
|
||||
#include "ClLinearExpression_fwd.h"
|
||||
|
||||
using std::string;
|
||||
using std::istream;
|
||||
|
||||
class ClConstraint;
|
||||
|
||||
class ClVarLookupFunction : public std::unary_function<const string &,ClVariable *> {
|
||||
public:
|
||||
virtual ~ClVarLookupFunction () {};
|
||||
virtual ClVariable *operator()(const string &) const { return &clvNil; }
|
||||
};
|
||||
|
||||
|
||||
// Attempts to read a constraint of input stream in
|
||||
// Returns constraint (freshly allocated, client responsibility to deallocate)
|
||||
// if succesful. Otherwise, returns 0.
|
||||
ClConstraint *PcnParseConstraint(istream &xi, const ClVarLookupFunction &lookup_func,
|
||||
const ClStrength &strength = ClsRequired());
|
||||
|
||||
class ClVarLookupInMap : public ClVarLookupFunction {
|
||||
public:
|
||||
ClVarLookupInMap(StringToVarMap *pmapVars, bool fAutoCreate)
|
||||
: _pmapVars(pmapVars), _fAutoCreate(fAutoCreate) { }
|
||||
|
||||
virtual ~ClVarLookupInMap () {};
|
||||
|
||||
ClVariable *operator()(const string &str) const
|
||||
{
|
||||
if (!_pmapVars)
|
||||
return &clvNil;
|
||||
StringToVarMap &_mapVars = *_pmapVars;
|
||||
StringToVarMap::iterator it = _mapVars.find(str);
|
||||
if (it != _mapVars.end()) {
|
||||
return &it->second;
|
||||
} else if (_fAutoCreate) {
|
||||
// save the old symbol table, if any
|
||||
StringToVarMap *pmapOld = ClVariable::VarMap();
|
||||
// and set it to this one temporarily
|
||||
ClVariable::SetVarMap(&_mapVars);
|
||||
ClVariable *pclv = new ClVariable(str);
|
||||
// now switch it back
|
||||
ClVariable::SetVarMap(pmapOld);
|
||||
return pclv;
|
||||
} else {
|
||||
return &clvNil;
|
||||
}
|
||||
}
|
||||
private:
|
||||
StringToVarMap *_pmapVars;
|
||||
bool _fAutoCreate;
|
||||
};
|
||||
|
||||
|
||||
/* the "yyerror" function */
|
||||
void clerror(const char *sz);
|
||||
|
||||
struct ClParseData {
|
||||
ClParseData(istream &xi, const ClVarLookupFunction &lookup_func)
|
||||
: _xi(xi), _lookup_func(lookup_func) { }
|
||||
|
||||
ClConstraint *Pcn() { return _pcn; }
|
||||
|
||||
ClVarSet _readOnlyVarsSoFar;
|
||||
|
||||
istream & _xi;
|
||||
ClConstraint * _pcn;
|
||||
const ClVarLookupFunction &_lookup_func;
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
const ClStrength
|
||||
&ClsFromSz(const char *sz)
|
||||
{
|
||||
const ClStrength *pcls = &ClsRequired();
|
||||
double n1, n2, n3;
|
||||
if (strcmp("required",sz) == 0)
|
||||
; /* initialized to ClsRequired, above */
|
||||
else if (strcasecmp("strong",sz) == 0) { pcls = &ClsStrong(); }
|
||||
else if (strcasecmp("medium",sz) == 0) { pcls = &ClsMedium(); }
|
||||
else if (strcasecmp("weak",sz) == 0) { pcls = &ClsWeak(); }
|
||||
else if (sscanf(sz,"(%lf,%lf,%lf)",&n1,&n2,&n3) == 3) {
|
||||
pcls = new ClStrength("parsed",n1,n2,n3);
|
||||
} else {
|
||||
throw ExCLParseErrorMisc("Error parsing strength");
|
||||
}
|
||||
return *pcls;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,588 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClSimplexSolver.h
|
||||
|
||||
#ifndef ClSimplexSolver_H
|
||||
#define ClSimplexSolver_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <stack>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include "Cassowary.h"
|
||||
#include "ClSolver.h"
|
||||
#include "ClTableau.h"
|
||||
#include "ClLinearInequality.h"
|
||||
#include "ClStrength.h"
|
||||
#include "ClStayConstraint.h"
|
||||
#include "ClEditConstraint.h"
|
||||
#include "ClSlackVariable.h"
|
||||
#include "ClObjectiveVariable.h"
|
||||
#include "ClErrors.h"
|
||||
#include "ClTypedefs.h"
|
||||
|
||||
using std::list;
|
||||
using std::stack;
|
||||
using std::ostream;
|
||||
|
||||
class ClVariable;
|
||||
class ClPoint;
|
||||
class ExCLRequiredFailureWithExplanation;
|
||||
|
||||
|
||||
// ClSimplexSolver encapsulates the solving behaviour
|
||||
// of the cassowary algorithm
|
||||
class ClSimplexSolver : public ClSolver, public ClTableau {
|
||||
protected:
|
||||
class ClEditInfo;
|
||||
typedef list<ClEditInfo *> ClEditInfoList;
|
||||
|
||||
ClEditInfo *PEditInfoFromClv(ClVariable clv) {
|
||||
ClEditInfoList::iterator it = _editInfoList.begin();
|
||||
for (; it != _editInfoList.end(); ++it) {
|
||||
ClEditInfo *pei = (*it);
|
||||
if (pei->_clv == clv)
|
||||
return pei;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
ClSimplexSolver() :
|
||||
ClSolver(),
|
||||
_objective(ClVariable(new ClObjectiveVariable("Z"))),
|
||||
_slackCounter(0),
|
||||
_artificialCounter(0),
|
||||
#ifdef CL_FIND_LEAK
|
||||
_cArtificialVarsDeleted(0),
|
||||
#endif
|
||||
_dummyCounter(0),
|
||||
_epsilon(1e-8),
|
||||
_fResetStayConstantsAutomatically(true),
|
||||
_fNeedsSolving(false),
|
||||
_fExplainFailure(false),
|
||||
_pfnResolveCallback(0),
|
||||
_pfnCnSatCallback(0)
|
||||
{
|
||||
_rows[_objective] = new ClLinearExpression();
|
||||
// start out with no edit variables
|
||||
_stkCedcns.push(0);
|
||||
#ifdef CL_TRACE
|
||||
std::cerr << "objective row new@ " << _rows[_objective] << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~ClSimplexSolver();
|
||||
|
||||
// Add constraints so that lower<=var<=upper. (nil means no bound.)
|
||||
ClSimplexSolver &AddLowerBound(ClVariable v, Number lower)
|
||||
{
|
||||
ClLinearInequality *pcn = new ClLinearInequality(ClLinearExpression(v - lower));
|
||||
return AddConstraint(pcn);
|
||||
}
|
||||
ClSimplexSolver &AddUpperBound(ClVariable v, Number upper)
|
||||
{
|
||||
ClLinearInequality *pcn = new ClLinearInequality(ClLinearExpression(upper - v));
|
||||
return AddConstraint(pcn);
|
||||
}
|
||||
ClSimplexSolver &AddBounds(ClVariable v, Number lower, Number upper)
|
||||
{ AddLowerBound(v,lower); AddUpperBound(v,upper); return *this; }
|
||||
|
||||
// Add the constraint cn to the tableau
|
||||
ClSimplexSolver &AddConstraint(ClConstraint *const pcn);
|
||||
|
||||
#ifndef CL_NO_DEPRECATED
|
||||
// Deprecated! --02/19/99 gjb
|
||||
ClSimplexSolver &AddConstraint(ClConstraint &cn)
|
||||
{ return AddConstraint(&cn); }
|
||||
#endif
|
||||
|
||||
// Add an edit constraint for "v" with given strength
|
||||
ClSimplexSolver &AddEditVar(const ClVariable v, const ClStrength &strength = ClsStrong(),
|
||||
double weight = 1.0 )
|
||||
{
|
||||
ClEditConstraint *pedit = new ClEditConstraint(v, strength, weight);
|
||||
return AddConstraint(pedit);
|
||||
}
|
||||
|
||||
ClSimplexSolver &RemoveEditVar(ClVariable v)
|
||||
{
|
||||
ClEditInfo *pcei = PEditInfoFromClv(v);
|
||||
if (!pcei) {
|
||||
throw ExCLEditMisuse("Removing edit variable that was not found");
|
||||
}
|
||||
ClConstraint *pcnEdit = pcei->_pconstraint;
|
||||
RemoveConstraint(pcnEdit);
|
||||
delete pcnEdit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// BeginEdit() should be called before sending
|
||||
// Resolve() messages, after adding the appropriate edit variables
|
||||
ClSimplexSolver &BeginEdit()
|
||||
{
|
||||
if (_editInfoList.size() == 0) {
|
||||
throw ExCLEditMisuse("BeginEdit called, but no edit variable");
|
||||
}
|
||||
// may later want to do more in here
|
||||
_infeasibleRows.clear();
|
||||
ResetStayConstants();
|
||||
_stkCedcns.push(_editInfoList.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// EndEdit should be called after editing has finished
|
||||
// for now, it just removes edit variables added from before the last BeginEdit
|
||||
ClSimplexSolver &EndEdit()
|
||||
{
|
||||
if (_editInfoList.size() == 0)
|
||||
throw ExCLEditMisuse("EndEdit called but no edit variables");
|
||||
Resolve();
|
||||
_stkCedcns.pop();
|
||||
RemoveEditVarsTo(_stkCedcns.top());
|
||||
// may later want to do more in here
|
||||
return *this;
|
||||
}
|
||||
|
||||
// RemoveAllEditVars() just eliminates all the edit constraints
|
||||
// that were added
|
||||
ClSimplexSolver &RemoveAllEditVars() { RemoveEditVarsTo(0); return *this; }
|
||||
|
||||
// remove the last added edit vars to leave only n edit vars left
|
||||
ClSimplexSolver &RemoveEditVarsTo(unsigned int n);
|
||||
|
||||
int numEditVars() const
|
||||
{ return _editInfoList.size(); }
|
||||
|
||||
// Add weak stays to the x and y parts of each point. These have
|
||||
// increasing weights so that the solver will try to satisfy the x
|
||||
// and y stays on the same point, rather than the x stay on one and
|
||||
// the y stay on another.
|
||||
ClSimplexSolver &AddPointStays(const vector<const ClPoint *> &listOfPoints,
|
||||
const ClStrength &strength = ClsWeak());
|
||||
|
||||
ClSimplexSolver &AddPointStay(const ClVariable vx, const ClVariable vy,
|
||||
const ClStrength &strength = ClsWeak(),
|
||||
double weight = 1.0)
|
||||
{ AddStay(vx,strength,weight); AddStay(vy,strength,weight); return *this; }
|
||||
|
||||
ClSimplexSolver &AddPointStay(const ClPoint &clp,
|
||||
const ClStrength &strength = ClsWeak(),
|
||||
double weight = 1.0);
|
||||
|
||||
|
||||
// Add a stay of the given strength (default to weak) of v to the tableau
|
||||
ClSimplexSolver &AddStay(const ClVariable v,
|
||||
const ClStrength &strength = ClsWeak(), double weight = 1.0 )
|
||||
{
|
||||
ClStayConstraint *pcn = new ClStayConstraint(v,strength,weight);
|
||||
return AddConstraint(pcn);
|
||||
}
|
||||
|
||||
// Remove the constraint cn from the tableau
|
||||
// Also remove any error variable associated with cn
|
||||
ClSimplexSolver &RemoveConstraint(ClConstraint *const pcn)
|
||||
{ RemoveConstraintInternal(pcn); pcn->removedFrom(*this); return *this; }
|
||||
|
||||
#ifndef CL_NO_DEPRECATED
|
||||
// Deprecated! --02/19/99 gjb
|
||||
ClSimplexSolver &RemoveConstraint(ClConstraint &cn)
|
||||
{ return RemoveConstraint(&cn); }
|
||||
#endif
|
||||
|
||||
|
||||
// Re-initialize this solver from the original constraints, thus
|
||||
// getting rid of any accumulated numerical problems. (Actually, we
|
||||
// haven't definitely observed any such problems yet)
|
||||
void Reset();
|
||||
|
||||
// Re-solve the current collection of constraints, given the new
|
||||
// values for the edit variables that have already been
|
||||
// suggested (see SuggestValue() method)
|
||||
// This is not guaranteed to work if you remove an edit constraint
|
||||
// from the middle of the edit constraints you added
|
||||
// (e.g., edit A, edit B, edit C, remove B -> this will fail!)
|
||||
// DEPRECATED
|
||||
void Resolve();
|
||||
|
||||
// Re-solve the current collection of constraints for new values for
|
||||
// the constants of the edit variables.
|
||||
// This is implemented in terms of SuggestValue-s, and is
|
||||
// less efficient than that more natural interface
|
||||
void Resolve(const vector<Number> &newEditConstants);
|
||||
|
||||
// Convenience function for Resolve-s of two variables
|
||||
void Resolve(Number x, Number y)
|
||||
{
|
||||
vector<Number> vals;
|
||||
vals.push_back(x);
|
||||
vals.push_back(y);
|
||||
Resolve(vals);
|
||||
}
|
||||
|
||||
// Suggest a new value for an edit variable
|
||||
// the variable needs to be added as an edit variable
|
||||
// and BeginEdit() needs to be called before this is called.
|
||||
// The tableau will not be solved completely until
|
||||
// after Resolve() has been called
|
||||
ClSimplexSolver &SuggestValue(ClVariable v, Number x);
|
||||
|
||||
// Set and check whether or not the solver will attempt to compile
|
||||
// an explanation of failure when a required constraint conflicts
|
||||
// with another required constraint
|
||||
ClSimplexSolver &SetExplaining(bool f)
|
||||
{ _fExplainFailure = f; return *this; }
|
||||
|
||||
bool FIsExplaining() const
|
||||
{ return _fExplainFailure; }
|
||||
|
||||
// If autosolving has been turned off, client code needs
|
||||
// to explicitly call solve() before accessing variables
|
||||
// values
|
||||
ClSimplexSolver &Solve()
|
||||
{
|
||||
#ifdef CL_SOLVER_CHECK_INTEGRITY
|
||||
AssertValid();
|
||||
#endif
|
||||
if (_fNeedsSolving)
|
||||
{
|
||||
Optimize(_objective);
|
||||
SetExternalVariables();
|
||||
#ifdef CL_TRACE_VERBOSE
|
||||
std::cerr << "Manual solve actually solving." << std::endl;
|
||||
#endif
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClSimplexSolver &SetEditedValue(ClVariable v, double n)
|
||||
{
|
||||
if (!FContainsVariable(v))
|
||||
{
|
||||
ChangeClv(v,n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (!ClApprox(n, v.Value()))
|
||||
{
|
||||
AddEditVar(v);
|
||||
BeginEdit();
|
||||
SuggestValue(v,n);
|
||||
EndEdit();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Solver contains the variable if it's in either the columns
|
||||
// list or the rows list
|
||||
bool FContainsVariable(const ClVariable v)
|
||||
{ return ColumnsHasKey(v) || RowExpression(v); }
|
||||
|
||||
ClSimplexSolver &AddVar(const ClVariable v)
|
||||
{ if (!FContainsVariable(v))
|
||||
{
|
||||
AddStay(v);
|
||||
#ifdef CL_TRACE
|
||||
std::cerr << "added initial stay on " << v << std::endl;
|
||||
#endif
|
||||
}
|
||||
return *this; }
|
||||
|
||||
typedef void (*PfnResolveCallback)(ClSimplexSolver *psolver);
|
||||
|
||||
void SetResolveCallback(PfnResolveCallback pfn)
|
||||
{ _pfnResolveCallback = pfn; }
|
||||
|
||||
typedef void (*PfnCnSatCallback)(ClSimplexSolver *psolver,
|
||||
ClConstraint *pcn, bool fSatisfied);
|
||||
|
||||
void SetCnSatCallback(PfnCnSatCallback pfn)
|
||||
{ _pfnCnSatCallback = pfn; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
friend ostream &operator<<(ostream &xo, const ClSimplexSolver &tableau);
|
||||
|
||||
ostream &PrintOn(ostream &xo) const;
|
||||
|
||||
ostream &PrintInternalInfo(ostream &xo) const;
|
||||
|
||||
ostream &PrintOnVerbose(ostream &xo) const
|
||||
{ PrintOn(xo); PrintInternalInfo(xo); xo << std::endl; return xo; }
|
||||
|
||||
#endif
|
||||
|
||||
const ClConstraintToVarMap &ConstraintMap() const
|
||||
{ return _markerVars; }
|
||||
|
||||
const ClVarToConstraintMap &MarkerMap() const
|
||||
{ return _constraintsMarked; }
|
||||
|
||||
bool FIsConstraintSatisfied(const ClConstraint *const pcn) const;
|
||||
|
||||
// DEPRECATED
|
||||
bool FIsConstraintSatisfied(const ClConstraint &pcn) const
|
||||
{ return FIsConstraintSatisfied(&pcn); }
|
||||
|
||||
// re-set all the external variables to their current values
|
||||
// most importantly, this re-calls all the ChangeClv callbacks
|
||||
// (which might be used to copy the ClVariable's value to another
|
||||
// variable)
|
||||
void UpdateExternalVariables()
|
||||
{ SetExternalVariables(); }
|
||||
|
||||
// A. Beurive' Tue Jul 6 17:05:39 CEST 1999
|
||||
void ChangeStrengthAndWeight(ClConstraint *pcn, const ClStrength &strength, double weight);
|
||||
void ChangeStrength(ClConstraint *pcn, const ClStrength &strength);
|
||||
void ChangeWeight(ClConstraint *pcn, double weight);
|
||||
// void DisplayObjective();
|
||||
|
||||
// Each of the non-required stays will be represented by an equation
|
||||
// of the form
|
||||
// v = c + eplus - eminus
|
||||
// where v is the variable with the stay, c is the previous value of
|
||||
// v, and eplus and eminus are slack variables that hold the error
|
||||
// in satisfying the stay constraint. We are about to change
|
||||
// something, and we want to fix the constants in the equations
|
||||
// representing the stays. If both eplus and eminus are nonbasic
|
||||
// they have value 0 in the current solution, meaning the previous
|
||||
// stay was exactly satisfied. In this case nothing needs to be
|
||||
// changed. Otherwise one of them is basic, and the other must
|
||||
// occur only in the Expression for that basic error variable.
|
||||
// Reset the Constant in this Expression to 0.
|
||||
void ResetStayConstants();
|
||||
|
||||
ClSimplexSolver &SetAutoResetStayConstants(bool f)
|
||||
{ _fResetStayConstantsAutomatically = f; if (f) ResetStayConstants(); return *this; }
|
||||
|
||||
bool FIsAutoResetStayConstants() const
|
||||
{ return _fResetStayConstantsAutomatically; }
|
||||
|
||||
protected:
|
||||
|
||||
// ClEditInfo is a privately-used class
|
||||
// that just wraps a constraint, its positive and negative
|
||||
// error variables, and its prior edit Constant.
|
||||
// It is used as values in _editInfoList, and replaces
|
||||
// the parallel vectors of error variables and previous edit
|
||||
// constants from the smalltalk version of the code.
|
||||
class ClEditInfo {
|
||||
friend class ClSimplexSolver;
|
||||
public:
|
||||
|
||||
// These instances own none of the pointers;
|
||||
// the tableau row (the Expression) owns the peplus, peminus,
|
||||
// and AddEditVar/RemoveEditVar pair or the client code owns
|
||||
// the constraint object
|
||||
ClEditInfo(ClVariable clv,
|
||||
ClEditConstraint *pconstraint,
|
||||
ClVariable eplus, ClVariable eminus,
|
||||
Number prevEditConstant)
|
||||
:_clv(clv),
|
||||
_pconstraint(pconstraint),
|
||||
_clvEditPlus(eplus), _clvEditMinus(eminus),
|
||||
_prevEditConstant(prevEditConstant)
|
||||
{ }
|
||||
|
||||
~ClEditInfo()
|
||||
{ }
|
||||
|
||||
ostream &PrintOn(ostream &xo) const
|
||||
{ xo << _clv << " -> [" << _clvEditPlus << ", " << _clvEditMinus << "]("
|
||||
<< _prevEditConstant << ")@" << " -- "
|
||||
<< *_pconstraint;
|
||||
return xo; }
|
||||
|
||||
friend ostream &operator<<(ostream &xo, const ClEditInfo &cei)
|
||||
{ return cei.PrintOn(xo); }
|
||||
|
||||
private:
|
||||
ClVariable _clv;
|
||||
ClConstraint *_pconstraint;
|
||||
ClVariable _clvEditPlus;
|
||||
ClVariable _clvEditMinus;
|
||||
Number _prevEditConstant;
|
||||
};
|
||||
|
||||
// Add the constraint expr=0 to the inequality tableau using an
|
||||
// artificial variable. To do this, create an artificial variable
|
||||
// av and Add av=expr to the inequality tableau, then make av be 0.
|
||||
// (Raise an exception if we can't attain av=0.)
|
||||
// (Raise an exception if we can't attain av=0.) If the Add fails,
|
||||
// prepare an explanation in e that describes why it failed (note
|
||||
// that an empty explanation is considered to mean the explanation
|
||||
// encompasses all active constraints.
|
||||
bool AddWithArtificialVariable(ClLinearExpression &pexpr,
|
||||
ExCLRequiredFailureWithExplanation &e);
|
||||
|
||||
// Using the given equation (av = cle) build an explanation which
|
||||
// implicates all constraints used to construct the equation. That
|
||||
// is, everything for which the variables in the equation are markers.
|
||||
// Thanks to Steve Wolfman for the implementation of the explanation feature
|
||||
void BuildExplanation(ExCLRequiredFailureWithExplanation & e,
|
||||
ClVariable av,
|
||||
const ClLinearExpression * pcle);
|
||||
|
||||
// We are trying to Add the constraint expr=0 to the appropriate
|
||||
// tableau. Try to Add expr directly to the tableax without
|
||||
// creating an artificial variable. Return true if successful and
|
||||
// false if not.
|
||||
bool TryAddingDirectly(ClLinearExpression &pexpr);
|
||||
|
||||
// We are trying to Add the constraint expr=0 to the tableaux. Try
|
||||
// to choose a subject (a variable to become basic) from among the
|
||||
// current variables in expr. If expr contains any unrestricted
|
||||
// variables, then we must choose an unrestricted variable as the
|
||||
// subject. Also, if the subject is new to the solver we won't have
|
||||
// to do any substitutions, so we prefer new variables to ones that
|
||||
// are currently noted as parametric. If expr contains only
|
||||
// restricted variables, if there is a restricted variable with a
|
||||
// negative coefficient that is new to the solver we can make that
|
||||
// the subject. Otherwise we can't find a subject, so return nil.
|
||||
// (In this last case we have to Add an artificial variable and use
|
||||
// that variable as the subject -- this is done outside this method
|
||||
// though.)
|
||||
//
|
||||
// Note: in checking for variables that are new to the solver, we
|
||||
// ignore whether a variable occurs in the objective function, since
|
||||
// new slack variables are added to the objective function by
|
||||
// 'NewExpression:', which is called before this method.
|
||||
ClVariable ChooseSubject(ClLinearExpression &pexpr);
|
||||
|
||||
// Each of the non-required edits will be represented by an equation
|
||||
// of the form
|
||||
// v = c + eplus - eminus
|
||||
// where v is the variable with the edit, c is the previous edit
|
||||
// value, and eplus and eminus are slack variables that hold the
|
||||
// error in satisfying the edit constraint. We are about to change
|
||||
// something, and we want to fix the constants in the equations
|
||||
// representing the edit constraints. If one of eplus and eminus is
|
||||
// basic, the other must occur only in the Expression for that basic
|
||||
// error variable. (They can't both be basic.) Fix the Constant in
|
||||
// this Expression. Otherwise they are both nonbasic. Find all of
|
||||
// the expressions in which they occur, and fix the constants in
|
||||
// those. See the UIST paper for details.
|
||||
// (This comment was for resetEditConstants(), but that is now
|
||||
// gone since it was part of the screwey vector-based interface
|
||||
// to resolveing. --02/15/99 gjb)
|
||||
void DeltaEditConstant(Number delta, ClVariable pv1, ClVariable pv2);
|
||||
|
||||
// We have set new values for the constants in the edit constraints.
|
||||
// Re-Optimize using the dual simplex algorithm.
|
||||
void DualOptimize();
|
||||
|
||||
// Make a new linear Expression representing the constraint cn,
|
||||
// replacing any basic variables with their defining expressions.
|
||||
// Normalize if necessary so that the Constant is non-negative. If
|
||||
// the constraint is non-required give its error variables an
|
||||
// appropriate weight in the objective function.
|
||||
ClLinearExpression *NewExpression(const ClConstraint *pcn,
|
||||
/* output to */
|
||||
ClVariable &clvEplus,
|
||||
ClVariable &clvEminus,
|
||||
Number &prevEConstant);
|
||||
|
||||
// Minimize the value of the objective. (The tableau should already
|
||||
// be feasible.)
|
||||
void Optimize(ClVariable zVar);
|
||||
|
||||
// Do a Pivot. Move entryVar into the basis (i.e. make it a basic variable),
|
||||
// and move exitVar out of the basis (i.e., make it a parametric variable)
|
||||
void Pivot(ClVariable entryVar, ClVariable exitVar);
|
||||
|
||||
// Set the external variables known to this solver to their appropriate values.
|
||||
// Set each external basic variable to its value, and set each
|
||||
// external parametric variable to 0. (It isn't clear that we will
|
||||
// ever have external parametric variables -- every external
|
||||
// variable should either have a stay on it, or have an equation
|
||||
// that defines it in terms of other external variables that do have
|
||||
// stays. For the moment I'll put this in though.) Variables that
|
||||
// are internal to the solver don't actually store values -- their
|
||||
// values are just implicit in the tableu -- so we don't need to set
|
||||
// them.
|
||||
void SetExternalVariables();
|
||||
|
||||
// this gets called by RemoveConstraint and by AddConstraint when the
|
||||
// contraint we're trying to Add is inconsistent
|
||||
ClSimplexSolver &RemoveConstraintInternal(const ClConstraint *const pcn);
|
||||
|
||||
void ChangeClv(ClVariable clv, Number n) {
|
||||
clv.ChangeValue(n);
|
||||
if (_pfnChangeClvCallback)
|
||||
_pfnChangeClvCallback(&clv,this);
|
||||
}
|
||||
|
||||
/// instance variables
|
||||
|
||||
// the arrays of positive and negative error vars for the stay constraints
|
||||
// (need both positive and negative since they have only non-negative values)
|
||||
ClVarVector _stayMinusErrorVars;
|
||||
ClVarVector _stayPlusErrorVars;
|
||||
|
||||
// give error variables for a non required constraint,
|
||||
// maps to ClSlackVariable-s
|
||||
ClConstraintToVarSetMap _errorVars;
|
||||
|
||||
// Return a lookup table giving the marker variable for each
|
||||
// constraint (used when deleting a constraint).
|
||||
ClConstraintToVarMap _markerVars;
|
||||
|
||||
// Reverse of the above-- a lookup table giving the constraint
|
||||
// for each marker variable (used when building failure explanations)
|
||||
ClVarToConstraintMap _constraintsMarked;
|
||||
|
||||
ClVariable _objective;
|
||||
|
||||
// Map edit variables to their constraints, errors, and prior
|
||||
// values
|
||||
ClEditInfoList _editInfoList;
|
||||
|
||||
int _slackCounter;
|
||||
int _artificialCounter;
|
||||
#ifdef CL_FIND_LEAK
|
||||
int _cArtificialVarsDeleted;
|
||||
#endif
|
||||
int _dummyCounter;
|
||||
const double _epsilon;
|
||||
|
||||
bool _fResetStayConstantsAutomatically;
|
||||
bool _fNeedsSolving;
|
||||
bool _fExplainFailure;
|
||||
|
||||
PfnResolveCallback _pfnResolveCallback;
|
||||
PfnCnSatCallback _pfnCnSatCallback;
|
||||
|
||||
// C-style extension mechanism so I
|
||||
// don't have to wrap ScwmClSolver separately
|
||||
void *_pv;
|
||||
|
||||
// a stack of the number of edit constraints
|
||||
// that existed at the prior BeginEdit.
|
||||
// an EndEdit needs to pop off the top value,
|
||||
// then remove constraints to get down
|
||||
// to the # of constraints as in _stkCedcns.top()
|
||||
stack<int> _stkCedcns;
|
||||
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
|
||||
friend ostream &PrintTo(ostream &xo, const ClSimplexSolver::ClEditInfoList &listPEditInfo);
|
||||
friend ostream &operator<<(ostream &xo, const ClSimplexSolver::ClEditInfoList &listPEditInfo);
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // ClSimplexSolver_H
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClSlackVariable.h
|
||||
|
||||
#ifndef ClSlackVariable_H
|
||||
#define ClSlackVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClAbstractVariable.h"
|
||||
|
||||
class ClTableau;
|
||||
class ClSimplexSolver;
|
||||
|
||||
|
||||
class ClSlackVariable : public ClAbstractVariable {
|
||||
public:
|
||||
#ifdef CL_FIND_LEAK
|
||||
~ClSlackVariable() { --cSlackVariables; };
|
||||
|
||||
static long cSlackVariables;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class ClTableau;
|
||||
friend class ClSimplexSolver;
|
||||
|
||||
ClSlackVariable(string Name = "") :
|
||||
ClAbstractVariable(Name)
|
||||
{
|
||||
#ifdef CL_FIND_LEAK
|
||||
++cSlackVariables;
|
||||
#endif
|
||||
}
|
||||
|
||||
ClSlackVariable(long number, char *prefix) :
|
||||
ClAbstractVariable(number,prefix)
|
||||
{
|
||||
#ifdef CL_FIND_LEAK
|
||||
++cSlackVariables;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << "[" << Name() << ":slack]";
|
||||
return xo;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual bool IsExternal() const
|
||||
{ return false; }
|
||||
|
||||
virtual bool IsPivotable() const
|
||||
{ return true; }
|
||||
|
||||
virtual bool IsRestricted() const
|
||||
{ return true; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClSolver.h
|
||||
|
||||
#ifndef ClSolver_H
|
||||
#define ClSolver_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClErrors.h"
|
||||
#include "ClTypedefs.h"
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
using std::list;
|
||||
using std::ostream;
|
||||
|
||||
class ClVariable;
|
||||
|
||||
// ClSolver is an abstract base class
|
||||
class ClSolver {
|
||||
public:
|
||||
|
||||
ClSolver() : _pv(0), _fAutosolve(true), _pfnChangeClvCallback(0) { }
|
||||
|
||||
virtual ~ClSolver()
|
||||
{ }
|
||||
|
||||
// Add the constraint cn to the solver
|
||||
virtual ClSolver &AddConstraint(ClConstraint *const pcn) = 0;
|
||||
|
||||
// Remove the constraint cn from the solver
|
||||
virtual ClSolver &RemoveConstraint(ClConstraint *const pcn) = 0;
|
||||
|
||||
// Same as above, but returns false if the constraint cannot be solved
|
||||
// (i.e., the resulting system would be unsatisfiable)
|
||||
// The above function "AddConstraint" throws an exception in that case
|
||||
// which may be inconvenient
|
||||
virtual bool AddConstraintNoException(ClConstraint *const pcn)
|
||||
{
|
||||
try {
|
||||
AddConstraint(pcn);
|
||||
return true;
|
||||
}
|
||||
catch (const ExCLRequiredFailure &e)
|
||||
{ return false; }
|
||||
catch (const ExCLTooDifficult &e)
|
||||
{ return false; }
|
||||
}
|
||||
|
||||
#ifndef CL_NO_DEPRECATED
|
||||
// Deprecated --02/22/99 gjb
|
||||
bool AddConstraintNoException(ClConstraint &cn)
|
||||
{ return AddConstraintNoException(&cn); }
|
||||
#endif
|
||||
|
||||
virtual bool RemoveConstraintNoException(ClConstraint *const pcn)
|
||||
{
|
||||
try {
|
||||
RemoveConstraint(pcn);
|
||||
return true;
|
||||
}
|
||||
catch (const ExCLConstraintNotFound &e)
|
||||
{ return false; }
|
||||
}
|
||||
|
||||
#ifndef CL_NO_DEPRECATED
|
||||
// Deprecated --02/22/99 gjb
|
||||
bool RemoveConstraintNoException(ClConstraint &cn)
|
||||
{ return RemoveConstraintNoException(&cn); }
|
||||
#endif
|
||||
|
||||
|
||||
virtual ClSolver &Solve()
|
||||
{ assert(false); return *this; }
|
||||
|
||||
virtual bool SolveNoException()
|
||||
{
|
||||
try {
|
||||
Solve();
|
||||
return true;
|
||||
}
|
||||
catch (const ExCLTooDifficult &e)
|
||||
{ return false; }
|
||||
catch (const ExCLRequiredFailure &e)
|
||||
{ return false; }
|
||||
}
|
||||
|
||||
|
||||
virtual void Resolve()
|
||||
{ assert(false); }
|
||||
|
||||
void SetPv(void *pv)
|
||||
{ _pv = pv; }
|
||||
|
||||
void *Pv() const
|
||||
{ return _pv; }
|
||||
|
||||
typedef void (*PfnChangeClvCallback)(ClVariable *pclv, ClSolver *psolver);
|
||||
|
||||
void SetChangeClvCallback(PfnChangeClvCallback pfn)
|
||||
{ _pfnChangeClvCallback = pfn; }
|
||||
|
||||
// Control whether optimization and setting of external variables
|
||||
// is done automatically or not. By default it is done
|
||||
// automatically and solve() never needs to be explicitly
|
||||
// called by client code; if SetAutosolve is put to false,
|
||||
// then solve() needs to be invoked explicitly before using
|
||||
// variables' values
|
||||
// (Turning off autosolve while adding lots and lots of
|
||||
// constraints [ala the addDel test in ClTests] saved
|
||||
// about 20% in runtime, from 68sec to 54sec for 900 constraints,
|
||||
// with 126 failed adds)
|
||||
ClSolver &SetAutosolve(bool f)
|
||||
{ _fAutosolve = f; if (f) Solve(); return *this; }
|
||||
|
||||
// Tell whether we are autosolving
|
||||
bool FIsAutosolving() const
|
||||
{ return _fAutosolve; }
|
||||
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
friend ostream &operator<<(ostream &xo, const ClSolver &solver);
|
||||
|
||||
virtual ostream &PrintOn(ostream &xo) const = 0;
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
// C-style extension mechanism so I
|
||||
// don't have to wrap ScwmClSolver separately
|
||||
void *_pv;
|
||||
|
||||
bool _fAutosolve;
|
||||
|
||||
PfnChangeClvCallback _pfnChangeClvCallback;
|
||||
};
|
||||
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
ostream &PrintTo(ostream &xo, const ClVarVector &varlist);
|
||||
ostream &operator<<(ostream &xo, const ClVarVector &varlist);
|
||||
|
||||
ostream &PrintTo(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet);
|
||||
ostream &operator<<(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet);
|
||||
|
||||
ostream &PrintTo(ostream &xo, const ClConstraintSet &setCn);
|
||||
ostream &operator<<(ostream &xo, const ClConstraintSet &setCn);
|
||||
|
||||
ostream &PrintTo(ostream &xo, const list<FDNumber> &listFDN);
|
||||
ostream &operator<<(ostream &xo, const list<FDNumber> &listFDN);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClStayConstraint.h
|
||||
|
||||
#ifndef ClStayConstraint_H
|
||||
#define ClStayConstraint_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClEditOrStayConstraint.h"
|
||||
|
||||
class ClStayConstraint : public ClEditOrStayConstraint {
|
||||
typedef ClEditOrStayConstraint super;
|
||||
public:
|
||||
|
||||
ClStayConstraint(const ClVariable var,
|
||||
const ClStrength &strength = ClsWeak(), double weight = 1.0 ) :
|
||||
ClEditOrStayConstraint(var,strength,weight)
|
||||
{ }
|
||||
|
||||
virtual bool isStayConstraint() const
|
||||
{ return true; }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{ super::PrintOn(xo); return xo << " STAY)"; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClStrength.h
|
||||
|
||||
#ifndef ClStrength_H
|
||||
#define ClStrength_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClSymbolicWeight.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class ClStrength;
|
||||
|
||||
const ClStrength &ClsRequired();
|
||||
const ClStrength &ClsStrong();
|
||||
const ClStrength &ClsMedium();
|
||||
const ClStrength &ClsWeak();
|
||||
|
||||
class ClStrength {
|
||||
public:
|
||||
|
||||
ClStrength(const string &Name, const ClSymbolicWeight &symbolicWeight) :
|
||||
_name(Name), _symbolicWeight(symbolicWeight)
|
||||
{ }
|
||||
|
||||
// special case for when nLevels = 3, should assert nLevels() == 3
|
||||
ClStrength(const string &Name, double w1, double w2, double w3);
|
||||
|
||||
virtual ~ClStrength()
|
||||
{ }
|
||||
|
||||
virtual bool IsRequired() const
|
||||
{ return (_symbolicWeight == ClsRequired()._symbolicWeight); }
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
virtual ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
xo << Name();
|
||||
if (!IsRequired())
|
||||
xo << ":" << symbolicWeight();
|
||||
return xo;
|
||||
}
|
||||
|
||||
friend ostream& operator<<(ostream &xos, const ClStrength &Cls)
|
||||
{ Cls.PrintOn(xos); return xos; }
|
||||
|
||||
#endif
|
||||
|
||||
virtual const ClSymbolicWeight &symbolicWeight() const
|
||||
{ return _symbolicWeight; }
|
||||
|
||||
void SetPv(void *pv)
|
||||
{ _pv = pv; }
|
||||
|
||||
void *Pv() const
|
||||
{ return _pv; }
|
||||
|
||||
private:
|
||||
string Name() const
|
||||
{ return _name; }
|
||||
|
||||
void SetName(string Name)
|
||||
{ _name = Name; }
|
||||
|
||||
void SetSymbolicWeight(const ClSymbolicWeight &symbolicWeight)
|
||||
{ _symbolicWeight = symbolicWeight; }
|
||||
|
||||
// instance variables
|
||||
string _name;
|
||||
ClSymbolicWeight _symbolicWeight;
|
||||
|
||||
void *_pv;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClSymbolicWeight.h
|
||||
|
||||
#ifndef ClSymbolicWeight_H
|
||||
#define ClSymbolicWeight_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClErrors.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
using std::vector;
|
||||
using std::ostream;
|
||||
|
||||
class ClSymbolicWeight {
|
||||
public:
|
||||
ClSymbolicWeight(unsigned int CLevels = 3, Number value = 0.0);
|
||||
|
||||
ClSymbolicWeight(Number w1, Number w2, Number w3);
|
||||
|
||||
ClSymbolicWeight(const vector<Number> &weights);
|
||||
|
||||
static ClSymbolicWeight &Zero();
|
||||
|
||||
ClSymbolicWeight &negated();
|
||||
|
||||
ClSymbolicWeight &MultiplyMe(Number n);
|
||||
|
||||
ClSymbolicWeight Times(Number n) const
|
||||
{ ClSymbolicWeight cl = *this; cl.MultiplyMe(n); return cl; }
|
||||
|
||||
ClSymbolicWeight DivideBy(Number n) const;
|
||||
|
||||
ClSymbolicWeight &addtoMe(const ClSymbolicWeight &cl);
|
||||
|
||||
ClSymbolicWeight Add(const ClSymbolicWeight &cl) const
|
||||
{ ClSymbolicWeight clRet = *this; clRet.addtoMe(cl); return clRet; }
|
||||
|
||||
ClSymbolicWeight Subtract(const ClSymbolicWeight &cl) const;
|
||||
|
||||
ClSymbolicWeight operator*(const Number &n) const
|
||||
{ return Times(n); }
|
||||
|
||||
ClSymbolicWeight operator/(const Number &n) const
|
||||
{ return DivideBy(n); }
|
||||
|
||||
// FIXGJB: can we express this statically?
|
||||
ClSymbolicWeight operator*(ClSymbolicWeight &w) const
|
||||
{ throw ExCLInternalError("Multiplication of symbolic weights encountered");
|
||||
return w; }
|
||||
ClSymbolicWeight &operator*=(ClSymbolicWeight &w)
|
||||
{ throw ExCLInternalError("Multiplicative assignment of symbolic weights encountered");
|
||||
return w; }
|
||||
|
||||
// FIXGJB: can we express this statically?
|
||||
ClSymbolicWeight operator-() const
|
||||
{ throw ExCLInternalError("Can not negate a symbolic weight");
|
||||
return ClSymbolicWeight::Zero(); }
|
||||
|
||||
friend ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &);
|
||||
|
||||
ClSymbolicWeight &operator*=(const Number &n)
|
||||
{ return MultiplyMe(n); }
|
||||
|
||||
ClSymbolicWeight operator+(const ClSymbolicWeight &cl) const
|
||||
{ return Add(cl); }
|
||||
|
||||
ClSymbolicWeight operator+=(const ClSymbolicWeight &cl)
|
||||
{ return addtoMe(cl); }
|
||||
|
||||
ClSymbolicWeight operator*(const Number &n)
|
||||
{ ClSymbolicWeight answer(*this);
|
||||
answer *= n;
|
||||
return answer; }
|
||||
|
||||
bool lessThan(const ClSymbolicWeight &cl) const;
|
||||
bool lessThanOrEqual(const ClSymbolicWeight &cl) const;
|
||||
bool equal(const ClSymbolicWeight &cl) const;
|
||||
bool greaterThan(const ClSymbolicWeight &cl) const;
|
||||
bool greaterThanOrEqual(const ClSymbolicWeight &cl) const;
|
||||
bool isNegative() const;
|
||||
|
||||
friend bool operator==(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
|
||||
{ return cl1.equal(cl2); }
|
||||
|
||||
friend bool operator!=(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
|
||||
{ return !(cl1 == cl2); }
|
||||
|
||||
friend bool operator<(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
|
||||
{ return cl1.lessThan(cl2); }
|
||||
|
||||
friend bool operator>(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
|
||||
{ return (cl2 < cl1); }
|
||||
|
||||
// function.h provides operator>, >=, <= from operator<
|
||||
|
||||
double AsDouble() const
|
||||
{
|
||||
vector<Number>::const_reverse_iterator i = _values.rbegin();
|
||||
Number sum = 0;
|
||||
Number factor = 1;
|
||||
// A. Beurive' Wed Jul 7 11:07:47 CEST 1999
|
||||
Number multiplier = 1000000;
|
||||
for ( ; i != _values.rend(); ++i)
|
||||
{
|
||||
sum += *i * factor;
|
||||
factor *= multiplier;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
vector<Number>::const_iterator i = _values.begin();
|
||||
if (i == _values.end())
|
||||
return xo;
|
||||
|
||||
xo << *i;
|
||||
for (++i; i != _values.end(); ++i)
|
||||
{
|
||||
xo << "," << *i;
|
||||
}
|
||||
return xo;
|
||||
}
|
||||
|
||||
// FIXGJB: use a template function to generate these automatically
|
||||
friend ostream& operator<<(ostream &xos, const ClSymbolicWeight &clsw)
|
||||
{ clsw.PrintOn(xos); return xos; }
|
||||
#endif
|
||||
|
||||
int CLevels() const
|
||||
{ return _values.size(); }
|
||||
|
||||
friend bool ClApprox(const ClSymbolicWeight &cl, Number n);
|
||||
friend bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2);
|
||||
|
||||
private:
|
||||
vector<Number> _values;
|
||||
|
||||
void push_back(Number d)
|
||||
{ _values.push_back(d); }
|
||||
|
||||
};
|
||||
|
||||
inline bool ClApprox(const ClSymbolicWeight &cl, Number n)
|
||||
{
|
||||
vector<Number>::const_iterator it = cl._values.begin();
|
||||
if (!ClApprox(*it,n))
|
||||
return false;
|
||||
|
||||
++it;
|
||||
for (; it != cl._values.end(); ++it)
|
||||
{
|
||||
if (!ClApprox(*it,0))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool ClApprox(const ClSymbolicWeight &cl1, const ClSymbolicWeight &cl2)
|
||||
{
|
||||
vector<Number>::const_iterator it1 = cl1._values.begin();
|
||||
vector<Number>::const_iterator it2 = cl2._values.begin();
|
||||
|
||||
for (; it1 != cl1._values.end() && it2 != cl2._values.end();
|
||||
++it1, ++it2)
|
||||
{
|
||||
if (!ClApprox(*it1,*it2))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (it1 == cl1._values.end() && it2 == cl2._values.end())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline ClSymbolicWeight ReciprocalOf(const ClSymbolicWeight &)
|
||||
{ throw(ExCLInternalError("Cannot take ReciprocalOf symbolic weight"));
|
||||
return ClSymbolicWeight::Zero(); }
|
||||
|
||||
#endif
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClTableau.h
|
||||
|
||||
#ifndef ClTableau_H
|
||||
#define ClTableau_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "Cassowary.h"
|
||||
#include "ClLinearExpression.h"
|
||||
#include "ClVariable.h"
|
||||
#include "ClTypedefs.h"
|
||||
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
class ClTableau;
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClTableau &clt);
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClVarSet &varset);
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClTableauColumnsMap &varmap);
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClTableauRowsMap &rows);
|
||||
|
||||
ostream &operator<<(ostream &xo, const ClVarVector &varlist);
|
||||
#endif // CL_NO_IO
|
||||
|
||||
class ClTableau {
|
||||
|
||||
public:
|
||||
// No public constructor, since this does nothing but support
|
||||
// an ADT for the ClSimplexSolver
|
||||
|
||||
// Variable v has been removed from an Expression. If the
|
||||
// Expression is in a tableau the corresponding basic variable is
|
||||
// subject (or if subject is nil then it's in the objective function).
|
||||
// Update the column cross-indices.
|
||||
void NoteRemovedVariable(ClVariable v, ClVariable subject)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
std::cerr << "(" << v << ", " << subject << ")" << std::endl;
|
||||
#endif
|
||||
ClVarSet &column = _columns[v];
|
||||
ClVarSet::const_iterator it = column.find(subject);
|
||||
assert(it != column.end());
|
||||
column.erase(it);
|
||||
#ifdef CL_TRACE_VERBOSE
|
||||
std::cerr << "v = " << v << " and Columns[v].size() = "
|
||||
<< column.size() << std::endl;
|
||||
#endif
|
||||
if (column.size() == 0)
|
||||
{
|
||||
_columns.erase(v);
|
||||
_externalRows.erase(v);
|
||||
_externalParametricVars.erase(v);
|
||||
}
|
||||
}
|
||||
|
||||
// v has been added to the linear Expression for subject
|
||||
// update column cross indices
|
||||
void NoteAddedVariable(ClVariable v, ClVariable subject)
|
||||
{
|
||||
#ifdef CL_TRACE
|
||||
Tracer TRACER(__FUNCTION__);
|
||||
std::cerr << "(" << v << ", " << subject << ")" << std::endl;
|
||||
#endif
|
||||
_columns[v].insert(subject);
|
||||
if (v.IsExternal() && !FIsBasicVar(v))
|
||||
{
|
||||
_externalParametricVars.insert(v);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
std::ostream &PrintOn(ostream &xo) const;
|
||||
|
||||
ostream &PrintInternalInfo(ostream &xo) const;
|
||||
|
||||
ostream &printExternalVariablesTo(ostream &xo) const;
|
||||
|
||||
#endif
|
||||
|
||||
// Check integrity of the tableau
|
||||
// not complete, yet, but a start, at least
|
||||
// Guard calls to AssertValid with CL_SOLVER_CHECK_INTEGRITY,
|
||||
// since this is expensive
|
||||
virtual void AssertValid() const {
|
||||
#ifndef NDEBUG
|
||||
// all external basic variables are in _externalRows
|
||||
// and all external parametric variables are in _externalParametricVars
|
||||
ClTableauRowsMap::const_iterator itRow = _rows.begin();
|
||||
for (; itRow != _rows.end(); ++itRow)
|
||||
{
|
||||
const ClVariable clv = (*itRow).first;
|
||||
if (clv.IsExternal())
|
||||
{
|
||||
if (_externalRows.find(clv) == _externalRows.end())
|
||||
{
|
||||
#ifndef CL_NO_IO
|
||||
std::cerr << "External basic variable " << clv
|
||||
<< " is not in _externalRows" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
const ClLinearExpression *pcle = RowExpression(clv);
|
||||
assert(pcle);
|
||||
ClVarToNumberMap::const_iterator it = pcle->Terms().begin();
|
||||
for (; it != pcle->Terms().end(); ++it)
|
||||
{
|
||||
ClVariable clv = (*it).first;
|
||||
if (clv.IsExternal())
|
||||
{
|
||||
if (_externalParametricVars.find(clv) == _externalParametricVars.end())
|
||||
{
|
||||
#ifndef CL_NO_IO
|
||||
std::cerr << "External parametric variable " << clv
|
||||
<< " is not in _externalParametricVars" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !NDEBUG */
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
// Constructor -- want to start with empty objects so not much to do
|
||||
ClTableau()
|
||||
{ }
|
||||
|
||||
virtual ~ClTableau();
|
||||
|
||||
// Add v=expr to the tableau, update column cross indices
|
||||
// v becomes a basic variable
|
||||
// expr is now owned by ClTableau class,
|
||||
// and ClTableauis responsible for deleting it
|
||||
// (also, expr better be allocated on the heap!)
|
||||
void addRow(ClVariable v, const ClLinearExpression &expr);
|
||||
|
||||
// Remove v from the tableau -- remove the column cross indices for v
|
||||
// and remove v from every Expression in rows in which v occurs
|
||||
// returns a pointer to the variable (since we often want to delete
|
||||
// the variable)
|
||||
ClVariable RemoveColumn(ClVariable v);
|
||||
|
||||
// Remove the basic variable v from the tableau row v=expr
|
||||
// Then update column cross indices
|
||||
// Probably want to call delete on the ClLinearExpression * returned
|
||||
// unless you're adding that same Expression back into the
|
||||
// tableau
|
||||
ClLinearExpression *RemoveRow(ClVariable v);
|
||||
|
||||
// Replace all occurrences of oldVar with expr, and update column cross indices
|
||||
// oldVar should now be a basic variable
|
||||
void SubstituteOut(ClVariable oldVar, const ClLinearExpression &expr);
|
||||
|
||||
ClTableauColumnsMap Columns()
|
||||
{ return _columns; }
|
||||
|
||||
ClTableauRowsMap Rows()
|
||||
{ return _rows; }
|
||||
|
||||
// return true iff the variable subject is in the Columns keys
|
||||
bool ColumnsHasKey(ClVariable subject) const
|
||||
{
|
||||
ClTableauColumnsMap::const_iterator i = _columns.find(subject);
|
||||
return (i != _columns.end());
|
||||
}
|
||||
|
||||
const ClLinearExpression *RowExpression(ClVariable v) const
|
||||
{
|
||||
ClTableauRowsMap::const_iterator i = _rows.find(v);
|
||||
if (i != _rows.end())
|
||||
return (*i).second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClLinearExpression *RowExpression(ClVariable v)
|
||||
{
|
||||
const ClTableau *pthis = const_cast<const ClTableau *>(this);
|
||||
return const_cast<ClLinearExpression *>(pthis->RowExpression(v));
|
||||
}
|
||||
|
||||
|
||||
bool FIsBasicVar(ClVariable v)
|
||||
{ return RowExpression(v) != 0; }
|
||||
|
||||
// private: FIXGJB: can I improve the encapsulation?
|
||||
|
||||
// _columns is a mapping from variables which occur in expressions to the
|
||||
// set of basic variables whose expressions contain them
|
||||
// i.e., it's a mapping from variables in expressions (a column) to the
|
||||
// set of rows that contain them
|
||||
ClTableauColumnsMap _columns;
|
||||
|
||||
// _rows maps basic variables to the expressions for that row in the tableau
|
||||
ClTableauRowsMap _rows;
|
||||
|
||||
// the collection of basic variables that have infeasible rows
|
||||
// (used when reoptimizing)
|
||||
ClVarSet _infeasibleRows;
|
||||
|
||||
// the set of rows where the basic variable is external
|
||||
// this was added to the C++ version to reduce time in SetExternalVariables()
|
||||
ClVarSet _externalRows;
|
||||
|
||||
// the set of external variables which are parametric
|
||||
// this was added to the C++ version to reduce time in SetExternalVariables()
|
||||
ClVarSet _externalParametricVars;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClTypedefs.h
|
||||
|
||||
#ifndef CL_TYPEDEFS_H__
|
||||
#define CL_TYPEDEFS_H__
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include "ClLinearExpression_fwd.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
using std::set;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
|
||||
class ClVariable;
|
||||
class ClConstraint;
|
||||
class ClEditInfo;
|
||||
|
||||
typedef set<ClVariable> ClVarSet;
|
||||
typedef map<ClVariable, ClVarSet > ClTableauColumnsMap;
|
||||
typedef map<ClVariable, ClLinearExpression *> ClTableauRowsMap;
|
||||
|
||||
// For Solver
|
||||
typedef map<const ClConstraint *, ClVarSet> ClConstraintToVarSetMap;
|
||||
typedef map<const ClConstraint *, ClVariable> ClConstraintToVarMap;
|
||||
typedef map<ClVariable, const ClConstraint *> ClVarToConstraintMap;
|
||||
typedef vector<ClVariable> ClVarVector;
|
||||
|
||||
typedef set<const ClConstraint *> ClConstraintSet;
|
||||
|
||||
// For FDSolver
|
||||
typedef map<ClVariable, ClConstraintSet> ClVarToConstraintSetMap;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// ClVariable.h
|
||||
// A handle on ClAbstractVariable-s
|
||||
|
||||
#ifndef ClVariable_H
|
||||
#define ClVariable_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Cassowary.h"
|
||||
#include "ClFloatVariable.h"
|
||||
#include "ClFDVariable.h"
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
class ClVariable;
|
||||
typedef map<const string,ClVariable> StringToVarMap;
|
||||
|
||||
|
||||
class ClVariable {
|
||||
ClAbstractVariable *pclv;
|
||||
public:
|
||||
// converters from raw ClAbstractVariable
|
||||
ClVariable(ClAbstractVariable *pclv_) : pclv(pclv_) { }
|
||||
ClVariable(ClAbstractVariable &clv_) : pclv(&clv_) { }
|
||||
|
||||
// Copy ctr
|
||||
ClVariable(const ClVariable &clv_) : pclv(clv_.pclv) { }
|
||||
|
||||
/// These ctrs build ClFloatVariable-s
|
||||
ClVariable(string name, Number Value = 0.0)
|
||||
: pclv(new ClFloatVariable(name,Value))
|
||||
{ if (pmapStrPclv) { (*pmapStrPclv)[name] = *this; } }
|
||||
ClVariable(Number Value = 0.0)
|
||||
: pclv(new ClFloatVariable(Value)) { }
|
||||
ClVariable(long number, char *prefix, Number Value = 0.0)
|
||||
: pclv(new ClFloatVariable(number,prefix,Value)) { }
|
||||
|
||||
// This one builds a ClFDVariable
|
||||
ClVariable(ClFDVariable *pcfv)
|
||||
: pclv(pcfv)
|
||||
{ if (pmapStrPclv) { (*pmapStrPclv)[pcfv->Name()] = *this; } }
|
||||
|
||||
// Destructor
|
||||
virtual ~ClVariable() {};
|
||||
|
||||
/// permit ClVariables to be used as pointers to pclvs
|
||||
ClAbstractVariable *operator->() { return pclv; }
|
||||
const ClAbstractVariable *operator->() const { return pclv; }
|
||||
|
||||
/// and also forward the function calls along
|
||||
|
||||
|
||||
bool IsFloatVariable() const { assert(pclv); return pclv->IsFloatVariable(); }
|
||||
bool IsFDVariable() const { assert(pclv); return pclv->IsFDVariable(); }
|
||||
bool IsDummy() const { assert(pclv); return pclv->IsDummy(); }
|
||||
bool IsExternal() const { assert(pclv); return pclv->IsExternal(); }
|
||||
bool IsPivotable() const { assert(pclv); return pclv->IsPivotable(); }
|
||||
bool IsRestricted() const { assert(pclv); return pclv->IsRestricted(); }
|
||||
|
||||
string Name() const { assert(pclv); return pclv->Name(); }
|
||||
|
||||
Number Value() const { assert(pclv); return pclv->Value(); }
|
||||
int IntValue() const { assert(pclv); return pclv->IntValue(); }
|
||||
void SetValue(Number Value)
|
||||
{ assert(pclv); pclv->SetValue(Value); }
|
||||
void ChangeValue(Number Value)
|
||||
{ assert(pclv); pclv->ChangeValue(Value); }
|
||||
void SetPv(void *pv)
|
||||
{ assert(pclv); pclv->SetPv(pv); }
|
||||
void *Pv() const
|
||||
{ assert(pclv); return pclv->Pv(); }
|
||||
|
||||
void SetName(string const &nm) {
|
||||
assert(pclv);
|
||||
if (pmapStrPclv) {
|
||||
pmapStrPclv->erase(Name());
|
||||
(*pmapStrPclv)[nm] = *this;
|
||||
}
|
||||
pclv->SetName(nm);
|
||||
}
|
||||
|
||||
ClAbstractVariable *get_pclv() const { return pclv; }
|
||||
bool IsNil() const { return pclv == 0; }
|
||||
|
||||
virtual FDNumber DesiredValue() const
|
||||
{ assert(false); }
|
||||
|
||||
virtual list<FDNumber> *PlfdnDomain()
|
||||
{ assert(false); return 0; }
|
||||
|
||||
static void SetVarMap(StringToVarMap *pmap) { pmapStrPclv = pmap; }
|
||||
static StringToVarMap *VarMap() { return pmapStrPclv; }
|
||||
static StringToVarMap *pmapStrPclv;
|
||||
#ifndef CL_NO_IO
|
||||
ostream &PrintOn(ostream &xo) const
|
||||
{
|
||||
if (pclv) return pclv->PrintOn(xo); /* return xo << "@" << pclv << endl; */
|
||||
return xo << "clvNil";
|
||||
}
|
||||
#endif
|
||||
|
||||
friend bool operator<(ClVariable cl1, ClVariable cl2)
|
||||
{ return cl1.pclv < cl2.pclv; }
|
||||
|
||||
friend bool operator==(ClVariable cl1, ClVariable cl2)
|
||||
{ return cl1.pclv == cl2.pclv; }
|
||||
|
||||
friend bool operator!=(ClVariable cl1, ClVariable cl2)
|
||||
{ return !(cl1 == cl2); }
|
||||
|
||||
};
|
||||
|
||||
#ifndef CL_NO_IO
|
||||
inline ostream &operator<<(ostream &xo, const ClVariable &clv)
|
||||
{ return clv.PrintOn(xo); }
|
||||
#endif
|
||||
|
||||
#ifdef CL_USE_HASH_MAP_AND_SET
|
||||
struct hash<ClVariable> {
|
||||
size_t operator()(const ClVariable & v) const
|
||||
{ return size_t((unsigned long)v.get_pclv()/CL_PTR_HASH_DIVISOR); }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// Compare two double-s approximately, since equality is no good
|
||||
inline bool ClApprox(double a, double b)
|
||||
{
|
||||
const double epsilon = 1.0e-8;
|
||||
if (a > b) {
|
||||
return (a - b) < epsilon;
|
||||
} else {
|
||||
return (b - a) < epsilon;
|
||||
}
|
||||
}
|
||||
|
||||
// Can remove these if I decide to
|
||||
// autoconvert from ClVariable-s to double-s
|
||||
inline bool ClApprox(ClVariable clv, double b)
|
||||
{
|
||||
return ClApprox(clv->Value(),b);
|
||||
}
|
||||
|
||||
inline bool ClApprox(double a, ClVariable clv)
|
||||
{
|
||||
return ClApprox(a,clv->Value());
|
||||
}
|
||||
|
||||
extern ClVariable clvNil;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
// $Id$
|
||||
// See http://cseng.aw.com/bookdetail.qry?ISBN=0-201-63371-X&ptype=634
|
||||
// auto_ptr from More Effective C++ an earlier appendix (works w/ egcs)
|
||||
|
||||
|
||||
#ifndef CL_AUTO_PTR_H
|
||||
#define CL_AUTO_PTR_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <memory>
|
||||
template<class T>
|
||||
void ReinitializeAutoPtr(auto_ptr<T> &apref, T *pt)
|
||||
{
|
||||
auto_ptr<T> ap(pt);
|
||||
apref = ap;
|
||||
}
|
||||
#define cl_auto_ptr auto_ptr
|
||||
#else
|
||||
// FIXGJB: This implementation for egcs is buggy -- be careful
|
||||
// and replace ASAP
|
||||
template<class T>
|
||||
class cl_auto_ptr {
|
||||
public:
|
||||
explicit cl_auto_ptr(T *p = 0): pointee(p) {}
|
||||
|
||||
template<class U>
|
||||
cl_auto_ptr(cl_auto_ptr<U>& rhs): pointee(rhs.release()) {}
|
||||
|
||||
~cl_auto_ptr() { delete pointee; }
|
||||
|
||||
template<class U>
|
||||
cl_auto_ptr<T>& operator=(cl_auto_ptr<U>& rhs)
|
||||
{
|
||||
if (this != &rhs) reset(rhs.release());
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator*() const { return *pointee; }
|
||||
|
||||
T* operator->() const { return pointee; }
|
||||
|
||||
T* get() const { return pointee; }
|
||||
|
||||
T* release()
|
||||
{
|
||||
T *oldPointee = pointee;
|
||||
pointee = 0;
|
||||
return oldPointee;
|
||||
}
|
||||
|
||||
// protected:
|
||||
// This is non-standard
|
||||
void reset(T *p = 0) { delete pointee; pointee = p; }
|
||||
|
||||
private:
|
||||
T *pointee;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
void ReinitializeAutoPtr(cl_auto_ptr<T> &apref, T *pt)
|
||||
{
|
||||
apref.reset(pt);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
// $Id$
|
||||
//
|
||||
// Cassowary Incremental Constraint Solver
|
||||
// Original Smalltalk Implementation by Alan Borning
|
||||
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
|
||||
// http://www.cs.washington.edu/homes/gjb
|
||||
// (C) 1998, 1999 Greg J. Badros and Alan Borning
|
||||
// See ../LICENSE for legal details regarding this software
|
||||
//
|
||||
// debug.h
|
||||
|
||||
#ifndef CASSOWARY_DEBUG_H_
|
||||
#define CASSOWARY_DEBUG_H_
|
||||
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
|
||||
#include <cassowary/config-inline.h>
|
||||
#define CONFIG_INLINE_H_INCLUDED
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include "Cassowary.h"
|
||||
|
||||
#ifdef CL_TRACE
|
||||
class Tracer {
|
||||
public:
|
||||
Tracer(const char *const sz) : sz_(sz) { cerr << "* " << sz; }
|
||||
~Tracer() { cerr << "x " << sz_ << " exited." << endl; }
|
||||
private:
|
||||
const char *const sz_;
|
||||
};
|
||||
|
||||
inline void CtrTracer(const char *const sz, const void *pv)
|
||||
{ cerr << "@+ " << sz << " ctrnew@ " << pv << endl; }
|
||||
|
||||
inline void DtrTracer(const char *const sz, const void *pv)
|
||||
{ cerr << "@- " << sz << " dtrnew@ " << pv << endl; }
|
||||
|
||||
#else
|
||||
class Tracer {
|
||||
public:
|
||||
Tracer(const char *const) { }
|
||||
};
|
||||
|
||||
inline void CtrTracer(const char *const, const void *) { }
|
||||
inline void DtrTracer(const char *const, const void *) { }
|
||||
#endif // CL_TRACE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
/* $Id$ */
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
// Programmer: John P. Russo
|
||||
// --------------------------
|
||||
// John Russo has given permission to any of my students to use his
|
||||
// "timer" class.
|
||||
//
|
||||
// Please give full credit to him any time you wish to use this class.
|
||||
// Hossein Hakimzadeh 11/5/96
|
||||
|
||||
/************************** timer.cpp **********************************
|
||||
|
||||
A simple example that shows how C++ classes can be used to implement
|
||||
a "Timer" object, which mimics the familiar actions of a stopwatch.
|
||||
|
||||
The code relies heavily on the clock() function defined in the time
|
||||
library. The clock() function returns the number of "ticks" that have
|
||||
elapsed since a program starts. The size of a "tick" is compiler
|
||||
dependent, but for PC compilers is about 1/18 second.
|
||||
|
||||
The problem with the clock function is that it is not convenient to
|
||||
use for typical timing operations. The timer class, defined below, by
|
||||
contrast, shows that an object-oriented approach to modules can
|
||||
provide tools that are natural and easy to use.
|
||||
|
||||
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
||||
#include <time.h>
|
||||
|
||||
class Timer
|
||||
{
|
||||
//==================== public section ================================
|
||||
|
||||
// The functions and/or data in the public section of a class are
|
||||
// accessible to anyone who uses the Timer class.
|
||||
|
||||
public:
|
||||
Timer(); // Constructor, used to declare Timer objects
|
||||
void Start(); // Starts a timer object
|
||||
void Stop(); // Stop a timer object
|
||||
void Reset(); // Reset timer object
|
||||
int IsRunning(); // Is the timer object running?
|
||||
double ElapsedTime(); // How much time has been recorded?
|
||||
double Resolution(); // Shortest measurable amount of time
|
||||
|
||||
//-------------------- private section -------------------------------
|
||||
|
||||
// The functions and/or data in the private section of a class are NOT
|
||||
// accessible to those who use the Timer class. They are accessible by
|
||||
// member functions of the class. This allows access to the data to be
|
||||
// carefully controlled.
|
||||
|
||||
private:
|
||||
long StartReading; // Number of ticks when timer object last started.
|
||||
long ElapsedTicks; // Number of ticks on timer object.
|
||||
int TimerIsRunning; // 1 if and only if timer object is running.
|
||||
double TicksPerSecond() // This inline function is used to convert
|
||||
// {return 18.206481;} // "ticks" (returned by clock() ) to seconds.
|
||||
{return CLOCKS_PER_SEC;} // "ticks" (returned by clock() ) to seconds.
|
||||
// In most UNIX systems this is 1000000
|
||||
};
|
||||
|
||||
/**************************** Start ************************************
|
||||
|
||||
If the declaration "Timer StopWatch;" has been made, the the call,
|
||||
"StopWatch.Start();" is like push the start button of a real stopwatch.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
void Timer::Start()
|
||||
{
|
||||
TimerIsRunning = 1; // Stopwatch is now running
|
||||
StartReading = clock(); // Look at internal clock and remember reading
|
||||
}
|
||||
|
||||
/**************************** Stop ************************************
|
||||
|
||||
Looks at the PC's internal clock and computes the number of ticks that
|
||||
have elapsed since the timer was started.
|
||||
|
||||
Note that if a timer is not reset, it can be used to time several events
|
||||
and return the elapsed time for the enter set of events.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
void Timer::Stop()
|
||||
{
|
||||
TimerIsRunning = 0; // Stop timer object.
|
||||
ElapsedTicks += clock() - StartReading; // Add elapsed time to the
|
||||
} // previous time.
|
||||
|
||||
/**************************** Reset ************************************
|
||||
|
||||
Clears a Timer of previous elapsed times, so that a new event can be
|
||||
timed.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
void Timer::Reset()
|
||||
{
|
||||
TimerIsRunning = 0; // Start not yet called.
|
||||
ElapsedTicks = 0; // No time on timer object yet.
|
||||
}
|
||||
|
||||
/************************** IsRunning ************************************
|
||||
|
||||
The data member, "TimerIsRunning" is used to keep track of whether a
|
||||
timer is active, i.e. whether an event is being timed. While we want
|
||||
those using the timer class to know when a timer is active, we do NOT
|
||||
want them to directly access the TimerIsRunning variable. We solve this
|
||||
problem, by making TimerIsRunning private and providing the public
|
||||
"access function" below.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
int Timer::IsRunning()
|
||||
{
|
||||
return TimerIsRunning;
|
||||
}
|
||||
|
||||
/************************* ElapsedTime ***********************************
|
||||
|
||||
This function allows a client to determine the amount of time that has
|
||||
elapsed on a timer object. Note that there are two possibilities:
|
||||
|
||||
1) A timer object has been started and stopped. We can detect this
|
||||
case, because the variable "TimerIsRunning" is false.
|
||||
|
||||
2) A timer object is "running", i.e. is still in the process of timing
|
||||
an event. It is not expected that this case will occur as frequently
|
||||
as case 1).
|
||||
|
||||
In either case, this function converts ticks to seconds. Note that
|
||||
since the function TicksPerSecond() returns a value of type double,
|
||||
an implicit type conversion takes place before doing the division
|
||||
required in either case.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
double Timer::ElapsedTime()
|
||||
{
|
||||
if ( !TimerIsRunning ) // Normal case
|
||||
return ElapsedTicks/TicksPerSecond();
|
||||
|
||||
else
|
||||
return (ElapsedTicks + clock() - StartReading)/TicksPerSecond();
|
||||
}
|
||||
|
||||
/************************** Resolution ***********************************
|
||||
|
||||
Althould we have no way of knowing how accurate the internal clock is,
|
||||
we can predict its resolution, which is the shortest event that can be
|
||||
measured by the clock.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
double Timer::Resolution()
|
||||
{
|
||||
return 1/TicksPerSecond(); // Note 1 is coverted to 1.0 before division
|
||||
}
|
||||
|
||||
/******************** Timer (constructor) *******************************
|
||||
|
||||
A "constructor" is a special class member function, one which has the
|
||||
same name as the class. The "default constructor" is a constructor that
|
||||
has no parameters. A constructor is called automatically when an
|
||||
instance of a class is declared. For example, the constructor defined
|
||||
below is called when the declaration "Timer T;" is executed.
|
||||
|
||||
If the programmer does not write a default constructor, then the
|
||||
compiler will generate one automatically. However, by writing the
|
||||
constructor below, we provide automatic initialization of timer objects.
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
|
||||
Timer::Timer()
|
||||
{
|
||||
TimerIsRunning = 0; // Start not yet called.
|
||||
ElapsedTicks = 0; // No time on timer object yet.
|
||||
}
|
||||
|
||||
#endif /* _TIMER_H_ */
|
||||
|
|
@ -1087,7 +1087,7 @@ sf_command (SNDFILE *sndfile, int command, void *data, int datasize)
|
|||
broadcast_info_copy (psf->broadcast_info, data) ;
|
||||
broadcast_add_coding_history (psf->broadcast_info, psf->sf.channels, psf->sf.samplerate) ;
|
||||
|
||||
if (psf->write_header)
|
||||
if (psf->auto_header && psf->write_header)
|
||||
psf->write_header (psf, SF_TRUE) ;
|
||||
return SF_TRUE ;
|
||||
|
||||
|
|
@ -1210,7 +1210,7 @@ sf_seek (SNDFILE *sndfile, sf_count_t offset, int whence)
|
|||
if (psf->error)
|
||||
return PSF_SEEK_ERROR ;
|
||||
|
||||
#ifdef ECDL_ORIGINAL#
|
||||
#ifdef ECDL_ORIGINAL
|
||||
if (seek_from_start < 0 || seek_from_start > psf->sf.frames)
|
||||
{ psf->error = SFE_BAD_SEEK ;
|
||||
return PSF_SEEK_ERROR ;
|
||||
|
|
|
|||
BIN
tools/osx_packaging/Ardour2.icns
Normal file
BIN
tools/osx_packaging/Ardour2.icns
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue