Multiple modules definitions in one file?

Reading the DCG tutorial, it seems that he can define multiple modules in one file by end_module/1:

%% module1
:- module(english).
:- export(sentence/3).

% ...

:- end_module(english).

%% module2
:- module(spanish).
:- export(sentence/3).

% ...

:- end_module(spanish).
translate(LANG_IN, LANG_OUT, SENTENCE, TRANSLATION) :-
  call( LANG_IN:sentence(MEANING, SENTENCE, []) ),
  call( LANG_OUT:sentence(MEANING, TRANSLATION, []) ).

?- translate(english, spanish, [the,dog,chases,the,cow], T).
T = [el, perro, caza, la, vaca] 
yes

Does SWI-Prolog support the similar feature? I can’t found it in SWI-Prolog module manual.

Also, I can’t run his example in an elegant way.

english.pl

:- module(english, [sentence/3]).
sentence(s(S,V,O)) --> subject(S), verb(V), object(O).
subject(sb(M,N)) -->  modifier(M),  noun(N).
object(ob(M,N)) -->  modifier(M),  noun(N).

modifier(m(the)) --> [the].
noun(n(dog)) --> [dog].
noun(n(cow)) --> [cow].
verb(v(chases)) --> [chases].
verb(v(eats)) --> [eats].

spanish.pl

:- module(spanish, [sentence/3]).
sentence(s(S,V,O)) --> subject(S), verb(V), object(O).
subject(sb(M,N)) --> modifier(M, G), noun(N, G).
object(ob(M,N)) --> modifier(M, G), noun(N, G).

modifier(m(the),m) --> [el].
modifier(m(the),f) --> [la].
noun(n(dog),m) --> [perro].
noun(n(cow),f) --> [vaca].
verb(v(chases)) --> [caza].
verb(v(eats)) --> [come].

translate_module_conflict.pl

:- ['english.pl'].
:- ['spanish.pl'].

translate(LANG_IN, LANG_OUT, SENTENCE, TRANSLATION) :-
  call( LANG_IN:sentence(MEANING, SENTENCE, []) ),
  call( LANG_OUT:sentence(MEANING, TRANSLATION, []) ).
?- consult(["translate_module_conflict.pl "]).
ERROR: e:/work-pl/prolog/code/dcg/amzi/language_translation/translate_module_conflict.pl :8:
ERROR:    import/1: No permission to import spanish:sentence/3 into user (already imported from english)

Thanks.

Use

:- use_module(english, []).

Multiple modules in a file are supported with the low level primitives. For example library(plunit) uses this to place the test sets in what is actually a submodule of the module it is contained in.

3 Likes

For others looking for the source code to see how this is done.

If one expects to find the source by going to GitHub for the SWI-Prolog account and look at the development repository of GitHub one will find the library subdirectory but plunit is not there.

The code for plunit is actually in the repository packages-plunit. The use of library in alias library(plunit) is for the hook file_search_path/2 when the code is loaded. Understanding that is an acquired skill.

The code dealing with unit test, test modules is here.