0
votes

Here is my simple program to test if else and function call in swi prolog. What is wrong with below code which says rule does not exist

call_rule(Roll):-
(
    member(Roll,[123]),
    writeln('inside call rule'),
    nb_getval(rule, 'this is the rule')
).
print_roll(Roll) :-
    (   Roll < 2 ->
        writeln('not a roll')
    ;
        (  Roll > 1243 ->
           writeln('not a roll'),writeln('this is 2nd alternative'),writeln('this is third alternative')
        ;
           ( Roll =:= 12 ->
                writeln('boxcars')
            ;
                ( call_rule(Roll) ->
                    nb_getval(rule, RULE),
            writeln('snake eyes')
                ;
                    nb_getval(rule,SUBJECT),
            writeln(SUBJECT)    
                )
            )
        )
    ).

result:

3 ?- print_roll(123).  
inside call rule
ERROR: nb_getval/2: variable `rule' does not exist
1
generally, you should avoid global variables, in any language, and much more in Prolog - CapelliC
I second what CappeliC wrote! Avoid nb_setval/2 and all predicates like it: They cannot be used as true relations and you therefore do not benefit from the usual advantages (generality etc.) of declarative solutions. - mat
@CapelliC: I could not understand your point. I am beginner in prolog, I learned this way of writing looking at various articles. I appreciate if you can show me optimal version of this code. - user2129623
@mat: thanks for pointing, but still muddleing to get advantage of generality - user2129623
@user2129623: Try to think in terms of relations. In this case, you apparently want to define a relation between a roll and its name, so think about (for example) roll_name/2. Generality: You can use such a predicate in all directions, for example: "Which rolls and names exist?" (?- roll_name(R, N).) or "Which rolls correspond to a given name?". nb_setval/2 and other predicates like it usually impose a single direction: You may be able to determine a name for a given roll, but not vice versa. Also, you cannot use your predicates in isolation any more, as you have already seen. - mat

1 Answers

1
votes

Before you can get a value from the non-backtrackable store, you need to nb_setval the key:

Example:

?- nb_getval(a,X).
ERROR: nb_getval/2: variable `a' does not exist
?- nb_setval(a,foo).
true.

?- nb_getval(a,X).
X = foo.