Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!brutus.cs.uiuc.edu!lll-winken!elroy.jpl.nasa.gov!ames!uhccux!munnari.oz.au!murtoa.cs.mu.oz.au!kemp From: kemp@cs.mu.oz.au (David Barry Kemp) Newsgroups: comp.lang.prolog Subject: Re: elementary problem (I hope) Message-ID: <2984@murtoa.cs.mu.oz.au> Date: 12 Mar 90 04:48:15 GMT References: <1990Mar9.095655.4191@bath.ac.uk> <2972@goanna.oz.au> Organization: Comp Sci, Melbourne Uni, Australia Lines: 95 ok@goanna.oz.au (Richard O'keefe) writes: (The original question...) >In article <1990Mar9.095655.4191@bath.ac.uk> >ccsdgdc@gdr.bath.ac.uk (Douglas Clark) writes: >>A user has been asking me how to write synonyms in Prolog. >>Being ignorant I have no idea. >>It is obvious why the natural >>father(X) :- male(X). >>male(X) :- father(X). >>father(fred). >>fails. But I cannot find a substitute that works. Some way of eliminating >>the repetitive backtracking. Help would be appreciated. (Richard's suggestion) >If you have two predicates p and q such that p iff and only if q, then all >you have to do is to pick one of them, say p, and decide to take it as basic. >What you do is include the axiom > q(X) :- p(X). >If this is the only clause for q, then p and q cannot possibly differ at >any point. YOU DON'T NEED TO DO ANYTHING TO P TO MAKE THIS SO. >..... >In this particular example, to make sure that father/1 and male/1 have >exactly the same set of answers, and that fred is a father, it suffices >to write > male(X) :- father(X). % make male, father equivalent > father(fred). % define father NOTE: If you have facts (unit clauses) for both male and father, then the database will need to be re-arranged so that all of them are stored as facts for father only. BUT If you already have code that asserts or retracts facts for male, then these will all need to be changed to asserts/retracts for father. Todd Feldman's solution almost avoids this, except for an important point given by Richard. >In article <1990Mar10.120125.12992@Neon.Stanford.EDU>, >feldman@Neon.Stanford.EDU (Todd J. Feldman) writes: >> How about: > >> father(X):- >> not(tried(male(X))), >> assert(tried(male(X))), >> male(X). >> male(X):- >> not(tried(father(X))), >> assert(tried(father(X))), >> father(X). (Richard's comment) >This does not work at all if you ask a question with a variable in it. >Suppose I ask > ?- male(fred), male(X). >Given the fact father(fred), this should succeed with X = fred. >... > ...An approach > which might work rather nicely would be to use extension tables. >But the simplest approach is just not to put the loop there in the first >place. I agree. However, if you really did want the two predicates to become equivalent, then the original suggestion of adding the rules father(X):-male(X). male(X):-father(X). would have worked exactly as you intended on one of the deductive database systems currently appearing/being developed that use minimal model semantics, since what you really wanted is the minimum model that satisfies these rules along with the database of male and father facts. To efficiently evaluate queries and avoid infinite loops, the extension tables that Richard refers to may be used (there is a lot of research into finding even better methods). ------------ David B. Kemp Key Centre for Knowledge Base Systems Department of Computer Science University of Melbourne Parkville 3052 Australia e_mail: kemp@cs.mu.OZ.AU Telephone: 61 3 344 7877 Fax: 61 3 348 1184 ------------