Page 1 of 1

Predicate Constant

Posted: 11 Oct 2014 12:31
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().

Posted: 11 Oct 2014 14:02
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.

Posted: 11 Oct 2014 15:01
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

Posted: 12 Oct 2014 17:29
by Thomas Linder Puls
Maybe.

Why do you want two predicates with same name?

Posted: 16 Oct 2014 15:42
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.

Posted: 16 Oct 2014 19:54
by Thomas Linder Puls
OK, that is a fine reason :-).

Posted: 30 Jan 2015 15:30
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

Posted: 30 Jan 2015 21:12
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 .

Posted: 30 Jan 2015 21:33
by Martin Meyer
No problem, with next release will be also fine.

Many regards
Martin

Posted: 1 Jul 2017 13:51
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").

Posted: 1 Jul 2017 15:29
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").

Posted: 3 Jul 2017 14:53
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.

Posted: 4 Jul 2017 17:54
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).

Posted: 4 Jul 2017 19:13
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)).

Posted: 8 Jul 2017 12:04
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