LPARSE VERSION HISTORY

1.1.2 (8.3.10)
	Cleaned the code so that it compiles with no problems with new g++
	versions and tweaked configure script so that you may now define
	the compiler tools with command line options CC, BISON, and LEX.

1.1.1  (10.10.07)
    Fixed a bunch of small memory errors. Added a workaround skipping
    a possible bug in g++ 4.1.2's STL implementation. 
	
	Range definitions of the form foo(1..n, 1..m) got broken in the
	change as did negative weights.

    Added a couple of new examples.  

1.1.0 (3.10.07)

    New version for a too long time. This version contains quite a bit
    of internal chances to make the source code to better conform with
    the C++ standard. As a part of that I got rid of the automake
    scripts that were causing more problems than solving. 

    These major changes mean that it is possible that something got
    broken in the way. So, it is probable that there will soon be
	a new version.

1.0.17 (13.10.05)

    Bugfixes. When using the option '-d all' some rules were printed
    twice. Another problem was that a choice rule with an empty head
    got passed to smodels that didn't like it. Now, the user has two
    choices. The default is that such rules are always dropped out
    from the input (as they are trivially true). However, if the
    command line option '--empty-choices' is set, they are printed but
    with the atom '_false' occuring as the only atom in the choice.

1.0.16 (30.09.05)

    Added support for including debugging data to lparse output. This
    is used by the exteremely experimental 'smdebug' debugger. Debug
    information is printed if the command line option

        --debug

    is included. 

    There is now also a (again, very experimental) static typechecker
    'typecheck' available that uses the #type and #predicate
    declarations that were added in the last version. 

    Both 'smdebug' and 'typecheck' are included in the lparse
    distribution in the new directory 'tools'.

1.0.15 (30.05.05)

    This version is basically a bugfix that removes three memory
    errors. There are two new features. Firs is the declaration:

	   #nondomain a(X) 

    That defines 'a/1' to be a non-domain predicate even if it would
    syntactically be a domain predicate. 

    There is also a new command line option

        --only-facts
  
    Setting it causes lparse to output only the domain predicates of
    the program and the non-domain part is not instantiated.

    The syntax also recognizes two new declarations that are not yet
    fully implemented:

        #type 
        #predicate

    these will be used to implement strong type checking but right
    now they do nothing. 

1.0.14 (2.5.05)

     This version changed the handling of '--dlp' option. Now, in the
     choice rules and disjunctive rules are handled differently in
     both input and output. When using only '--dlp', you can't mix the
     two, but mixing is allowed when using the option '--dlp-choice'.
     (If you mix them, make certain that your solver understands
     both). The possible special head types are now:

         { a, b, c } :- body.        % choice rule.
         2 { a(X) : d(X) } 2:- body. % choice rule. 

    ->   a | b | c :- body.          % disjunctive rule
    ->   | a(X) : d(X) | :- body.    % disjunctive rule  
      
         1 [ a(X) : b(X) = X ] 2.    % weight rule

         a x b x c :- body.          % ordered disjunction

     In the textual output disjunctive rules are denoted by having
     a '|' separate the atoms in the head. Thus, the program

         d(1..3).
         | a(X) : d(X) |.
  
     instantiates to:

         a(1) | a(2) | a(3).

     When outputting the smodels format, a disjunction has the rule
     identifier '8' and it is otherwise similar to a choice rule, so
     the above rule becomes:

        8 3 1 2 3 0 0

     There is another change in the language in that negative
     literals are no longer allowed in choice rule heads. This
     change was made because the semantics was not really
     well-defined and especially it wasn't what the user would
     reasonably expect. 

     The default command line behavior is now to output all
     warnings. The warnings may be surpressed with command line
     options if desired (-W none turns warnings off and adding '~' in
     front of a warning turns off that particular one). 

     There are now several new command line options:

         --dlp-choice    --- allow mixing disjunctive and choice
                             rules. 
         --all-symbols   --- output all atom names, even internal
                             ones. 
         --dependency-graph 
                         --- print the dependency graph of the
                             program in the form of logic programming
                             facts. 
         --debug         --- output debugging information for rules.
                             This functionality is not yet complete. 
         --strict        --- enable strong typing. This does not work
                             yet. 
         --check-tightness 
                         --- check whether it is completely certain
                             that the outputted portion of the
                             program is tight, and include the result
                             at the very end of the program. Note that
                             this analyses only the non-ground program
                             and it is possible that the program is
                             tight even though this check misses it. 

      This version also contains lots of small bugfixes.


1.0.13 (19.6.03)
      Empty programs are now again handled gracefully. The option
      `--dlp' produced few irrelevant rules. Warnings for using
      general constraint literals together with `--dlp' weren't
      printed. 

1.0.12 (26.3.03)
      Fixed a typo in error.cc. Added few missing declarations. Also,
      empty rules now produce unsatisfiable programs.


1.0.11 (30.9.02)
      Changed the behavior of `-d all' switch. Now, the domain facts
      that are derived using rules of the form:
       
    a(1..2)
    b(X) :- a(X).
    
      are no longer explicitly added to the output as facts. 

      Fixed a bug with '#domain' declaration that occurred when using
      rules of the form:
 
    #domain d(X).
    a :- 1 { nd(X) }.
      

1.0.10 (17.6.02)
      Added support for preference programming using ordered
      disjunctions. They work with 'psmodels' modification of smodels
      proper. The relevant arguments are:

        --priorities --- enable ordered disjunction priorities
        --cardinality-optimal --- use cardinality preference semantics 
        --inclusion-optimal --- use inclusion preference semantics
                                (default) 
        --pareto-optimal --- use pareto-optimality criterion in
                             priorities
        --interactive-priorities --- generate rules for interctive
                                     priority resolution 
      
      The accepted syntax is:
 
          a x b.   % Define a choice over a and b, a preferred. 
       r: a x b.   % As above, but give the name 'r' to the choice
       q: b x a.   % And again, name 'q'
          priority(r, q).  % define that it is more important to satisfy
                           % 'r' than it is to satisfy 'q'.

      The differences between the semantics are explained in Brewka,
      Niemel, Syrjnen: "Implementing Ordered Disjunctions",
      JELIA-02. Note that psmodels doesn't support interactive
      definition of meta-priorities, yet, no matter what lparse source
      might imply.

      Fixed few bugs: sometimes when domain predicates were defined in
      the end of a program, lparse would fail to identify them. Also,
      error messages when undefined constants were used were rather
      cryptic. 


1.0.9 (12.9.01)
      The `#domain' declaration didn't work correctly always for all
      variables occuring in rules. 

      Cleaned up code for `-Wunsat' a little and now there's less
      spurious warnings. 

1.0.8 (30.8.01)
      A host of bugs fixed. First, there was a problem with compute
      statements containing domain predicates when `-d none'
      command-line option was used.

      Next, the option `--true-negation' and hide declarations didn't
      work correctly together and constraints of the form:

        :- b, -b.
 
      were usually left out when b was hidden. (At least for now `hide
      b.' will hide both `b' and `-b' at the same time.)

      Also, if an empty hide declaration was given, then the names of
      symbolic functions would be garbled.

1.0.7 (17.8.01)
      There was a rather embarassing bug in code handling 0-ary atoms
      that could cause some rules to be lost. In particular, the
      following construction didn't work correctly:

         a :- b. 
     b :- a. 
     a.
     c :- a, b.
      
      There are now two more internal functions: exponentation a**b
      and a norm-function ||d(X)|| that finds out the size of the
      extension of a domain predicate d(X). The latter makes it
      possible to write code like:

        { choose(X) : option(X) }. % option(X) defined in other file
    number( 0.. ||option(X)||).
    count_chosen_options(I) :- I { choose(X) : option(X) } I,
                                   number(I).

      So, in effect you can now count things a little easier. However,
      be careful when domains are large since it is quite easy to get
      an exponential blowup using this. 

1.0.6 (25.6.01)
      Three more bugs squashed, all memory bugs this time. Lparse
      segfaulted sometimes trying to ground 0-ary predicates. The
      warning -Wsimilar also potentially caused problems. Third, using
      hide statements on transitive domain predicates with textual
      output could crash the program. 

1.0.5 (4.6.01)
      Fixed several bugs. First, lparse sometimes ended in an infinite
      loop if there were rules of the form:
 
         a(X) :- d1(X), d2(X+1).

      where both `d1' and `d2' were domain predicates.

      Second, there were two bugs with warnings. Lparse would
      segmentation fault with some warning combinations if the warning
      level was defined using the #option statement:

         #option -Wall

      The other problem was that there were incorrect warnings about
      different const declarations when there shouldn't have been. 

      Finally, rules of the form:

        a(X) :- b(X+1).

      got through the domain-restriction check only to cause a
      combination of a runtime error and an internal error later. (A
      rule: a(X-1) :- b(X) works well). 

1.0.4 (21.3.01)
      Fixed one more bug from symbolic functions. This time things
      went awry when symbolic functions were used in
      recursively-defined domain predicates.

1.0.3 (13.3.01)
      The class of domain predicates was extended significantly. See
      the User's Manual for details.

      There's a new syntax for statements available. It adds the `#'
      character in front of keywords. For example

        hide a(X), b(X).

      can be written as:

          #hide a(X), b(X). 

      Two new statements were added:

          #option foo bar baz.
      #domain a(X).
      
      The option statement can be used to define lparse command line
      options directly from source code. The domain statement is a
      notational shortcut that assigns a fixed domain to a set of
      variables. For example, given the above domain statement, the
      rule:

          b(X) :- not c(X).

      will be expanded to:

          b(X) :- a(X), not c(X). 

      The error and warning messages were tidied. The length of some
      static buffers was way too short in Windows binaries. There was
      also a bug that messed up things if there were nested symbolic
      functions in wrong places. 

1.0.2 (5.2.01)
        A bug sometimes caused lparse to instantiate rules incorrectly
        when there were negative numbers in the index variables of
        domain predicates.

1.0.1 (10.1.01)
        Added a new internal function, `weight' to the language. It
        takes one basic literal as its (only) argument and returns its
        weight. For example, in the program:

        weight a = 10.
        b :- weight(a) > 5.

    The atom `b' is true since the weight of `a' is 10. 

    Four bugs were squashed. The most severe caused lparse to
    either dump core or produce incomplete grounding if an input
    of the following form was given:

        d(-2 .. 2).
            e(0..2).
            b(X) :- d(X), e(X). 

    The bug occurs only when the larger domain predicate (`d') has
    some negative integer values (< -1) defined for it. In most
    cases lparse would dump core when seeing this occur, but on
    some cases it would silently discard the negative integers
    from the grounding. 

    When using the `-g' option, lparse identified some predicates
    incorrectly. 

    Lparse also grounded some rules of the form:

        foo :- not bar(X) : baz(X). 

    incorrectly. 

    Optimize statements with negative weights generated malformed
    rules that smodels rejected. 

1.0 (12.12.2000)
    I decided to make the current version of lparse the official
    version 1.0. 

0.99.62 
    Command line constant definitions now override the const
    declarations in the programs. 

    A new option `--version' was added because it is a pretty much
    standard option. 

    Several bugfixes. The `-1' option works once more and some
    problems with the partial model translation were fixed. 


    Few minor tweaks to get lparse compile easier under Windows. 

0.99.61 (23.11.2000)
    Negative literals are now allowed in choice rule heads, as in:

         1 { not b, not c } 1.
    
    Also, the semantics of weights of negative literals was
    tweaked a bit. Now, as default, the weight of a negative
    literal will be the same as the weight of the corresponding
    positive literal, if no weight is defined for the negative
    literal. So, given the following statements:

         weight a = 2.
         weight not a = 3.
         weight b = 5
        
    The weight of `a' is 2, of `not a' is 3, and both `b' and 
    `not b' have weights of 5. This defaulting can be turned off
    with the command line argument `--separate-weight-definitions'. 

    One new warnings have been added. Lparse now warns if the same
    constant is used as both numeric and symbolic constant. This
    will catch mistakes like: 

         foo(parameter).
         const parameter = 5.
     
        where the number is used before it is defined. This warning
    is added behind the `-W similar' argument. 

    A number of bugs relating to weight and constraint literals
    were fixed. First, lparse assigned a wrong weight to a
    non-ground literal if different instantiations of the literal
    used different weight definitions.

    Second, there was a bug that sometimes caused constraint and
    weight rules that had conditions in negative literals to be
    grounded incorrectly (namely, one negative literal was flipped
    over to be positive). 

    There was a memory error that caused segmentation faults if
    the abs-operator || was used with non-ground argument. 
    
0.99.60 (8.11.2000)
    Lparse's handling of quoted strings caused problems when the
    atoms were handled by other programs. For this reason the
    constants `"foo"' and `foo' are now different. Lparse warns of
    mixed usage given an argument `-W similar'. The old behavior
    (dropping quotes when possible) is available with a new
    command line option `--drop-quotes'. 

    Another change is that now positive and negative literals are
    handled separately in the weight definitions. For example, in 

             weight a = 5.
             weight not a = 10.

              :- 6 [ a, not a].

        the weight of `a' is 5 and of `not a' is 10. 


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
