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

**URL:** <https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547>\
**Category:** Help!\
**Tags:** how-to\
**Created:** [February 1, 2021, 3:30pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547 "2021-02-01T15:30:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kowalsky](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kowalsky/32/394_2.png) [@kowalsky](https://swi-prolog.discourse.group/u/kowalsky)\
**Post date:** [February 1, 2021, 3:30pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547/1 "2021-02-01T15:30:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 1, 2021, 5:32pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547/2 "2021-02-01T17:32:51Z")

</div>

> [@kowalsky](#):
>
> 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.

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.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [February 1, 2021, 5:46pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547/3 "2021-02-01T17:46:39Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![kowalsky](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kowalsky/32/394_2.png) [@kowalsky](https://swi-prolog.discourse.group/u/kowalsky)\
**Post date:** [February 3, 2021, 4:29pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547/4 "2021-02-03T16:29:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![kowalsky](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/kowalsky/32/394_2.png) [@kowalsky](https://swi-prolog.discourse.group/u/kowalsky)\
**Post date:** [February 3, 2021, 4:38pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547/5 "2021-02-03T16:38:05Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 3, 2021, 4:59pm UTC](https://swi-prolog.discourse.group/t/import-a-predicate-from-a-module-that-behaves-as-copy-paste/3547/6 "2021-02-03T16:59:52Z")

</div>

> [@kowalsky](#):
>
> `include(FileName, ListOfClauses)` could be a useful predicate that allows to cherry-pick certain clauses from existing projects.

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.
