merging trunk

git-svn-id: svn://localhost/ardour2/branches/undo@652 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Hans Fugal 2006-06-29 14:19:37 +00:00
parent 7ff370e798
commit 7968974c01
116 changed files with 735 additions and 12963 deletions

View file

@ -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()

View file

@ -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 ""

View file

@ -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."

View file

@ -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."

View file

@ -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."

View file

@ -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"

View file

@ -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."

View file

@ -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"

View file

@ -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."

View file

@ -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']:

View file

@ -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:

View file

@ -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 */

View file

@ -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 ();

View file

@ -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 ();

View file

@ -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);
}

View file

@ -20,7 +20,7 @@
#include <algorithm>
#include <stdlib.h>
#include <cstdlib>
#include <sigc++/bind.h>

View file

@ -94,14 +94,6 @@ AudioTrack::~AudioTrack ()
}
}
#if 0
void
AudioTrack::handle_smpte_offset_change ()
{
diskstream
}
#endif
int
AudioTrack::deprecated_use_diskstream_connections ()
{

View file

@ -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;
}

View file

@ -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;

View file

@ -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 ""

View file

@ -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 ""

View file

@ -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 ""

View file

@ -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
{

View file

@ -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

View file

@ -1,3 +0,0 @@
ClReader-lex.cc
ClReader.cc
ClReader.cc.h

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>
*/

View file

@ -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();
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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>;

View file

@ -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"); }

View file

@ -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 = &xi;
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

View file

@ -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

View file

@ -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); }

View file

@ -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)
{
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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));

View file

@ -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/

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1 +0,0 @@

View file

@ -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

View file

@ -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_ */

View file

@ -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 ;

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more