Re: Integer instances and arithmetic

Thomas Russ <[email protected]> Mon, 8 Nov 2010 08:54:03 -0800
Newsgroups gmane.comp.ai.powerloom
Message-ID <[email protected]>
On Nov 7, 2010, at 3:14 AM, lee martie wrote:

> I am trying to create instances of type integer and increment these
> instances by some amount.
>
> I have found a work around to do this but would be very appreciative
> for a simpler solution if one exists or pointers to Powerloom  
> features I
> am overlooking.
>
> I found that I could not accomplish defining an integer instance with
> "(assert (INTEGER x))".

That's correct.  Integers are literal objects in PowerLoom and not  
actual instances.  So you could only use literals, which are immutable  
objects.

If you want something that you can increment then you have to create  
some object and give it a value.  The simplest way of doing that is to  
use a function (via deffunction) and then change the value of that  
function on the instance.  That is what you end up doing below:

> I am using the following workaround:
>
> (deffunction intVar ((?x thing)) :-> (?y integer)) .

Yes.  This will create an object with a functional value that can be  
set to various integers.

> I also have a need to increment an integer instance by some amount.
>
> I found that:
> (assert (=(intVar g) 0))
> (assert (=(intVar g) (+ (intVar g) 1)))
>
> will not map "g" to "1" .

Correct again.
Assertions are used to state logical facts. So PowerLoom will treat  
this as an equivalence between the value of (intVar g) and the  
formula.  Now, in this case, the formula that you have asserted is  
unsatisfiable -- although PowerLoom does not figure that out.  In  
effect what this formula
     (= (intVar g) (+ (intVar g) 1))
says is that the value of the intVar function of G is always one  
bigger than it's value.  The key point is that this is a formula and  
not a procedural assignment.  In fact, if PowerLoom were to try to  
treat this as a logical rule, you would end up with an infinite loop,  
since this rule says that whatever the value of G is, it should be one  
higher.  So if it changes, it should still be one higher, ....

> I am instead incrementing "g" by executing:
>
> (assert-from-query
> (retrieve all (+ (intVar g) 1 ?x))
> :pattern
> (setofall (?x Integer) (=(intVar g) ?x) ) )

Yes, this is what you will need to do, because ASSERT-FROM-QUERY is a  
procedural operator.  It executes a particular query and then produces  
assertions from it.  The query part is used to come up with a single  
new value which is then assigned to the function.  The key difference  
between this and the plan assertion is that the RETRIEVE provides an  
answer that is outside the logical assertion space, and you then set  
that value into the logical assertion space with the pattern.

So you will need to do something along these lines, either using  
ASSERT-FROM-QUERY or some similar construct that you build on your own.