Search code examples
loadingswi-prologlogtalk

Prolog SWI : Logtalk, How do I load my own project files?


so this week consisted of me installing Logtalk, one of the extensions for Prolog. In this case I'm using Prolog SWI, and I've run into a little snag. I'm not sure how to actually consult my own projects using Logtalk. I have taken a look at the examples that Logtalk comes with in order to understand the code itself, and in doing so I've been able to load them and execute them perfectly. What I don't understand though is what is actually going on when logtalk is loading a file, and how I can load my own projects.

I'll take the "hello_world" example as the point of discussion. The file called hello_world, is located in the examples folder of the Logtalk files. and yet it is consulted like so:

| ?- logtalk_load(hello_world(loader)).

First thing I thought was "that is a functor", looking at what it was doing using trace, I found that it was being called from the library and was being told how to get to the examples folder, where it then opened the "hello_world" folder and then the "loader" file. After which normal compiling happened.

I took a look at the library and couldn't figure out what was going on. I also thought that this can't possibly be the practical route to load user created projects in Logtalk. There was another post that was asking how to do this with SWI as well, but it didn't have any replies and didn't look like any effort had been made to figure the problem out.

Now let me be clear on something, I can use the "consult('...')." command just fine, I can even use "consult" to open my projects, however if I do this the logtalk console doesn't seem to be using any of the logtalk extensions and so is just vanilla prolog. I've used an installer for windows to install logtalk and I know that it is working as I've been looking at the examples that it comes with.

I've tried to find a tutorial but it is very difficult to find much of anything for Logtalk, the most I have found is this documentation on loading from within your project:

logtalk_load/1.
logtalk_load/2.

which I understand like so:

logtalk_load(file). % Top level loading
logtalk_load(folder(file). % Bottom level loading

So to save a huge manual load each time I would have a loader file that will load the other components of my project (which is what the examples for Logtalk do). This bit makes sense to me, I think, how I get to my loader file, doesn't.

Whether or not I have been understanding it correctly or not remains to be seen, but even if I have been understanding it correctly, I'm still lost as to how I load my own projects. Thanks for any help you can give, if you could give an example that'll be best as I do learn from examples quite quickly.

LITTLE UPDATE

You asked if I was using a logtalk console for my program running, and I am, I'm using the one that is provided and referred to during the "QUICK_START" file [Start > Programs > Logtalk > "Logtalk - Prolog-SWI (console)"] I thought to double check if the logtalk add ons were working and tested the "birds" example since it uses objects and is a nice familiar example. Yet again, everything works fine when using the logtalk_load/2 functor.

I took a look at what the library path was referring to a bit more given the feedback given so far. Looking into how logtalk loads files. Set up as it is so far, without changing things logtalk consults a folder which contains a prolog file called libpaths. It is basically how the examples are found, all it is is a part way description for where to get a file from. So when I say "logtalk_load/2" from what I can tell at least I'm going to this file and finding where the folder is that I'm asking for.

Now since I have already placed my own project folder in the examples folder, I promptly added my own folder to the list to test if this would at least be a part way solution to help me understand things a bit more. I added the following to the libpaths.pl file.

logtalk_library_path(my_project, examples('my_project/')).
% The path must end in a / so I have done so

So, I've got my folder path declared, got my folder, and the loader file is what I'll be calling when I use the loader. Without thinking about setting my own lib path folder, I should have enough to get things working and do some practical learning. But alas no, seems my investigation failed and I was returned the following:

ERROR: Unhandled exception: existence_error(library,project_aim)

Not what I wanted to see, I'm back to this library error business. I'm missing a reference to my project folder somewhere but I don't know where else it could need referencing. Running trace on the matter didn't help I simply had the following occur:

Call: (17) logtalk_library_path(my_project, _G943) ? creep
Fail: (17) logtalk_library_path(my_project, _G943) ? creep
ERROR: Unhandled exception: existence_error(library,my_project)

The call is failing, I'm simply not finding a reference where ever it is logtalk is looking. And I'm a novice at best when it comes to these sorts of issues, I've been using computers now for only 3 years and programming for the past 2 in visual studios using c# and c++. At least I've shone some more light on the matter, any more helpful advice given this information?


Solution

  • Please use the official Logtalk support channels for help in the future. You will get timely replies there. Daniel, thanks for providing help to this user.

    I assume that you're using Logtalk 2.x. Note that Logtalk 3.x supports relative and full source file paths. In Logtalk 2.x, the logtalk_compile/1-2 (compile to disk) and logtalk_load/1-2 (compile and load into memory) predicates take either the name of a source file (without the .lgt extension) OR the location of the source file to be loaded using "library notation". To use the former you need first to change the current working directory to the directory containing the file. This makes the second option more flexible. As you mention, the hello_world example you cite, can be loaded by typing:

    ?- logtalk_load(hello_world(loader)).
    

    or:

    ?- {hello_world(loader)}.
    

    Logtalk 2.x and 3.x also provide integration with some SWI-Prolog features such as consult/1, make/0, edit/0-1, the graphical tracer and the graphical profiler. For example:

    ?- [hello_world(loader)].
    
    ********** Hello World! **********
    % [ /Users/pmoura/logtalk/examples/hello_world/hello_world.lgt loaded ]
    % [ /Users/pmoura/logtalk/examples/hello_world/loader.lgt loaded ]
    % (0 warnings)
    true.
    

    To load your own examples and projects, the easiest way is to add a library path to the directory holding your files to the $LOGTALKUSER/settings.lgt file (%LOGTALKUSER%\settings.lgt on Windows) as Daniel explained. The location of the Logtalk user directory is defined by you when using the provided installer. The default is My Documents\Logtalk in Windows. Editing the libpaths.pl file is not a good idea. Use the settings.lgt file preferentially to define your own library paths. Assuming, as it seems to be your case, that you have created a %LOGTALKUSER%\examples\project_aim directory, add the following lines to your %LOGTALKUSER%\settings.lgt file:

    :- multifile(logtalk_library_path/2).
    :- dynamic(logtalk_library_path/2).
    
    logtalk_library_path(project_aim, examples('project_aim/').
    

    If you have a %LOGTALKUSER%\examples\project_aim\loader.lgt file, you can then load it by typing:

    ?- {project_aim(loader)}.
    

    Hope this helps.