Release Notes

Twoocon version 0.9

Austen Clark

Department of Philosophy, University of Connecticut

January 2005

"Twoocon" is the CONsole version of TWOOtie 2, a truth tree program in symbolic logic. The source code is available (on my website and perhaps elsewhere) for distribution and use under the terms of the GNU general public license. It will compile and run in both Windows and Linux.

Twoocon implements most of the essential commands of Twootie 2 but in a command line style. It has the full inference engine of Twootie 2 (a variant of a resolution theorem prover) for predicate logic with identity, and it uses that engine to solve arbitrary problems in predicate and sentential logic. The point of the release is to make that inference engine available, and thereby, I hope, to stimulate interest among open-source programmers in (a) improving the engine, and (b) eventually developing a GUI version of Twootie that would run in both Windows and Linux. The program is therefore released in a fashion that is likely to appeal mostly to programmers or instructors; it is set up to make it relatively easy to explore big trees, and to reveal internals of the data structures on command. In its current state it is not suited for instructional use by novices, though it may appeal to advanced students.

0. Files in the distribution. Installing and running.

The executable (in Windows) is "twoocon.exe". In Linux it has no extension, and is just "twoocon". The *.two files are text files that contain the problems you can load with the load command. They are: bigprobs.two, ifprobs.two, q.two, plprobs.two, and slprobs.two. Readme.txt has information for programmers. Readme.htm is an html version of the same readme file. The separate source code distribution includes in addition nine files with a *.pas extension, and one file called "twoocon.dpr", which is where the main routine is found.

To install the program: Unzip all the files into whatever directory you like. Open up a DOS window (also known as "command prompt" or "terminal" or "console"). Change (CD) into that directory. Type "twoocon" and press Enter. In Linux you will need to type "./twoocon" (unless you have altered your PATH).

If you get a run-away tree, control-C will usually terminate the program. If your keyboard has a "Break" key, usually control + that Break key will also do the same.

1. Current compilers

1.1 Windows

On Windows the source code will compile and run using Borland's Delphi, version 6. Probably other versions of Delphi will work as well, though they have not been tested. Delphi (and Kylix) use a language that Borland calls "Object Pascal", derived from Turbo Pascal, but with numerous extensions.

1.2 Linux

On Linux the source code will compile and run using Borland's Kylix, version 3. Borland has released an "open edition" of Kylix 3, available for free from the Borland website. To download a copy, a link that may or may not work is:

If it fails, a search for "Borland Kylix" will likely produce a current link.

1.3 DOS

Near the end of developing this release I also discovered that the code will compile and run using Borland's Turbo Pascal version 5.5, running in a Dos window in Windows. While this development environment is not as sophisticated as current ones, it has the great advantage of also being available for free. Borland distributes Turbo Pascal 5.5 for free on its website as "antique" software. A link that may or may not work is:,1410,20803,00.html

If it fails, search for "Turbo Pascal 5.5" or (the name of the file) "".

The great advantage of the Delphi/Kylix combination is that both products support a component library for cross platform development of GUI applications, which Borland calls "CLX". A GUI version of Twootie developed with CLX on Kylix will also compile and run in Windows, and vice-versa. Both Kylix and Delphi are also "visual" programming environments, similar to "Visual Basic", but far superior in supporting true object-oriented programming. Borland calls the underlying language "Object Pascal"; it is a descendant of Turbo Pascal 5.5, with OOP extensions.

When I discovered that Twoocon 0.9 will compile and run in Turbo Pascal 5.5, I decided to release it initially in a form that uses none of the Delphi/Kylix extensions. This will make it available to the largest possible population of potential programmers. It also explains some of the features of the current release.

2. Features of this release

2.1 No memory checking.

This is the main reason it is called version "0.9": with infinite trees the program will eventually cause a runtime error and terminate. It allocates memory using "New()" and "Dispose()", does not check for the availability of free memory before calling "New()", does not trap errors, and does not clean up after itself at all.

From a programming point of view this isn't such a problem: there is a lengthy pause when the program tries to solve an infinite tree, and a control-C in Windows or Linux usually terminates things nicely. (In Linux different keys might be used, depending on the shell.) But it is not fit for novice use.

The problem is that Delphi, Kylix, and Turbo Pascal 5.5 all implement memory checking in different ways. And the problem may be finessed by using language features available only in Object Pascal (cutting off the Turbo branch). But that's why it seemed to make sense to release it as is.

2.2 Standard input and output

That is, "readln" and "writeln". A "console" application can use these, but once the code is wrapped in a GUI these are no longer available.

Use of "readln" and "writeln" is (mostly) confined in the code to the modules "initial.pas" "printit.pas" and "commands.pas". No such use is essential to the modules "parser.pas", "decompos.pas", "adddata.pas", "readdata.pas" or "picker.pas", where the real work of the program is done.

2.3 No use of Object Pascal extensions

The simplest way to deal with memory management will be to use the new construct Borland calls "dynamic arrays", which do most of the needed memory management without relying on "New()" or "Dispose()". Another tempting new feature of Object Pascal is exception handling, which would help clean up the error handling in the source code considerably. But for now the code uses no such extensions, and no object-oriented extensions either.

3. Notes to programmers

3.1 Some useful commands

The program defaults to "trace" OFF, so that when the inference engine generates decomposition products they are not displayed. If you type "uncle" the program silently completes the tree and simply tells you whether it is open or closed (with a few additional details). If you are going to try a tree that might be infinite, it is wise to turn trace ON.

An even wordier output is possible if you turn "debugging" on. The inference engine then issues reports of its activities at each resolution. (There are internal switches available for other levels of report, including "warning" and "flagerrors", but those are not accessible from commands.)

"Show" presents data on the status of the current branch, and allows display of the internal data structures if you want it. "leaf <n>" is useful for making the leaf whose sequence number is <n> the current branch.

Commands.dispatchcommand is the source from whence commands are actually called.

3.2 A few conditional compiler directives (pragmas)

No editing of the source code is needed to compile it either in Delphi or Kylix, but there are three places where it uses "conditional directives" to compile different bits of source code in the different operating systems. If you are working in Kylix the symbol "Linux" is automatically defined; in Windows the symbol "MSWindows" is automatically defined. The code uses {$ifdef Linux} or {$ifdef MSWindows} directives in three places.

First, in printit.printsymbol, the code will make use of the Linux capability to use unicode in order to display the logic symbols correctly. In Linux the program will display the upside down "A", the backwards "E", the horseshoe, etc even in a console program. In Windows it uses characters in the upper ascii 128.

Second, in initial.setdefaults, the code will use different characters for the "checkmark" symbol. In Windows a square root sign, ascii 251, looks the most like a checkmark. In Linux it just uses an asterisk.

Third, in commands.dispatchcommand, there is slightly different code called when the user issues the "memory" command. This reports on how much memory is used or free, and as noted differs slightly across the three compilers.

3.3 Edits needed to compile in Turbo Pascal 5.5

The same three places mentioned in 3.2 also have conditional directives defined as {$ifdef Turbo55}. These are meant for programmers using the Turbo Pascal 5.5 compiler. You must define the symbol "Turbo55" for the correct code to compile in those three places. (To "define the symbol" you can either add a "Conditional define" in "Compiler | Options", or add the line {$define Turbo55} at the very beginning of the source code.

There are a few other edits needed to get the source code to compile in Turbo 5.5. For this release there is a separate distribution package with these edits already made (the filename is ""), but for future reference here is a list.

First, in Delphi and Kylix the main program is stored in a file with a "dpr" extension (for delphi project resource). So "twoocon.dpr" needs to be saved as "twoocon.pas".

Second, in twoocon.pas the {$APPTYPE CONSOLE} directive will not be understood by Turbo 5.5, and should be deleted. Also, there is no "Sysutils" unit in Turbo 5.5, so the first line in the "uses" clause in twoocon.pas should be edited to read "uses Dos, Crt" instead of "uses Sysutils".

Finally, the editor in the Turbo 5.5 environment will not support files larger than 64k, so the code in commands.pas, picker.pas, adddata.pas, and readdata.pas must be split in each case in two: a main file and an "include" file. It also truncates lines over a certain length (which is not an issue in the code just released, but may become so someday.)

3.4 Some limits to Turbo Pascal 5.5

With those edits made, the program will compile successfully in Turbo Pascal 5.5. It should be noted that that compiler is indeed somewhat old, if not antique; and it constrains development in various ways. One is that it uses DOS-like memory models, so confines the workspace to much smaller regions than are now available in Delphi or Kylix. (For example, load "identity" problems and try #5. Turn "trace" on first. Turbo fills memory after about 1200 sentences and exits with a runtime error. In Delphi the same problem happily creates 6000 sentences before slowing down, and even then I don't know how many it will create before filling memory.) Delphi and Kylix versions will both request more memory as needed from the operating system, and these days they could easily employ megabytes worth. Whereas Turbo was struggling with the 640k limit and 16 bit segments.

More memory space is one of the attractions of working on the inference engine in Windows or Linux. I have already come across trees that have 41 branch points in one branch. 2^41 is a lot of sentences!

Second, the Turbo version is just a pure DOS program, and it performs rather awkwardly in a Windows environment. Control-C for example does *not* terminate a run-away tree. Scrolling up or down in the console buffer does not work.

Finally, of course, once any of the Object Pascal extensions are used or the first GUI version comes out, Turbo 5.5 will no longer work. I'd urge you to explore the Linux/Kylix combination, or Delphi (if you can afford it).

3.5 Code that is commented-out

Some code is rendered inactive by placing it within comment delimiters ("{" and "}") while other parts are put within a conditional directive {$ifdef oldcode} ...{endif}. Almost all of these portions reflect code that will be needed in final versions of twoocon, but which is not needed in a console version. For example, in the console version the program can at best list the sentences in the current branch; it is operating in what Twootie 2 called "stack" (or "compressed") display mode. Parts of the code that handle "uncompressed" output to the screen might be present, but commented out. If the first comment delimiter reads "{CLX:" then it was definitely used in Twootie 2, and will be needed in a final GUI CLX version, but is not needed in the console version.

The {$ifdef oldcode} construct is a simple way to comment out bigger blocks which also include comments. It too reflects program logic that will eventually need to be reconstructed.A few routines that are present in the source code have a similar status to these smaller blocks: they are not used in the console version, but may be useful for the final version.

4.0 Some development goals

4.1 Get smarter about identities

The unification algorithms in the inference engine were designed before identity decomposition was added to the program, so they do a very poor job of pruning the tree when there are identity statements around. This is the biggest single limit on its capabilities.

4.2 Become less rigid about priorities

The key to a smart inference engine is picking which sentence to develop next. Most of the effort here went into careful selection of instantiating constants when completing proofs in predicate logic. Once we get down to literals (or just sentence letters) the approach is more brute-force: the program will always pick a sentence that can be checked off and does not branch over any sentence that will branch. If the sentence will branch, it always picks one that can be checked off over any universal sentence (which can't be checked). If it is choosing among sentences that all branch but can all be checked off, it always picks the longest one. The result is less than optimal in some of the "bigprobs" that involve only literals (see 1-5).

4.3 Implement some pruning commands

As it stands the program provides a useful "calculator" for telling whether a truth tree problem is open or closed, and how large its solution will be. This can be useful for instructors designing tests or problem sets. A few new commands could make it even more useful. For example, it would be handy to be able to edit the set of primary assumptions after a verdict is returned, so that the problem can be made to work as desired, with the size needed. That is, after a tree is completed, an instructor could "delete" everything except the primary assumptions, then "remove" some, "edit" others, and add some as needed. Then run the problem again and get a new verdict. In the end, "save" the set of primaries into a text file.

4.4 Display results graphically

This will be the first step in implementing a GUI version: produce a graphical display of a completed tree. As noted in the code, an almost universal preference is to use a fixed width font to display logic sentences, and if that preference is respected, the algorithms in Twootie 2 "redrawer" will still work. They simply need to be converted from a character-based metric to a pixel-based metric. That is, instead of treating the screen as an array that is (say) 80 characters wide and 25 rows deep, it is treated as an array of (say) 800 pixels across and 600 down. If each character "box" is 10 pixels wide and 24 high, the old character-based calculations still yield results that will work perfectly well with pixels. Instead of using the old GoTOXY(where x and y were character rows and columns), we will use the new MoveToXY(x: pixel, y:pixel), and then "paint" a character starting at that location.

One fun part is the CLX allows for a "canvas" that is bigger than an available screen, so large trees could be pictured. One can also use differently sized fonts, or resize the entire canvas, creating various display options. Bitmaps can be copied and cut to the clipboard.

5.0 Notes on prior versions

5.1 Twootie 2

Twootie 2 was developed in MS-DOS in the mid to late 1980's, starting with Turbo Pascal 3.0, moving briefly to Oregon Pascal, and then back to Turbo 4.0, 5.0, and (finally) 5.5. Twootie 2.0 also used a proprietary library of routines developed and sold by Turbopower Software, of Scotts Valley CA, for the menus, screen handling, and help system. Twootie 2 was distributed with various logic textbooks in the 1990's, including "The Logic Book", by Merrie Bergmann, James Moor, and Jack Nelson, 2nd and 3rd editions, published by Random House and by McGraw Hill; with "Formal Logic: Its Scope and Limits" by Richard Jeffrey, published by McGraw Hill; and with "A Modern Formal Logic Primer" by Paul Teller, published by Prentice Hall.)

5.2 TwootCLX

In 2002 source code for both Twootie 2.1 and Bertie3 was released under terms of the GNU GPL. A version of the Twootie source code called "TwootCLX" was released that compiles in both Delphi and Kylix, but does not run. To do this, all the calls to the library from Turbopower software which handled the menus, help system, and screen were replaced with "stubs" which simply returned without doing anything. Nevertheless, it can be handy to look at the code for Twootclx, to see what a routine did in Twootie 2, or which routines it called. As long as the code compiles, finding and cross referencing the routines is very easy in Delphi or Kylix. Twootclx source code is available on my web site.

5.3 Routines that will be useful from TwootCLX

If we stick with dynamic data structures the routines in cleanup.pas did most of the disposing of records and nodes.

The algorithms for drawing and redrawing a tree neatly were found in placer,pas, pusher.pas, and redrawer.pas. The routines that called these (including "placedevelopees") are still found in the source code, though with all the "noncompressed" display mode logic commented out or deleted.

Created January 2005. Other links:

The Bertie/Twootie homepage.

The source code page.

Austen Clark's homepage.

The Philosophy Department homepage.