Discussions related to Visual Prolog
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Predicate Constant

Unread post by Martin Meyer »

Hello Thomas and hi all,

the below code throws error c229 : Undeclared identifier 'myRenamedPredicate/0' (in VIP build 7500). Is it intended or bug?

Regards
Martin

Code: Select all

class predicates     myPredicate : (). clauses     myPredicate().   constants     myRenamedPredicate : core::predicate = myPredicate.   class predicates     test : (). clauses     test() :-         myRenamedPredicate().
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

(Named) predicates are constants.

So it is (kind of) intended that constants cannot be predicates.

But it is a bug that the error is given at the usage rather than at the constant definition.
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

Thanx for the info Thomas!

Maybe you can make predicate constants work in a future release? They have usage in increasing code's readability and easing its maintainance. In the place, where I tried to use it, I have now put a wrapper predicate in the style of

Code: Select all

class predicates     myRenamedPredicate : (). clauses     myRenamedPredicate() :-         myPredicate().
But compared to a predicate constant this construction wastes a little CPU-time.

Regards
Martin
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

Maybe.

Why do you want two predicates with same name?
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

The example below deals with personID's and sets of them. The personID's are implemented as of domain symbol and the sets as of domain personIdSet.

Domain personIdSet in turn is implemented through a patricia set of unsignedNative keys (patricia set's code is just a modified version of the radixTree package, the code is in package radixSet in attached project "PredicateConstant").

I want to hide the way, personIdSet is implemented, from the main code. So, in the main code I use predicates personIdSet_insert, personIdSet_union, personIdSet_getAll_nd rather than anything from package radixSet.

The issue now is, that one of the personIdSet predicates, i.e. personIdSet_union, happens to be completely equal to radixSet::merge. Hence it would be nice to just give predicate radixSet::merge a second name, which fits to the rest of the personIdSet predicates.

Regards
Martin

Code: Select all

domains     personId = symbol.     %%%%%%%%% %  Domains and predicates for personIdSet   domains     personIdSet = radixSet::dictionary.   constants     personIdSet_empty : personIdSet = radixSet::empty.   class predicates     personIdSet_insert : (         personIdSet PersonIdSet_0,         personId PersonId)         -> personIdSet PersonIdSet. clauses     personIdSet_insert(PersonIdSet_0, PersonId) = radixSet::insert(PersonIdSet_0, uncheckedConvert(unsignedNative, PersonId)).   class predicates     personIdSet_getAll_nd : (personIdSet PersonIdSet_0)         -> personId PersonId         nondeterm. clauses     personIdSet_getAll_nd(PersonIdSet_0) = uncheckedConvert(personId, PersonIdUnsignedNative) :-         PersonIdUnsignedNative = radixSet::getAll_nd(PersonIdSet_0).   class facts  %instead of a fact a predicate constant could go here     personIdSet_union : function{personIdSet PersonIdSetA, personIdSet PersonIdSetB, personIdSet PersonIdSetAB} := radixSet::merge.     %%%%%%%%% %  Main code   clauses     run() :-         PersonIdSet_a1 = personIdSet_insert(personIdSet_empty, "Huey"),         PersonIdSet_a = personIdSet_insert(PersonIdSet_a1, "Dewey"),         PersonIdSet_b1 = personIdSet_insert(personIdSet_empty, "Louie"),         PersonIdSet_b = personIdSet_insert(PersonIdSet_b1, "Huey"),         PersonIdSet_ab = personIdSet_union(PersonIdSet_a, PersonIdSet_b),         foreach PersonId = personIdSet_getAll_nd(PersonIdSet_ab) do             stdIo::write(PersonId, "\n")         end foreach.
Attachments
PredicateConstant.zip
(11.84 KiB) Downloaded 572 times
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

OK, that is a fine reason :-).
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

In the new features list http://wiki.visual-prolog.com/index.php ... Build_7501 I see an entry "Problem with predicate constants". But when I try to replace the class fact from the example by

Code: Select all

constants     personIdSet_union : function{personIdSet PersonIdSetA, personIdSet PersonIdSetB, personIdSet PersonIdSetAB} = radixSet::merge.
the compiler complains of Undeclared identifier 'personIdSet_union/2->'.

Regards
Martin
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

Yes, I see the same problem.

The problem is solved in our internal version, so I think the problem is that it hasn't been merged into the release.

So I am sorry to say that you will have to continue to use the fact .
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

No problem, with next release will be also fine.

Many regards
Martin
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

Hello Thomas,

predicate constants are working (in VIP 7502), thank you!. An example:

Code: Select all

domains     screenWriter = (string Msg).   class predicates     writeOnScreen : screenWriter. clauses     writeOnScreen(Msg) :-         stdIO::write(Msg).   constants     writeOnScreen2 : screenWriter = writeOnScreen.   clauses     run() :-         writeOnScreen2("Hello").
But there is a problem with polymorphic predicate domains. In the below code the predicate domain screenWriter has a parameter Type. The compiler throws fatal error c098 : Not synchronized lists for fixed parameters (Type) on it.

Code: Select all

domains     screenWriter{Type} = (Type Msg).   class predicates     writeOnScreen : screenWriter{Type}. clauses     writeOnScreen(Msg) :-         stdIO::write(Msg).   constants     writeOnScreen2 : screenWriter{Type} = writeOnScreen.   clauses     run() :-         writeOnScreen2("Hello").
Regards Martin
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

Testing a little more I found that cases exist where polymorphic predicate constants are working out. For example:

Code: Select all

class test     domains         screenWriter{Type} = (Type Msg).       predicates         writeOnScreen : screenWriter{Type}.         altWriteOnScreen : screenWriter{Type}. end class test   implement test     clauses         writeOnScreen(Msg) :-             stdIO::write(Msg).       constants         writeOnScreen2 : screenWriter{Type} = writeOnScreen.       clauses         altWriteOnScreen(Msg) :-             writeOnScreen2(Msg). end implement test   implement main   clauses     run() :-         test::altWriteOnScreen("Hello").
Regards Martin
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

We do not support (and have no plans for supporting) polymorphic constants.

But the compiler should of course give an error instead of breaking down.
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

The predicate domain in

Code: Select all

constants     writeOnScreen2 : screenWriter{Type} = writeOnScreen.
is polymorphic. But is the constant polymorphic? The constant has no type parameter.

Looking at cases where it is not a predicate domain but a polymorphic compound type, everything works out perfectly with constants. The attached example unsignedNativeListTrieDemo contains a class for maps of keys to Data where the keys are lists of unsignedNative numbers. In the class the constant empty is declared as below and works fine.

Code: Select all

domains     dictionary{Data} =         nonMember(radixTree::dictionary{dictionary{Data}} ChildDict);         member(             Data Value,             radixTree::dictionary{dictionary{Data}} ChildDict)         [in_iterate(up_nd)].   constants     empty : dictionary{Data} = nonMember(radixTree::empty).
Attachments
unsignedNativeListTrieDemo.zip
(12.63 KiB) Downloaded 394 times
Regards Martin
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

You are right we do actually support polymorphic compound domain constants.

So I should have said: We do not support (and have no plans for supporting) polymorphic constants.

(writeOnScreen2 is polymorphic, because its type (i.e. screenWriter{Type}) contains a free type variable (i.e. Type)).
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer »

Thank you for the info Thomas!

Btw. I suppose with scope type parameters it is within the intended functionality to declare polymorphic predicate constants. Below code works fine.

Code: Select all

interface example{@Type}       open core   constants     myCompare : function{@Type, @Type, compareResult} = compare.   end interface example   %===   implement main   clauses     run() :-         Result = example::myCompare(1, 2),         stdIO::write(Result).   end implement main
Regards Martin
Post Reply