Can I use variables with assert/1?
Asked Answered
I

1

8

What I have now checks that X(Y) is not an accepted fact in my small DB. Since X(Y) returns false it will attempt to assert it. (I realize this presents problems when X is a rule and not a fact)

ifNotAdd(X,Y):-
    not(call(X,Y)),
    !,
    assert(X(Y)).

For example, let's say that this fact is in the DB

mammal(dolphin).

I ask ifNotAdd(mammal, elephant).

I want it to see that ? mammal(elephant). is false and then assert mammal(elephant).

Obviously the "assert(X(Y))." line is wrong but what do I replace it with? I'm trawling prolog documentation and forums for the answer but no luck so far. I'm also trying to write something that will do this on my own.

EDIT I need to edit the DB in order to have a dynamic database the user can interact with. I'm building an argument machine and I need to allow the user to tell the system that they "know the fact for sure" so that the system can deal with knowledge outside of it's domain.

In the vein of http://en.wikipedia.org/wiki/Reason_maintenance

Cheers,

Insistency answered 25/12, 2011 at 2:17 Comment(0)
D
8

You can use the univ operator =../2 to construct the term before asserting it (note that the predicate in question has to be declared dynamic for it to work) :

ifNotAdd(X,Y):-
    not(call(X,Y)),
    !,
    Term =.. [X, Y],
    assert(Term).

BTW if you want ifNotAdd/2 not to fail when it doesn't need to add the fact to the db, you should wrap that in a if structure, plus, not/1 is deprecated, (\+)/1 is preferred :

:- dynamic(mammal/1).

mammal(dolphin).

ifNotAdd(X, Y):-
    (   \+ call(X, Y)
     -> Term =.. [X, Y],
        assert(Term)
     ;  true).

But I'm not sure what you're trying to do is right there. Quite often when a beginner in prolog wants to manipulate the database it's because a particular prolog mechanism isn't properly understood. Then again you might not be a beginner and my remark could be dumb, in which case, just forget it ! But if you do are a beginner, you may want to precise what you're trying to achieve here so that we can confirm that those manipulations are needed !

Duprey answered 25/12, 2011 at 2:26 Comment(2)
Ah hah, I usually use not() just for readability when hacking it together the first time even though it's deprecated. Should have changed that for the post. Anyway that's exactly what I've been looking for. I haven't used prolog since the class I learned it in a while ago and am relearning. Totally forgot =../2 so that solves that. I'll clarify program above.Insistency
about your edit : seems a legit reason to manipulate the db : ]Duprey

© 2022 - 2024 — McMap. All rights reserved.