1

Given this program, why am I forced to define every atom in the predicate, even if they're anonymous. Why is it that undefined variables in a dict predicate aren't thought of as anonymous?

funt2(X) :-
    X = point{x:5, y:6}.

evalfunt(point{x:5, y : 6}) :-
    write('hello world!').

evalfunt(point{x:_, y : _} ) :-
    write('GoodBye world!').

Why can't I just say

evalfunt(point{x:5}) :-
        write('GoodBye world!').

^that won't match, by the way.

I may as well just use a structure if I have to define every possible value in the dict to use dicts.

What's the motivation here? Can I do something to make my predicate terse? I'm trying to define a dict with 30 variables and this is a huge roadblock. It's going to increase my program size by a magnitude if I'm forced to define each variables (anonymous or not).

Brian Rosamilia
  • 1,448
  • 14
  • 24
  • I am not sure that I understand the question, but I think the main problem here is the understanding, that `dict` is just a complex data type, like tuple, which has data AND structure. If you have, for example two facts `fact(point{x:5, y:6}).` and `fact(point{x:5}).`, then the query `fact(point{x:_}).` will match the second one, but not the first one. And the query `fact(point{x:_, y:_}).` will match the first one, but not the second. – Eugene Sh. Mar 23 '15 at 14:22
  • The issue is having to define every field in the dict to define a matching predicate. Why is this? If all you care about is the value of X being 5, why must you write y: _ ... + EVERY other member in the dict – Brian Rosamilia Mar 23 '15 at 14:33
  • Because if you don't write them, it will potentially match dict's with different structure. – Eugene Sh. Mar 23 '15 at 14:35
  • 1
    If you want a shortcut, you can always define a rule that will do it for you – Eugene Sh. Mar 23 '15 at 14:37
  • Could you post an example? I was having trouble doing this without once again defining the dict. I'm a bit new to prolog. I'll accept an example of that as it will probably be terse enough. – Brian Rosamilia Mar 23 '15 at 14:44

2 Answers2

4

Dict is just a complex data type, like tuple, which has data AND structure. If you have, for example two facts:

fact(point{x:5, y:6}).
fact(point{x:5}).

Then the query

fact(point{x:_}).

will match the second one, but not the first one. And the query

fact(point{x:_, y:_}).

Will match the first one, but not the second.

Now, if you want to match facts of the form fact(point{x:_, y:_, z:_}) only by one specific field, you can always write a helper rule:

matchByX(X, P) :- fact(P), P=point{x:X, y:_, z:_}. 

So having facts:

fact(point{x:5, y:6, z:1}).
fact(point{x:1, y:2, z:3}).
fact(point{x:2, y:65, z:4}).

and quering

matchByX(1, P).

will return:

P = point{x:1, y:2, z:3}


UPDATE:
Moreover, in SWI-Prolog 7 version the field names can be matched as well, so it can be written in much more generic way, even for facts with different structures:

fact(point{x:5, y:6, z:1}).
fact(point{x:1, y:2}).
fact(point{x:2}).
fact(point{x:2, y:2}).

matchByField(F, X, P) :- fact(P), P.F = X.

So query:

?- matchByField(x, 2, P).
P = point{x:2} ;
P = point{x:2, y:2}.
Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
1

I was able to accomplish what I needed by doing the following

checkiffive(Y) :- 
        get_dict(x, Y, V), V=5.

You need to use the built in methods for unifying values from a dict.

Described in chapter 5.4 of the SWI prolog reference

http://www.swi-prolog.org/download/devel/doc/SWI-Prolog-7.1.16.pdf

Brian Rosamilia
  • 1,448
  • 14
  • 24