Import a predicate from a module that behaves as copy/paste

I would like to import a predicate pred from a module some_module without loading the modules used by some_module. So, basically I want to import pred like it is defined in some_module and nothing else.
That’s why use_module is not an option.
I could define pred in a separate file and import it in both places, but since some_module is already used by other project, I prefer to leave it intact.

In other words I would like something like \input{} of latex but instead of inserting an entire file, I would like only the predicate definition.

1 Like

You could use :- autoload/1,2 instead of :- use_module/1,2 to get the dependencies. In that case they will only be loaded when actually needed. This requires the development version (8.3.18 as we speak).

Other than that, loading a file without making its dependencies available doesn’t seem a sensible thing to do. After using use_module/1,2 you should have the guarantee that everything exported can be used. Just not loading the dependencies may make part of the module work and part not. As the module evolves that may change. This breaks the promises modules should give you.

You can move the predicate into its own module and simply import it using use_module/1,2 into the old module. Modules may export predicates that they import, allowing you to compose modules from smaller modules. You can also use :- reexport/1,2 for that. I’m always a little unsure whether or not that is a good idea as it makes it less obvious what is exported by a module.

Hope this helps.

1 Like

If you put pred into a separate file, then you could use the include/1 directive to get just its source, both in the place you want to “include” it and also in some_module.

1 Like

Thank you, I didn’t know about :-autoload/1,2 but for now I am using 8.2.0.

It happens that in a module there are predicates that are self-contained and those that depend on other user-defined modules. Probably, it is a bad design to put such predicates in a single module regardless they processing similar data.

clause-specific include/1 is what I am/was searching for.
include(FileName, ListOfClauses) could be a useful predicate that allows to cherry-pick certain clauses from existing projects. Advantage of it could be to prevent maintaining several copies of predicates.

How do you think something like that can work? The predicates may depend on other predicates or, even trickier, their compilation may depend on macros, operators, etc. appearing elsewhere in the file. You would have to load the entire file anyway, as also :- use_module(...) may pull in stuff that changes the compilation of the remainder of the file.

It is typically wise to make sure all your Prolog files are module files and import everything they need. That way you can blindly import a module and assume all it needs is loaded and you can actually use the predicates it exports.

Without some care that indeed leads to the situation where loading one module will load half the world. That indeed implies that stuff you see as reusable for other projects should not have undesired dependencies. In the situation you describe you can split the module in two pieces and simply make the module with lots of dependencies import the one without.

Another hacky solution is to use conditional compilation using :- if(condition). ..., etc. To include/exclude part of the code depending on some project related condition. It works, but I wouldn’t advice it.

The new autoaload/1,2 reduces load time and memory usage for applications running from the source code that typically need only a small part of the code loaded.

1 Like