Discussions related to Visual Prolog
choibakk
Active Member
Posts: 35
Joined: 5 Sep 2019 19:30

Using "anyflow" works in "pro" file but seems to need all declared iterations in the "cl" file.

Unread post by choibakk »

This is only my 2nd post and again I'll state again I haven't developed with prolog in about 30 years until just recently (my previous experience being "Turbo Prolog" in the late 80's).

So I have this quick question. I created a predicate called "slide" that (slides) through a List performing some basic pattern matching (I know someone will say there is already a predicate for that, but its also a learning exercise--although I would like to know the predicate name!). Here is one of the declarations:

Code: Select all

    slide : (Elem* Source, Elem V1, Elem V2, Elem V3) nondeterm anyflow.
I can declare that as a "class predicate" in the ".pro" file, and it works fine. However, if I try to "expose" it by declaring in the ".cli", I get the error: "error c243 : Illegal flow pattern 'anyflow'."

Hopefully it is clear I want V1, V2, V3 to be either "in" or "out" parameters so I can make calls like this (not a very good example but hopefully you get the idea):

Code: Select all

        L = [ V || slide(["I", "am", "who", "I", "said", "I", "am"], V, "I", _V2) ]                 -or-                 L = [ Keyword1 || slide(["I", "am", "who", "I", "said", "I", "am"], "I", Keyword1, _Keyword2) ]
However, if I add all the possible iterations of the predicate in/out in the ".cl" file, it will compile! As in:

Code: Select all

predicates %   o o o %   o o i %   o i i %   i o o %   i i o %   i i i %   o i o %   i o i     slide4 : (Elem* Source, Elem V1 [out], Elem V2 [out], Elem V3 [out]) nondeterm.     slide4 : (Elem* Source, Elem V1 [out], Elem V2 [out], Elem V3) nondeterm.     slide4 : (Elem* Source, Elem V1 [out], Elem V2, Elem V3) nondeterm.     slide4 : (Elem* Source, Elem V1, Elem V2 [out], Elem V3 [out]) nondeterm.     slide4 : (Elem* Source, Elem V1, Elem V2, Elem V3 [out]) nondeterm.     slide4 : (Elem* Source, Elem V1, Elem V2, Elem V3) nondeterm.     slide4 : (Elem* Source, Elem V1 [out], Elem V2, Elem V3 [out]) nondeterm.     slide4 : (Elem* Source, Elem V1, Elem V2 [out], Elem V3) nondeterm.
If I want to add a (slide5) the iterations obviously keep increasing. What is the best way to handle a situation like this in Visual Prolog?

Thanks in advance!

P.S. For context, here the source for a simpler version (slide3) if it will help.

Code: Select all

    % TEST FOR END OF LIST     slide([_H], _V1, _V2) :-         fail.         % TEST FOR THE SUCCESS CASE     slide([H, TH | _TT], V1, V2) :-         V1 = H,         V2 = TH,         succeed.         % RECURSE     slide([_H | T], V1, V2) :-         slide(T, V1, V2).
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Re: Using "anyflow" works in "pro" file but seems to need all declared iterations in the "cl" file.

Unread post by Martin Meyer »

The Language Reference says:
The special flow pattern anyflow can be stated only in declarations of local predicates (i.e. in predicate declarations inside the implementation of a class). It means that the exact flow pattern(s) will be evaluated during the compilation.
In accordance with the 1st sentence the compiler issues error error c243 : Illegal flow pattern 'anyflow' when flow pattern anyflow is stated in predicate declarations inside a class declaration.

The 2nd sentence is also of means. I made a test. This does not compile:

Code: Select all

class predicates     test : (unsigned [out]). clauses     test(X) :-         stdIO::write(X). % throws: The flow pattern '(o)' does not exist for 'stdio::write/0...'
However that does compile (with a warning) and run:

Code: Select all

class predicates     test : (unsigned) anyflow. clauses     test(X) :-         stdIO::write(X).   clauses     run() :-         test(1).
Apparently the compiler evaluates the flow pattern, which is actually used, and does not throw an error because the output flow variant is not used.

Flow patterns can be listet in a predicate declaration. Unfortunately it takes but 2^n flow patterns to support every flow on n arguments:

Code: Select all

predicates     slide4 : (Elem* Source, Elem V1, Elem V2, Elem V3) nondeterm         (i,o,o,o)         (i,o,o,i)         (i,o,i,o)         (i,o,i,i)         (i,i,o,o)         (i,i,o,i)         (i,i,i,o)         (i,i,i,i).
Above slide4 predicate could be used for example by:

Code: Select all

clauses     run() :-         V2 = "I",         slide4(["I", "am", "who", "I", "said", "I", "am"], V1, V2, V3),         stdio::write(V1, ", ", V2, ", ", V3, '\n'),         fail.     run().
To circumvent the numerous flow patterns that can be coded better:

Code: Select all

predicates     slide4 : (Elem* Source, Elem V1 [out], Elem V2 [out], Elem V3 [out]) nondeterm.

Code: Select all

clauses     slide4([X1, X2, X3 | Rest], V1, V2, V3) :-         V1 = X1,         V2 = X2,         V3 = X3         or         slide4([X2, X3 | Rest], V1, V2, V3).   clauses     run() :-         slide4(["I", "am", "who", "I", "said", "I", "am"], V1, V2, V3),         V2 = "I",         stdio::write(V1, ", ", V2, ", ", V3, '\n'),         fail.     run().
Putting that idea into your example code, it becomes:

Code: Select all

        L = [ V || slide(["I", "am", "who", "I", "said", "I", "am"], V, V1, _V2), V1 = "I" ]                 -or-                 L = [ Keyword1 || slide(["I", "am", "who", "I", "said", "I", "am"], V, Keyword1, _Keyword2), V = "I" ]
Regards Martin
choibakk
Active Member
Posts: 35
Joined: 5 Sep 2019 19:30

Re: Using "anyflow" works in "pro" file but seems to need all declared iterations in the "cl" file.

Unread post by choibakk »

Thank you for the great response! I was so proud of my little "slide" routine in 8 lines of code. And then I see this (your version):

Code: Select all

slide4([X1, X2, X3 | Rest], V1, V2, V3) :-         V1 = X1,         V2 = X2,         V3 = X3         or         slide4([X2, X3 | Rest], V1, V2, V3).
Brilliant. Thanks again.
Post Reply