Symbolic domains (was Re: indomain/2 gives type error in version 5.5 (not before!))

From: Warwick Harvey <wh_at_icparc.ic.ac.uk>
Date: Mon 02 Dec 2002 04:49:38 PM GMT
Message-ID: <20021202164935.X25998@tempest.icparc.ic.ac.uk>
On Mon, Dec 02, 2002 at 10:09:36AM -0500, Sebastian Sardina wrote:
> Well I have no strong reason to use symbolic domains. In my application,
> the user/programer writes a set of axioms and programs for a robot and I
> have to perform some reasoning over them.
> 
> For instance, there may be a set of objects which I describe via a
> (symbolic) finite domain, and I have to reason about them with things
> like "if the robot picks up object A then she will be holding A, etc.."
> 
> I use constraints because sometimes it's very useful and practical to
> say things like: "the robot is holding everything except object C"
> (e..g, holding(X) "applies" with X#\=C)
> 
> That's my whole reason, nothing fancy. ;-)

Yes, I've used them in a similar fashion, as convenient labels for entities
I'm working with, where I only need equality and disequality constraints.

> I can easily imagine pre-processing the specification given by the user
> and transforming symbolic domains into integer domains. However, I have
> to do the mapping transparent for the user. Is there any already
> existing tool to do this?

No pre-packaged tool, but it's easy enough to do using, say, the hash
library.  You can set up a hash table which maps the user's symbols to
integers and (assuming you have to output the symbols later) another one
mapping the integers back to the user's symbols.

In the following I map symbols to integers starting from 0, using the number
of entries in the hash table to remember where I'm up to (since it maintains
that information and it saves me the bother :).

    % Map a symbol to an integer, allocating a new integer if the symbol
    % has not been seen before.
symbol_to_integer(SymIntHash, IntSymHash, Symbol, Integer) :-
	( hash_get(SymIntHash, Symbol, Integer) ->
		% It's an existing symbol
		true
	;
		% It's a new symbol: map it to the next integer.
		hash_count(SymIntHash, Integer),
		hash_set(SymIntHash, Symbol, Integer),
		hash_set(IntSymHash, Integer, Symbol)
	).

    % Map an integer back to a symbol.  Fails if there is no corresponding
    % symbol for the integer.
integer_to_symbol(IntSymHash, Integer, Symbol) :-
	hash_get(IntSymHash, Integer, Symbol).


Note that the above implementation won't give consistent answers across
backtracks (if you look a symbol up, backtrack, and then look the symbol up
again, you might get a different answer).  If this is a problem for you let
me know: we've recently added "persistent" hash table functionality to
ECLiPSe.  This will eventually be available publicly, once we've decided on
the right interface and documented it properly, but can be used now if you
know the predicate names and where to import them from --- and don't mind
the fact that the interface will almost certainly change in a future version
of ECLiPSe.

Cheers,
Warwick
Received on Mon Dec 02 16:50:39 2002

This archive was generated by hypermail 2.1.8 : Wed 16 Nov 2005 06:07:19 PM GMT GMT