Predicate Constant

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

Predicate Constant

Unread post by Martin Meyer » 11 Oct 2014 12:31

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: 2422
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 11 Oct 2014 14:02

(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: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 11 Oct 2014 15:01

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: 2422
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 12 Oct 2014 17:29

Maybe.

Why do you want two predicates with same name?
Regards Thomas Linder Puls
PDC

Martin Meyer
VIP Member
Posts: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 16 Oct 2014 15:42

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 266 times

User avatar
Thomas Linder Puls
VIP Member
Posts: 2422
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 16 Oct 2014 19:54

OK, that is a fine reason :-).
Regards Thomas Linder Puls
PDC

Martin Meyer
VIP Member
Posts: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 30 Jan 2015 15:30

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: 2422
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 30 Jan 2015 21:12

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: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 30 Jan 2015 21:33

No problem, with next release will be also fine.

Many regards
Martin

Martin Meyer
VIP Member
Posts: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 1 Jul 2017 13:51

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: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 1 Jul 2017 15:29

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: 2422
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 3 Jul 2017 14:53

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: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 4 Jul 2017 17:54

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 79 times
Regards Martin

User avatar
Thomas Linder Puls
VIP Member
Posts: 2422
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls » 4 Jul 2017 19:13

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: 276
Joined: 14 Nov 2002 0:01

Unread post by Martin Meyer » 8 Jul 2017 12:04

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