LPARSE VERSION HISTORY

0.99.59 (15.10.2000)
	An earlier fix had broken rules of the form:

	   1 { foo(X,Y) : bar(X) } 1 :- baz(Y).

	Additionally, there was still one problem with symbolic
	functions that resulted in some programs having a pretty
	strange behavior.

0.99.58 (14.9.2000)
	Expressions in constraint and weight literals now work more
	intuitively. For example, rules like:

	  a(X,Y) :- 1 { X + Y == 0, Y < X } 1,
	           foo(X,Y).

        work now as expected. (That is, in this case a(X,Y) is true
        when precisely one of the conditions hold. 

	An empty condition is now everywhere considered to be an
	unsatisfied literal. This is because the older behavior would
	sometimes cause unintuitive behavior.

	Few other bugs were fixed. First, isolated variables in rule
	bodies caused segmentation faults. (as in: a :- X.) This was
	fixed by disallowing them altogether. Second, lparse didn't
	realize when a constant in a range definition was actually a
	symbolic constant. Third, lparse would sometimes crash if
	there were too many variables inside a constraint literal.

0.99.57 (18.8.2000)
	Lparse now (again) supports classical negation. The rules with
	classical negations are transformed into rules without them. A
	classical negation of an atom foo(X) is denoted with:

		  -foo(X).

	Note that there may be no space between the minus sign and the
	atom name. Correspondingly, expressions where `-' denotes the
	arithmetic minus function have to be written with a space if
	it is followed by something that looks like an atom:

		  1 - bar.

	For each classically negated atom -a that appears in the
	grounded program, a rule of the form:

		 :- a, -a. 

	is added to the program. This behavior is enabled with the
	command line switch `--true-negation'.

	You may now write two-part command line arguments without a
	space between the parts. For example, 

	         lparse -Wall -dnone foo.lp
		 
	is now a valid command line. 

	There was a bug that caused the lower bound in rules of the
	form:

	  1 [ foo(X) : bar(X) = X ] 4.

	to be counted incorrectly. 
	  	
	Also, there were a few cases where negative weights would
	cause problems in the output. The rules were grounded
	correctly but the output routine sometimes printed out weights
	with wrong signs. 

	There was also a minor glich with warnings that caused wrong
	alarms when using the `-W arity' switch. 

0.99.56 (31.7.2000)
	There were a few nasty bugs in the code that handled negative
	weights that caused invalid code to be emitted sometime.
	Smodels would then die trying to read it. 

	Another bug that was found and fixed was that the results
	could change if the program was put through lparse more than
	once. For example, the following command line could cause
	problems:

	   lparse -t foo.lp | lparse | smodels 
	

0.99.55 (26.6.2000)
	Lparse should now compile well under Windows with Borland C++
	version 5.5. It may also work with other compilers but they
	are not tested. The dynamical linking of user-defined
	functions does not work well, and for now they should be
	linked statically to lparse binaries. (For example, by writing
	the code of the functions directly to the end of `library.cc'
	and by adding corresponding `function_table->Register' calls
	in the beginning of the file). 

	It is now possible to use variables in bounds for constraint
	and weight rules. For example:

	  foo :- X { bar, baz }, bound(X). 

	The syntax of optimize statements was made to be consistent
	with constraint and weight rules. Now, if you want to use
	weights in optimize statements, use square brackets.

	  minimize { a, b, c }. % all literals weight 1
	  minimize [ a=2, b=3, c ]. % the literal c may use global
                         	    % weight declaration

        It is now also possible to define the weight of a literal
        in terms of another literal:

	  weight a(X) = b(X). 

	defines a(X) to have the weight that the literal b(X) would
	have at the point. 

	Arity restrictions are now kind of back. You may still have as
	many arguments as you want in predicates but functions are now
	limited to 64 arguments. 
			   
        Three old bugs were also fixed:
        
        Lparse tried to used $HOME environmental variable even when no
	user-defined functions were needed causing problems when the
	variable was not initialized. 

	Weight rules of the form
	   a :- [ foo, bar ] 3.
        behaved incorrectly sometimes. 

	Also, ranges didn't work correctly if they were started from a
        negative number.

lparse-0.99.54 (22.5.2000)
	All declarations now allow more than one literal in the
	declaration. For example, the following lines are now legal
	declarations:

	    hide a(X), b(X), c(X).
            weight a(X) = X, a(b) = 10.
            external a(X), b(X). 

	In addition, a new declaration was added, namely, the show
	declaration:

            show a(X). 

        A show declaration is the opposite of a hide declaration as it
        marks that a predicate should be shown always. By default, all
        predicates are shown but an empty hide declaration of the
        form: 

	    hide .

	states that only predicates that are explicitly shown are
	printed. 

	There is now one more experimental command line argument to be
	used when grounding a program in two stages. The argument
	
	--atom-file file-name
	
	states that the names of the atoms in the program should be
	diverted to the file `file-name'. For example, given a
	program foo.lp:

	    a(X) :- b(X), not c(X).
	    c(X) :- b(X), not a(X).
	    b(1). 
	    compute { not c(1) }.

	and the lparse command line

	    lparse --atom-file foo foo.lp

	the output in stdout is 

	    1 1 1 1 2  
	    1 3 0 0 
	    1 2 1 1 1  
	    1 4 2 1 4 1 
	
	that is the smodels internal representation for the grounded
	rules and the file foo contains:

	    1 c(1)
	    2 a(1)
	    3 b(1)

	Unfortunately, it is not enough that you just catenate the two
	outputs together and send them to smodels but you have to add
	some glue to it. There will be some nice method to do this
	with time but for now the missing parts have to be added by
	hand. 

	Note that there are four rules in the program instead of the
	normal three. The final rule is generated for the compute
	statement and it is of the form

           _cant_be_true :- not _cant_be_true, c(1). 

        In effect, the rule states that there is a contradiction if
        not c(1) is false and c(1) is true. 

	There was a nasty bug that caused a segmentation fault
	sometimes when functions were used as arguments inside
	conditions. The constructs of the form:

            1 { foo(X) : bar(X) : baz(X+1) }

	were affected. 

	Lparse should now work faster when reading large programs. 

lparse-0.99.53
	A logic program can now be grounded in two stages. To make
	this property useful I defined a new class of domain
	predicates, that is, external predicates. In the first stage,
	the external predicates are used to generate the Herbrand
	instantiation of the program but they are not included in
	facts in the program. In the next stage, the extensions of the
	external atoms are combined to the program that was generated
	in the first stage. Intuitively, in the first stage we tell
	what atoms are possibly true and in the next stage we tell
	what atoms are actually true. 

	For example, the program:

	    external a(X).
	    a(1..2).
	    b(X) :- a(X).

	is first grounded to:

	    b(1) :- a(1).
	    b(2) :- a(2).

	In the next stage the user gives the domain for a.

	Suppose that the first program is stored in a file foo.lp and
	bar.lp contains only the fact a(1). Then, the following
	command sequence calculates the models for the combined
	program:

	    % lparse foo.lp > tmp_out
	    % lparse -g tmp_out bar.lp | smodels 
            smodels version 2.25. Reading...done
            Answer: 1
	    Stable Model: b(1) a(1) 
	    True

        This feature is useful when the grounding of a program takes a
        lot of time and there are many similar queries for the
        program. 

	The '-g' option is used to tell lparse that the following file
	is already grounded. It is possible to use more than one
	grounded file but you have to be certain that both have
	exactly the same set of atoms and in exactly same order.
	Lparse notices some of these errors but not all.

	Note that lparse doesn't try to reconstruct a grounded program
	in any way. For example, adding an atom a(3) to bar.lp in the
	example above doesn't add the atom b(3) to the model. 

	This feature is still quite experimental and its behavior may
	possibly change in the future. Also, there are probably bugs
	left in the code.

	There was a bug that caused conditions to work incorrectly
	sometimes when they were used in tails of domain predicates.
	In particular, the construct:

           foo(X) :- bar(X), never_satisfied(X, Y) : domain(Y). 


lparse-0.99.52 (7.4.00)
	Minor problem with output when using --partial. 

lparse-0.99.51 (6.4.00)
	Modified the behavior of --dlp and -r switches. Added a switch
	--partial that behaves in the sameway as -r. 

	A bug caused constraints of the form

               :- body.

        to fail to work correctly if option '-d none' was used and
        there were only domain predicates in the body. 

	Another bug caused problems with rules like:

	{ a(X), b(X+1) } :foo (X). 

lparse-0.99.50 (25.3.00)
	Lparse didn't always handle conditions correctly in weight
	rules. In particular, rules of the form

             1 [ foo(X) : bar(X, W) = W ] 2

	didn't work. Sometimes the results were plain wrong and
	sometimes lparse crashed. 

lparse-0.99.49 (1.3.00)
	Lparse mangled compute statements when smodels 1.x output was
	used.

lparse-0.99.48 (22.2.00)
	There was a little bug introduced in 0.99.46 that caused some
	rules to be left out of the program even with '-d all' option.

	Fixed a bug that messed with optimize statements when atoms of
	the form a("something-quoted") were used. 

lparse-0.99.47 (3.2.00)
	Added a simple API that allows the user-defined functions to
	access symbolic constants. The details are in the manual.

	Fixed a bug that once again caused internal errors sometimes
	when nested symbolic functions were used. 

lparse-0.99.46 (21.1.00)
	Updated the "-d all" switch to include ground rules for domain
	predicates as well as the facts.

lparse-0.99.45 (18.1.00)
	There was a bug that range definitions did not always notice
	differencies between symbolic and numeric constants.

lparse-0.99.44 (14.1.00)
	Lparse now handles correctly the cases where there are more
	than one relational operator in the row. However, you may use
	only one operator in the expression.

	There was a bug with '-d all' option that sometimes caused
	incorrect atoms to be added to the model. 

lparse-0.99.43 (5.1.00)
	Changed the modulo function to work with normal mathematical
	semantics instead of C programming language semantics (that
	is, the modulo is now always positive).
	
	Also, noticed the bug that functions of the form

	      A < B < C
	      
	do not work correctly. This will be fixed in next release,
	meanwhile the construct

	     lt(A,B,C)

	works. 

lparse-0.99.42 (4.1.00)
	Lparse messed up the symbolic functions in the rule tails if
	the nesting depth was too large. This version fixes it and
	additionally allows now assignments in the rule bodies to be
	in any order (as long as there are no cycles).

	There was also a bug that messed up conditions that were too
	deep.
	
	Finally, a literal with symbolic functions was sometimes
	dropped from compute and optimize statements. 

lparse-0.99.41 (30.11.99)
	If a function was used in a extended rule tail, lparse could
	mess up the dependency graph of the program. 

lparse-0.99.40 (12.11.99)
	A typo on yesterday's fix broke the conditions from working
	within choice rule heads. 

lparse-0.99.39 (11.11.99)
        There was a missing 'break' in a switch statement that crashed
        the program sometimes when there were more than one function
        argument in a literal. 

	If all literals in a constraint or weight rule had functions
	with global arguments, the lparse dropped the rule from the
	output.

lparse-0.99.38 (5.11.99)
        There was a bug that caused a numerical constant to be treated
        as a normal constant when they appeared as sole arguments. 

lparse-0.99.37 
	Fixed a bug where lparse didn't count the number of
	domain predicates in a rule correctly which confused smodels.

	Added a new command-line option:
	 --dlp  
	  Use disjunctive logic program semantics for separator '|',
	  ie translate rule of the form
               a1 | ... | an :- foo
          into 
              { a1, ..., an } :- foo
          instead of
              1 { a1, ..., an } 1 :- foo

lparse-0.99.36 (13.10.1999)
	Fixed an error where an assertion failed when printing an
	error message. 

lparse-0.99.35 (12.10.1999)
	There was a bug in range restriction checking code that failed
	with constructions like:
	     
	     1 { foo(bar(X,Y)) : domain(X,Y) } :- ... .

	Another bug in the grounding code caused lparse to hang
	sometimes if it encountered a constructs of the form:
  
	     not foo(X+2), or
             not foo(Y) : X = Y + 2


lparse-0.99.34 (28.9.1999)
	Yesterday's fix for empty conditions broke the semantics, so I
	had to rewrite that portion of code. 

	Now empty conditions behave in following way:
	    a :- b : c.
	becomes:
	    a :- b. 
	if 'c' is true, or
	    a.
	if 'c' is not true. 

	In constraint and weight rules a literal with empty condition
	doesn't count against bounds. This is because it allows rules
	of the form:

          foo :-  1 { chosen(X) : version(X) : X >= 10 }.
	  
	where the set 'version(X) and X >= 10' is possibly empty and
	'foo' should only be true when at leas one of 'chosen(X)' is
	in the model. 

	If there is a choice rule head with empty condition, the rule
	is dropped from the program. 

	Patched the configure script somewhat. Now it should detect
	correctly if c++ compiler doesn't implement exceptions. 

lparse-0.99.33 (27.9.1999)
	There was a serious bug in lexer that caused it to
	misinterpret numeric constants as atoms sometimes. 

	Before lparse would happily accept code of the form:
	{ a(X) : b(X) }.
	where b(X) was empty, and generate incorrect code for it.
	Now lparse generates a new unsatisfiable literal in place of
	a(X) if this happens. 

	Fixed a segmentation fault from error display code. Now the
	parser recovers from parse errors to check the rest ofcode and
	gives a little more intuitive error messages. 

	Fixed an error checking code that had its test backwards
	(indicated error when memory allocation actually succeeded). 
	There was a bug that sometimes caused an internal error if
	symbolic functions were used in normal rule heads. 

lparse-0.99.32 (14.9.1999)
	Cleaned error and warning messages. Now they show also
	filename in addition to the line number. In addition, if there
	were multiple input files and one of them ended with a comment
	line without a terminating newline then the first line of the
	next file was discarded as a comment. 

lparse-0.99.31 (11.9.1999)
        A hard disk crash destroyed the changes for versions 0.99.29
        and 0.99.30, so I had to rewrite them.

	Changes: multiple compute statements didn't work correctly,
	and constraints were dropped when the program was of the form

	   :- only, domain, predicates, here.
	   1 { some, atoms } 1.

        and the body of the first rule was false. 

lparse-0.99.28 (2.9.1999)
	Fixed a bug that prevented expressions from working
	inside symbolic functions. (This bug was first inroduced in
	0.99.15, fixed in 0.99.16, and then reintroduced in 0.99.26.
	There is now a test case to ensure that it will not come back
	again).

	Fixed a bug in smodels-mode.el which prevented using  'M-x
	smodels-mode' directly. 

lparse-0.99.27 (1.9.1999)
	The relational operators can now be used to compare symbolic
	constants. Additionally, non-alphanumeric characters can be
	used with constants by enclosing the constants with double
	quotes.	For example:

	   "quoted constant-1"

	is now a legal constant. The comparison operators put the
	constants into lexicographic order. 

lparse-0.99.26 (31.8.1999)
	I simplified the use of global weight declarations. I found
	out that there was a nasty bug that caused weights to have
	wrong values sometimes (for example, definition 'weight
	a(X)=X.' was lost if it was later applied to a(Y) ). Fixing
	this bug resulted in having lots and lots of special cases, so
	I decided to clean up the semantics. Now the latest matching
	declaration is always used. For example, after declarations:

	   weight p(1)=5.
	   weight p(X)=X.

	atom p(1) will have weight 1, not 5 as before. To get the same
	behavior as before you have to reorder the declarations. 

	Conditions are now allowed to have global variables. If a
	condition doesn't have a global variable it works just as
	before, but otherwise the global variables will be
	instantiated before expanding the condition. For example,
	rule: 

	   1 { chosen(X,Y) : edge(X,Y) } 1 :- node(X).

        ensures that exactly one outgoing edge is chosen for each node.

	The new behavior is _much_ slower than the old one because
	the expansion happens at the innermost loop of lparse, so you
	shouldn't use global variables unless you really need them. 
	
	Cleaned up the parser warnings. There are now five different
	warning types that can be enabled at the command line. See
	the User's Manual for details.

	Added support for extended rules for the regular model
	semantics translation. 

    	As a minor change I changed the default lower bound of weight
	rules from 0 to -infinity to get cleaner semantics. 

	In the process I fixed a couple of minor bugs that occured
	when there were many literals and functions on the right side
	of a condition. 

	I also wrote a major-mode for editing smodels programs with
	Emacs. It is located at src/smodels-mode.el. The instructions
	on its use are in User's Manual. 

lparse-0.99.25 (12.8.99)
	Added three levels to regular model translation. They work now
	as with default '2'
		lparse -r [1 | 2 | 3]

	Level one omits the integrity constraints from the program.
	That is, rules of the form " :- b, not b'" are left out. This
	option can be used to calculate alternating fixpoints of the
	program. 

	Level two performs just like the original regular model
	translation.

	Level three adds constraints of the form " :- b', not b" to
	the model. The resulting program will have same stable models
	than the untranslated program. 
	

lparse-0.99.24 (11.8.99)
	Added preliminary support for regular model semantics. Given a
	logic program and compute statement smodels can now find out
	whether there is a regular model of the program where the
	compute statement is true.

	The support is enabled with option '-r'. The program in
	question is transformed in the following way:

	a :- not b.
	b :- not a.
	f :- not a, not f.
	compute { a }.
	
	becomes

	b :- not a'.
	b' :- not a.
	f :- not a', not f'.
	f' :- not f, not a.
	a :- not b'.
	a' :- not b.
	 :- b, not b'.
	 :- a, not a'.
	 :- f, not f'.
	compute { a }.

	If atoms "p" and "p'" are in the model "p" is true in it, if
	both are missing "p" is false. If only "p'" is in model "p" is
	undefined in the model. 

	The regular model semantics don't currently work with extended
	rules. 

	Fixed a memory bug that could corrupt the arena when there
	were too many variables in extended rules. 

lparse-0.99.23 (30.7.99)
	Added a new warning option:
              -W weight
	This prints a warning if a default weight gets used somewhere.
	This option is useful to catch typos when you have a lot of
	weight definitions. 

	Fixed a memory bug that sometimes crashed lparse when using
	smodels 1.x format.

	The arguments of form '-W nofoo' didn't work correctly, now
	they do. 

	Removed many possibly dangerous operations where
	bit-pattern 0 was implicitly casted to a NULL pointer.

	Cleaned out some unused code. 

lparse-0.99.22 (22.7.99)
	Added bitwise operators AND (&), OR (|), XOR (^), and NOT (~)
	to internal functions.  

	Removed the predicate and function call arity limits.

	Changed the prototypes of used-defined functions to

	     long foo(int num_args, long *arg_array)

	where 'arg_array' is an array of 'num_args' longs.


lparse-0.99.21 (20.7.99)
	Fixed an operator precedence bug.

lparse-0.99.20 (8.7.99)
	Removed two memory errors that caused lparse to crash in some 
	circumstances (namely, when new internal variables were
	introduced in wrong places). Fixed three small memory leaks
	and one uninitialized variable. 

lparse-0.99.19 (1.7.99)
	Found and fixed a bug that caused atoms to be
	lost when there were too many hash table collisions. Added an
	optimization that reduces the memory usage. 

	Fixed a typo that prevented compilation on older Debian Linux
	systems.

	Functions 'eq' and 'neq' didn't work correctly with symbolic
	functions. 

	Corrected a couple of minor errors from example file
	'logistics.lp', and added two problem instance examples. 

lparse-0.99.18
	The user's manual is now up-to-date. It is distributed as a
	texinfo source. To get a dvi-version of it type 'make dvi'. 

	I reorganized the code structure to use autoconf and automake.
	As this is my first try using them there are probably some
	glitches left.

	The code is now explicitly under GPL. 	

	A bug that caused misformed output when there was unsatisfied
	ground domain literals in the rule body was fixed. Another bug
	was that some rules were lost if all domain predicates were
	printed. There was still one part of the code that supposed
	that atom set is saved also for those predicates that don't
	need it. Functions as tests didn't work if the whole rule was
	ground. Function argument type checking didn't work always.
	Weight definitions didn't work correctly with conditions.
	Negative weights work now also within optimize statements.
	
	Register is no longer needed. I also removed '-f' option
	because it was so closely tied with register.

lparse.0.99.17
	Changed the behavior of '-n' switch to override
	compute-statements. I also removed the switch '-s' because it
	didn't have any useful effect. 

	Some earlier change had broken choice rules when conditions
	were used. I fixed it. The more efficient data structures
	broke the handling of domain literals without arguments. This
	bug is also now fixed.



lparse-0.99.16 (4.6.1999)
	I fixed the command line argument handling code that
	segmentation faulted some times. 

	Also, I fixed a bug that caused nested function calls to
	fail.

	One more memory leak was found and eliminated.

lparse-0.99.15 (3.6.1999)
	For this version I rewrote the hash table codes almost from
	scratch. The result is that the memory consumption dropped by
	a third and in some cases the running times are now up to a
	half faster than before. 

	There is also a new feature in code, symbolic functions of
	type: 
	      a(f(X,Y)) :- d1(X), d2(Y).
	The above rule in conjunction with domain definitions
	d1(1..2), d2(1..2) will be grounded as follows:
	      a(f(1,1)).
	      a(f(1,2)).
	      a(f(2,1)).
	      a(f(2,2)).

	The symbolic functions have to be strongly range restricted.
	The functions can be used also in domain predicates. Adding
	the rule:
	      p(X,Y) :- a(X), d1(Y).
        to the above program adds the atoms:
	      p(f(1,1),1). p(f(2,1),1).
	      p(f(1,2),1). p(f(2,2),1).
	      p(f(1,1),2). p(f(2,1),2).
	      p(f(1,2),2). p(f(2,2),2).
	to the model. 

	I fixed many little memory bugs (mainly leaks) from the code,
	and it is possible that the fixes broke something else
	somewhere, so version 0.99.14 may be more stable.

lparse-0.99.14 (3.6.1999)
	Fixed a couple of bugs affecting ranges and functions.

lparse-0.99.13 (28.5.1999)
	Added a new keyword 'hide'. The syntax for it is
             hide p(X,Y).
        This marks all ground atoms of predicate p/2 to be anonymous,
	that is smodels 2.x doesn't print them in the models. 

	Fixed a bug that caused choice rules to fail if there were
	free variables in the heads. Also, smodels 1.x output format
	works again. 

lparse-0.99.12 (26.5.1999)
	The minor fixes of version .11 introduced a major bug into
	handling of negative literals. 


lparse-0.99.11 (25.5.1999)
	Fixed a lot of minor bugs from the code. I also clarified some
	of the error messages a little.

lparse-0.99.10 (23.5.1999)
	Added support for weights in choice rules. Now it is possible
	to use constructions like:
	    2 [ a(X):d(X)=X ] 5.
	
	Negative weights work now correctly. 

lparse-0.99.9 
	Changed the behavior of conditions. Now they are allowed also
	within basic rules. It is now an error if a global variable is
	used in condition. 

	Removed support for conjunctive ranges, since conditions can
	do everything that conjunctive ranges could do, and much more.
	The rule:
	    foo :- bar(1,,3).
	can now be encoded with two rules:
	    foo :- bar(X) : d(X).
	    d(1..3).

	Fixed a bug which caused problems when functions were used as
	arguments within special rules. Another bug that prevented
	using functions like "abs(X)" was also removed. 

	Added some optimizations to weight and constraint rules. Now
	lparse notices if the domain literals have enough weight to
	make the rule true. 

	Added a little error detection code to the parser. 

lparse-0.99.8 (9.5.1999)
	Fixed a bug that caused atoms to be misinterpreted as
	constants within weight rules.

	The global definitions of the weights work now more
	intuitively. It is now possible to define one literal as
	having different weights at different parts of the program.
	The weight used is either the latest definition for that
	particular ground literal, or if that is not found, the
	latest definition for unifiable literal. As the last resort a
	global weight definition for the predicate is used.

	It is now possible to define the default weight for literals
	by using command line argument '-w'. 
	
	I added some optimizations to index selection process during
	grounding. Now lparse tries to choose a constant value as an
	index if possible. 
	
lparse-0.99.7 (5.5.1999)
	Fixed a bug that caused range restriction checking to fail
	if functions were used in special rules.

	Found and fixed an uninitialized variable that caused problems
	with choice rules. 

lparse-0.99.6 (3.5.1999)
	Removed a memory bug that affected (again) compute statements.
	Removed a divide-by-zero problem.

lparse-0.99.5 (14.4.1999)
	Removed a bug which lost a choice rule if all variables
	occuring in its head were in conditions. 

lparse-0.99.4 (12.4.1999)
	Removed the support for generate rules because of their weak
	semantic foundation. The choice rules can now be used to
	express exlusive-ors, as they now work more like constraint
	rules: 

	   lower { a1, ... , an } upper :- body.

	The rule means that if body is true in a stable model, then
	the number of head literals of the rule that are true in the
	model will be between 'lower' and 'upper', inclusive.

	Internally, the rule will be translated into three rules:

	   { a1, ... an } :- body.
	    :- upper +1 { a1, ... an }, body.
	    :- n-lower+1 { not a1, ..., not an }, body.

	The expression
	   a1 | a2 | ... | an :- body.
	is now an alias for
	   1 { a1, ..., an } 1 :- body. 
	    	    
        Fixed a problem	that caused lparse output misformed rules when
        there were only negative literals inside a constraint rule.
        The upper bounds for constraint and weight rules are now
        inclusive as they should be. 

	Also, earlier bugfix didn't fix all problems with compute
        statements, this takes care of those problems.

lparse-0.99.3 (7.4.1999)
	Conditions and negative literals in the compute statement now
	work as advertised. Also, fixed a bug that caused ground
	special rules to fail in certain conditions.

	Changed the behavior of -d none -- flag. If there are any
	special rules in the program -d none now behaves like -d
	facts, since otherwise lparse might lose models when there are
	domain predicates in special tail sections. 

lparse-0.99.2 (6.4.1999)
	Fixed a couple of memory bugs, a bug which caused smodels
	to calculate wrong number of models, and a bug which broke
	conditions in optimize statements. Also updated SYNTAX to
	reflect the fact that global weights may also have variables. 

lparse-0.99.1 (29.3.1999)
	Fixed two bugs, one that caused a segmentation fault when a
        special rule had an empty head, and one error in lexer, which
        mixed constants with identifiers.

lparse-0.99.0 (24.3.1999)

	Includes support for new smodels 2.x rule types, declarations
	can now be anywhere in the program file, and constant valued
	expressions may be used everywhere where numerical constants
	may be used.

	This is (hopefully) the final beta version, and this will be
	elevated to version 1.0 when most of the new bugs are
	eliminated.
	
	The manual is not updated yet, the changes are described in
	file SYNTAX.

lparse-0.9.25 (8.3.1999)
        Fixed a bug that messed with unsatisfied ground predicates in
        otherwise non-ground bodies.

        Option -t now also prints the compute statement.

lparse-0.9.24 (15.2.1999)
	Fixed a bug in predicate argument handling code.

lparse-0.9.23 (12.2.1999)
	Fixed a bug which caused lparse fail when presented with rules
	of the form:
              a :- not b.
	where b was a domain predicate.

lparse-0.9.22 (9.2.1999)
	Fixed support to multiple argument lists. Rules of the form
	      foo(a;b;c).
	work again as expected.

lparse-0.9.21 (8.2.1999)
	Fixed a few bugs in range checking code. Thanks to Neil Moore
	for pointing them out.

lparse-0.9.19 (10.11.1998)
	Allow now rules of the form:
	      a | b :- 2 { c, d, e }, f.
	Corrected a few errors in lparse.ps

lparse-0.9.18 (6.11.1998)
	Rules of the form a | b . now work corerctly.
	Fixed a memory bug.

lparse-0.9.17 (28.10.1998)
        Fixed the handling of variable-free rules having non-true
        bodies.

lparse-0.9.16 (23.10.1998)
	First official beta version
