Dwim and other errors, with very simple facts

I’m using: SWI-Prolog version ???
8.2.1

I want the code to:

return true or at least no error our

But what I’m getting is:

an error

My code looks like this:

isvaluable(gold).

The DWIM could not correct goal error occurs if I type a simple fact.

If I place all the facts (just facts, not rules) in a separate test.pl file and

chdir(‘c:/Personal_Programming/Prolog/SWI32’).

and

consult(facts).

or

[facts].

, it then says

c:/personal_programming/prolog/swi32/facts.pl:1:
ERROR: Arguments are not sufficiently instantiated

I installed SwI Prolog 8.2.1 on a different laptop, than the ones I used in the past.

I know that others have reported similar messages, but this was the simplest code possible.

When I first read it I thought it all looked correct but the fact that you gave just the right amount of detail I tried to reproduce your problem and upon doing so immediately identified your problem and how to solve it.


You are working in a directory, for this example I will C:/Users/Groot/Documents.

Now in that directory you create a file test.pl

File: test.pl

isvaluable(gold).

Then you start up SWI-Prolog

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.8)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- 

use chdir/1 to change the directory within the top level.

?- chdir('C:/Users/Groot/Documents').
true.

and to verify the directory is correct I will add a step to check it

?- pwd.
% c:/users/groot/documents/
true.

then you loaded the facts using

[facts].

and received an error

?- [facts].
ERROR: source_sink `facts' does not exist
ERROR: In:
ERROR:   [22] throw(error(existence_error(source_sink,facts),_26960))
ERROR:   [18] '$resolve_source_path'(facts,_26992,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2313
ERROR:   [17] '$load_file'(facts,user,[expand(false),...]) at c:/program files/swipl/boot/init.pl:2287
ERROR:    [9] toplevel_call(user:user: ...) at c:/program files/swipl/boot/toplevel.pl:1113
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

which is not the same as the one you received.

However if instead the consult is done as

?- [test].
true.

because test is the name of file (test.pl) without the filetype then

?- isvaluable(Valuable).
Valuable = gold.

it works as expected.


While the use of chdir/1 will work, in Prolog the customary way to change the working directory is to use working_directory/2, e.g.

?- working_directory(_,'C:/Users/Groot/Documents').
true.

I don’t understand what the distinction is between

[facts].

and

[test].

, if either of them reflect the names of a file that actually exists.

But aside from that,

The DWIM error isn’t occurring from consulting a file. It’s occurring from manually inserting a single fact, like

isvaluable(gold).

The consult is leading to the error that Arguments are not sufficiently instantiated.

So we’re talking two separate errors -

  1. a simple fact like isvaluable(gold). leads to a DWIM error

  2. Consulting an existing file, leads to Arguments are not sufficiently instantiated.

I’ve never experienced this probem before. I think I’ll try this on another laptop altogether, just to see what happens.

You should switch to user stream

example

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.8-2-g3c22b06)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- [user].
|: a(1).
|: a(2).
|: ^D% user://1 compiled 0.05 sec, 2 clauses
true.

?- a(X).
X = 1 ;
X = 2.

Thanks CapelliC, but I don’t understand this syntax, specifically the 3rd parameter with the ^D% etc.

At any rate, I installed this on a fresh Windows 7 laptop, and am able to load existing .pl databases, without error. I can do this, whether SWI’s working folder is left at the default, or if I change to another folder.

So, e.g. in test.pl I set the following facts:

isvaluable(gold).
isfemale(jane).
isfemale(karen).
owner_owned(jane,gold).
father_child(john,mary).
person_gift_recipient(john,book,mary).

However, I can’t add new facts directly. So e.g. after loading test.pl, if I try to add a new fact, the DWIM error occurs again.

?- howareyou(terrific).
ERROR: Unknown procedure: howareyou/1 (DWIM could not correct goal)
?- 

You’re saying that changing the stream might help, but I don’t know why, and don’t understand the syntax.

If I just stick with facts and predicates from external consulted database, I think it should be ok. It’s just confusing, because I’ve been using another Prolog variant for a while. I came back to SWI, because of their rich XML module.

No, you cannot add facts like this. When you do this:

?- howareyou(terrific).

… you are querying the existing facts! In order to add this as a fact, you can do several things:

  1. add it to a file and consult the file
  2. Use the assert* predicates for this.
  3. Add it to the user module.

The first option should be clear. The second option looks like this:

?- assertz(howareyou(terrific)).
true.

?- howareyou(X).
X = terrific.

The third option was shown to you by @CapelliC. You “consult” the user module, this lets you t ype in your definitions. You close this mode using Ctrl+D, on *nix systems (End-of-file signal). It might be something else on Windows (was it Ctrl+Z? might depend on the terminal emulator you are using, actually… not sure). On my system:

?- [user].
|: howareyou(terrific).
|: ^D% user://1 compiled 0.02 sec, 1 clauses
true.

?- howareyou(X).
X = terrific.

The “|: ^D” means I was at the |: prompt and I typed Ctrl+D (signal EOF). The “% user://...” is a comment telling you what happened.

1 Like

See: Managing (dynamic) predicates

For a higher level overview see: Database

As other have noted

You can also use end_of_file. to exit consult mode, (ref), e.g.

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.8)

?- [user].
|: likes(mary,john).
|: end_of_file.

% user://1 compiled 0.02 sec, 1 clauses
true.

?- likes(mary,Who).
Who = john.

?- listing(likes).
likes(mary, john).

true.

Ok, I understand all of this, now. The ^D was confusing, because I don’t remember ever having to do it. Also, it looked like ‘^D’ followed by a percentage sign.

Yes, I understand about consulting, of course.

The main problem is that I haven’t used SWI a great deal, and not recently. The other implementations that I’ve been working with allow you to just type rules, the same as if you were typing them in a database.

Everything’s working fine, now. Thanks everyone, for the assistance.

1 Like