Difference between revisions of "VIP7 Construct examples"

From wiki.visual-prolog.com

Line 275: Line 275:
pd(poly_dom{A,B});
pd(poly_dom{A,B});
poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)
poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)
integer(B);% er...no complaint from the compiler, so go on - be strange
s(string).
string.
another{A}=integer;
another{A}=integer;
string;
string;

Revision as of 16:56, 23 March 2009

This page contains a collection of basic examples for (mainly) the newer constructs found in VIP7.

Fact variables

Fact variables are the only mutable types in VIP.

Examples - "reminder- ordinary facts"

facts
    ndb_int:(integer).  % a nondeterministic fact (0 to any number of values)
    db_int:(integer,string) determ. % a deterministic fact (0 to 1 value)

These types of fact are asserted and retracted.

Examples - "fact variables"

facts
    zz_int:integer:=0.
    zz_fred:integer:=erroneous.
 
domains
    dom=dom(string,chaindb:ref).
 
facts
    zz_dom:dom:=erroneous.
 
clauses
    pred():-
        zz_int:=7,
        stdio::write("\n zz_int = ",zz_int), %will write "zz_int=7"
        zz_int:=zz_int+20,
        stdio::write("\n zz_int = ",zz_int), %will write "zz_int=27"
        succeed.

A fact variable is great for counting eg.

predicates
    pred:()=integer Count.
clauses
    pred()=_:-
        zz_int:=0,
        some_nondeterm_fact_or_pred(),
            zz_int:=zz_int+1,
            fail.
    pred()=zz_int.

Lists - findall and list comprehension

See Lists and Recursion
findall() has been depricated, so use the list comprehension construct.

Examples

facts
    ndb:(integer). %default is nondeterm for a fact
clauses
    ndb(1).
    ndb(2).
    ndb(3).
    ....
    ndb(10).
clauses
    pred_old():-
        findall(X,ndb(X),List).
        %results in List = [1,2,3,4,5,6,7,8,9,10]
clauses
    pred_new():-
        List=[X||ndb(X)].
        %results in List = [1,2,3,4,5,6,7,8,9,10]
clauses
    pred_filter():-
        List=[X||ndb(X), X>6].
        %results in List = [7,8,9,10]
 
    pred_filter():-
        List=[X||ndb(X), X mod 2=0].
        %results in List = [2,4,6,8,10]
 
    pred_filter():-
        List=[X||ndb(X), X mod 2=0, X<7].
        %results in List = [2,4,6]
 
    pred_filter():-
        zz_int:=0,
        List=[X||ndb(X), X mod 2=0, X<7, zz_int:=zz_int+1].
        %results in List = [2,4,6] and zz_int=3.
 
    pred_filter():-
        List=[X||ndb(X), Y=pred2(X), Y>10].   %with pred2(X)=X^2.
        %results in List = [4,5,6,7,8,9,10]
        %reason - X=3 gives Y=9 which is < 10.
 
    pred_other():-
        L=[1,2,3,4,5,6,7,8,9,10],
        LIST=[ X || X = list::getMember_nd(L)].
        %results in List= L
 
    pred_other():-
        Primes=[X||X=std::fromto(1,300),
		L1=[Y||Y=std::fromto(2,150)],
		tt(X,L1)].
        %results in List= prime numbers, with:
class predicates
        tt:(integer,integer*) determ.
clauses
        tt(_X,[]):-!.
        tt(X,[X|_]):-!.
        tt(X,[Y|L]):-
		X mod Y<>0,
		tt(X,L).

if-then-else (code)

Examples

clauses
    pred(X):-
        if X>0 then
            stdio::write("\n X>0")  %the last line in each block has no comma
        else
            stdio::write("\n X<=0")
        end if.
 
    pred(X):-
        if X>0 then
            stdio::write("\n X>0")
        elseif X = 0 then
            stdio::write("\n X=0")
        else
            stdio::write("\n X<0")
        end if.
 
clauses
    pred(X,Y)=Z:-
        if X=0 then
            Z="x is zero"
        elseif X>0 then
            if pred3(Y)=true then
                Z="x>0 and pred(Y) is true"
            else
                Z="x>0 and pred(Y) is false"
            end if  %note, no comma here either
        else
            Z="x <0"
        end if.


#if #then #else (directive for conditional compilation)

Examples

constants
    u64_con=1.
    int_con=2.
    real_con=3.
 
    compile_big_con=u64_con. %change this and then recompile.
 
#if compile_big_con=u64_con #then
    predicates
        pred:()->unsigned64.
    clauses
        pred()=U64:-
            U64=78766.
 
#elseif compile_big_con=int_con #then
    predicates
        pred:()->integer.
    clauses
        pred()=Int:-
            Int=20.
 
#else
    predicates
        pred:(real [out]).
    clauses
        pred(0.766).
 
#endif

Note
Code construct uses if  - then, elseif  - then, else, end if
compiler directive uses #if - #then, #elseif - #then, #else, #endif
(just the "end if" is "different")

Trap and try/catch/finally

See Try-catch-finally
Note, in Built-in entities/Predicates
suggests using try-end try instead of trap(_,_,_)

Example 1

clauses
    pred_all():-
        try
            call_pred_that_might_crash(0)
        catch ErrorNo do
            call_own_exception_pred(ErrorNo)
        finally
            always_call_this_anyway()
        end try.
 
class predicates
    call_pred_that_might_crash:(integer).
    call_own_exception_pred:(pointer ErrorNo).
    always_call_this_anyway:().
clauses
    call_pred_that_might_crash(X):-
        Y=9/X.
 
    call_own_exception_pred(ErrorNo):-
        vpiCommonDialogs::note("crashed").
 
    always_call_this_anyway():-
        vpiCommonDialogs::note("finally reached").

Example 2

clauses
    pred_some():-
        try
            call_pred_that_might_crash(0)
        finally
            always_call_this_anyway()
        end try.

% in this case, VIP will automatically pop up its exception dialog

Example 3

clauses
    pred_some():-
        try
            call_pred_that_might_crash(0)
        catch ErrorNo do
            call_own_exception_pred(ErrorNo)
        end try.

Example 4 - illegal - it must have a catch or finally

clauses
    pred_illegal():-
        try
            call_pred_that_might_crash(0)
        end try.


64 bit numbers

Polymorphic Domains

See Objects and Polymorphism


First, check out the definitions - core::tuple. And while you're there, just below, see core::predicate and core::function

The domains in class list:: are polymorphic, but you can define your own polymorphic domains. Here are some examples:

domains
	poly_dom{A,B}=poly_def(A,B).

When you use it in your code, A and B can be any other domain.
The domain name is poly_dom{A,B}, and you reference it you must use its whole name (not just poly_dom) e.g.

domains
	joe{A,B}=poly_dom{A,B}*.	
/* the next two lines are illegal
	poly_dom{A,B}=poly_def(A,B)*.
	poly_dom{A,A}=poly_def(A,A).
*/
	fred{A,B}=fred(poly_dom{A,B},integer).
 
	maybe_silly_dom{A,B}=silly2(A,B);
							silly(A);
							pd(poly_dom{A,B});
							poly_dom(A,B);%IS NOT THE SAME POLY_DOM!! (notice no braces)
							s(string).
 
	another{A}=integer;
				string;
				a(A).
 
facts
	zz_poly_dom:poly_dom{integer,integer}:=erroneous.
 
class predicates
	p_morphic_test:(). 
clauses			
	p_morphic_test():-
		zz_poly_dom:=poly_def(1,5),
		call_pd(zz_poly_dom),
		fail.
	p_morphic_test():-
		PD=poly_def(1,["an example","or two"]),
		call_pd(PD),
		fail.
	p_morphic_test():-
		Q= [poly_def(X, Y) || X= std::fromTo(1, 4),
					Y= std::fromTo(1, 5)],
		stdio::write("\n",Q),
		fail.
	p_morphic_test().
 
class predicates
	call_pd:(poly_dom{A,B}).
clauses
	call_pd(POLY_DOM):-
		stdio::write("\n",POLY_DOM),
		fail.
	call_pd(poly_def(A,B)):-%note this is POLY_DEF
		stdio::write("\n",A,B),
		fail.
	call_pd(_).

Properties

Properties in a class are used almost identically to fact variables, but properties can be set directly (from another class), without having to declare a public predicate to make the change.

Example

interface fred
    domains
        complete_dom=is_complete;
                not_complete.
    properties
        prop_complete : complete_dom.
end interface fred

In fred.pro:

facts
    zz_complete:complete_dom:=erroneous.
 
clauses %for the property
    prop_complete()=zz_complete. %get
    prop_complete(COMPLETE):-zz_complete:=COMPLETE. %set


In some other class that calls class fred:

implement other
    open fred
clauses
    pred():-
        Fred=fred::new(),
        Fred:prop_complete:=is_complete,% to set the value
        Value=Fred:prop_complete,!. %get


Comparators and compare

Anonymous predicates

(under development) See Anonymous_Predicates

Examples

clauses
    run() :-
        Anon={()=9},
        K=Anon().
        %results in K=9
    run() :-
        Anon={=88},
        K=Anon().
        %results in K=88.
    run():-
        Anon={(A,B)=A+B},
        K=Anon(4,8),
        %results in K=12.
    run():-
        Anon={
            (A,B)=C:-
            R=math::random(7),
            C=A+B+R,
            stdio::wRite("RRRR=",R)
            },
        K=Anon(4,8).
        %results in K=12 + a random number <7
 
    run():-
        Anon={=f_abc(3)},
        K=Anon(),
        stdio::write("\nI={=f_abc(3)} gives ",K),
        fail.
    run().


Threads

To start a thread:

clauses
    pred():-
        _=thread::start(fred).
 
predicates
    fred:().
clauses
    fred():-.....

fred can have no arguments, so no argument brackets are allowed:

    _=thread::start(fred())

is illegal. But the thread can access data prepared before it is started.

facts
    zz_int:integer:=erroneous.
clauses
    pred():-
        zz_int:=88,
        _=thread::start(fred).
 
predicates
    fred:().
clauses
    fred():-
        K=zz_int,
        ...