[m-users.] Tabling a semidet predicate
Volker Wysk
post at volker-wysk.de
Thu Jun 10 19:45:33 AEST 2021
Am Mittwoch, den 09.06.2021, 05:54 +1000 schrieb Zoltan Somogyi:
> 2021-06-08 22:47 GMT+10:00 "Volker Wysk" <post at volker-wysk.de>:
> > Hi!
> >
> > I have a semidet predicate, and want to achieve termination with tabling.
> > Like this:
> >
> >
> > :- pred test(int::in) is semidet.
> > :- pragma minimal_model(test/1).
> >
> > test(X) :- test(X).
> > test(1).
> > test(2).
>
> The way to achieve termination in this case is not to enable tabling,
> but to simply delete the first clause.
>
> > I'm not sure if I understand this fully. Is this the way to go?
>
> No. You have not told us anything about the *actual* program
> you are working on, but probably what you want is pragma memo,
> not pragma minimal_model.
What I'm trying to build is a miniature expert system. The following is a
simplified description.
It's about items (files on disk) and categories (directories). A file can be
member of several directories.
I have a type for terms:
:- type tterm
---> dir(string) % meaning "the file in question is member
% of this directory"
; and(tterm, tterm)
; or(tterm, tterm)
; not(tterm).
The rules are read from a text file and are stored like this:
:- type rules == multi_map(string, % rule head (directory name)
tterm). % rule body
The memberships of files in directories is stored like this:
:- type files == multi_map(string, % directory name
string). % file name
The central predicate checks if a file name satisfies a term:
:- pred check(rules::in, files::in, tterm::in, string::in) is semidet.
:- pragma memo(check/4).
I've used "pragma memo" now, instead of "pragma minimal_model", as you
suggested.
The inference goes like this:
check(Rules, Files, dir(Dir), File) :-
(
multi_map.search(Files, Dir, FilesL),
member(File, FilesL)
;
multi_map.search(Rules, Dir, Terme),
member(Term, Terme),
check(Rules, Files, Term, File)
).
check(Rules, Files, and(T1, T2), File) :-
check(Rules, Files, T1, File),
check(Rules, Files, T2, File).
check(Rules, Files, or(T1, T2), File) :-
(
check(Rules, Files, T1, File)
;
check(Rules, Files, T2, File)
).
check(Rules, Files, not(T), File) :-
not(check(Rules, Files, T, File)).
After I've changed from minimal_model to memo, it *appears* to work. Except
for it being *very* slow. I've done a trace and get only a few calls of
check/4 per second.
The "files" multimap has about 60000 entries. The "rules" multimap has some
100 entries. I suspect that Files has to be copied with every call of
check/4...
Can you tell what's going on, and how to do it right?
Best wishes,
Volker
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mercurylang.org/archives/users/attachments/20210610/ec24f80c/attachment.sig>
More information about the users
mailing list