manipulating a compund term in Prolog

78f0b97754d9d585c2eedbff57a8f37d
0
keb5 101 Jun 09, 2006 at 11:19

Working in Prolog, I am trying to turn the compound term

admitPatient(P,oncology)

into

zadmitPatient1(P,oncology)

Is there some way of manipulating the head of the compound term (perhaps by temporarily separating it from the body?) so that it can be changed?

This is quite urgent so any and all help would be gratefully received!
Thanks,
Kirsty

13 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jun 09, 2006 at 16:10

This sounds like a homework question, and I am afraid we don’t help people with their homework on this site. Try looking in your textbook or asking your professor for help.

78f0b97754d9d585c2eedbff57a8f37d
0
keb5 101 Jun 09, 2006 at 18:45

Actually I am a PhD student trying to develop a system so this is not a “homework” question! The system is an AI planning system being developed to look at how classical planning paradigms can be applied to the computerisation of medical guidelines. The urgency is because I don’t want to delay the building of the rest of my system.

I am still in need of advice if anyone can help!!! :o)

Cff67041e0c439e1beefef7de6f864fe
0
Nodlehs 101 Jun 09, 2006 at 21:47

No offense, but it is homework.

You are a student, no matter your level, and you have a task involved in your schooling. Plus, I think if you are at a PhD level, that you would be able to find the information you are looking for in a prolog textbook or from a knowledgable Professor on campus.

78f0b97754d9d585c2eedbff57a8f37d
0
keb5 101 Jun 10, 2006 at 08:02

Ok I appreciate your stance on what constitutes homework and realise I am unlikely to get a response but I wanted to point out that before posting to this site I did check every text book I could find (including reference manuals of various prolog systems) and searched the internet. There are no Prolog experts at my university either (in fact it was my professor who suggested poting to forums!).
I only use forum postings as a last resort when all other resources have been exhausted.

6b7e1a4b42e4b47d92fdef8bf2bd8e2c
0
Jare 101 Jun 12, 2006 at 21:25

@keb5

There are no Prolog experts at my university either

Are there any Prolog experts left anywhere? ;) From what little I remember about that language, there is no answer to your question, but it’s been 15 years and I’m probably not even understanding the question itself. Given the lack of expertise around, I’d suggest revisiting the decision to use Prolog if at all possible.

B7dcbc0c0f07253f25ff5c25fe38c081
0
SamuraiCrow 101 Jun 13, 2006 at 04:21

I’m afraid Prolog is a one-of-a-kind language. There is no substitute. Even Lisp is a different type of processing than Prolog.

As for the question of how to do what the OP was proposing, I only had a two week orientation on Predicate Calculus so I don’t know of a way to do what was proposed but I’ll give it some thought.

-edit- It sounds to me like you could use a form of inheritance. Are you using an Object Prolog system or a traditional one?

-edit2- http://www.faqs.org/faqs/prolog/resource-guide/part1/section-7.html has some Object-Oriented layers to add to Prolog that you might find useful.

Fe76116c2453dd04043c163cf01e1e5e
0
itsbrian 101 Jul 19, 2006 at 03:07

I’m not yet sure how to seperate the head of the compound term perhaps someone else can help with that. If you are using SWI prolog one way of manipulating strings is to convert into a list of ascii code, do the manipulating then revert back to string. I’m only a beginner myself still learning but maybe this might help.

To asci:
?- name(admitPatient, L).

L = [97, 100, 109, 105, 116, 80, 97, 116, 105, 101, 110, 116] ;

No

To string:
?- name(N, [97, 100, 109, 105, 116, 80, 97, 116, 105, 101, 110, 116]).

N = admitPatient ;

No

Of course you still need code to do the seperation/manipulation/modification part!

4413189eb92ecb0c72aa193596bda383
0
Trap_D 101 Aug 29, 2006 at 23:16

In SWI-Prolog, to do that, you would use assert, retract, dynamic, forall.

2f9f82c36ec6a28702dc365e43753d79
0
Ooka 101 Aug 30, 2006 at 07:55

Never used prolog before, but google apparently still works :P

http://gnu-prolog.inria.fr/manual/manual067.html

That *seems* to define how you manipulate compound terms in prolog.

4413189eb92ecb0c72aa193596bda383
0
Trap_D 101 Aug 30, 2006 at 08:51

It *seems* to be “manipulating Prolog terms in C”

2f9f82c36ec6a28702dc365e43753d79
0
Ooka 101 Aug 30, 2006 at 20:24

never used prolog before, just trying to help, maybe steer him onto a different track. Googling his topic title brings up a few hundred thousand topics… the answer’s gotta be in there somewhere.

Fe76116c2453dd04043c163cf01e1e5e
0
itsbrian 101 Sep 12, 2006 at 08:12

Here’s one (crude) solution!

start(A, B, C, D) :-
        tell('filename.pl'),
        manipulate(A, B, C, D), !,
        told.
start(_, _, _, _) :-
        told.


manipulate(A, B, C, D) :-
        write(A),
        write(B),
        write(C),
        write(D),
        write('.').

Note: both admitPatient and (P,oncology) would each be contained in some variable (ALL terms preferably). Since i haven’t got terms as variables i’ll put the query in manually as follows:

start('z', 'admitPatient', '1', '(P,oncology)').

This writes the modified term to filename.pl.
Which contains the new predicate:

zadmitPatient1(P,oncology).

Then to use the new predicate could use:

consult('filename.pl').

Is crude but is a start and it works!

To do it dynamically I guess you would need to add this line:

:- dynamic admitPatient/2.

The infix operator ‘=..’ (pronounced “univ”) can be used either to
decompose a term into a list containing its functor and arguments or
else to construct a term from such a list.

http://wwwcgi.rdg.ac.uk:8081/cgi-bin/cgiwrap/wsi14/poplog/prolog/ploghelp/univ

i.e,

To extract the term ‘admitPatient’ perhaps a call similar to:

?- admitPatient(P, oncology) =.. [H|B] .

P = _G404
H = admitPatient
B = [_G404, oncology] ;

No

Variable H (inserted at paramater B in my ‘static’ code above for example) can then be manipulated; likewise Variable B (inserted at paramater D above).

:excl: Of course there’s a better way as i’m just a novice. :unsure:

4413189eb92ecb0c72aa193596bda383
0
Trap_D 101 Sep 12, 2006 at 12:32

As I understand the problem, I think you want to change the facts of the database admitPatient(P,oncology) into zadmitPatient1(P, oncology).

I suppose that your facts are in a file named “admitPatient.pl”, I modify the facts and I save the new database in “admitPatient1.pl”.

The change are made with this :

% the predicates must be declared dynamic because they will be changed
:-dynamic(admitPatient/2, zadmitPatient1/2).

my_test :-
        % reading the database
    consult('admitPatient.pl'),
        % opening the new database for writing
    tell('admitPatient1.pl'),
        % I work with all the patient of oncology
    forall(admitPatient(P, oncology),
           (  %  I remove the fact of the database
                  retract(admitPatient(P, oncology)),
                  % I add the new fact in the database
              assert(zadmitPatient1(P,oncology)),
                  % I save the fact in the file "admitPatient1.pl"
              write(zadmitPatient1(P,oncology)),
               nl)),
        % I save the rest of the database
    forall(admitPatient(X, Y),
           (   write(admitPatient(X,Y)),
               nl)),
        % it's done.
    told.