[net.lang.prolog] Help - how do I avoid circularity here?

dave@lsuc.UUCP (David Sherman) (05/11/86)

I'm designing a large Prolog program for corporate tax planning
under Canadian income tax law. I want to include the following
definitions:

tptype(Taxpayer, corporation) :- tptype(Taxpayer, ccpc).

Let's call this a "type 1" definition. ccpc stands for
Canadian-controlled private corporation, a term used in
our income tax system. The purpose of this definition, and
dozens like it, is to say "if I'm told as part of the facts
entered by the user that we have a CCPC, then of course it's
a corporation". Of course, if the facts contain the statement
"tptype(xyzcorp, ccpc).", then any rules which depend on xyzcorp
being a corporation, a private corporation, a Canadian corporation
or a CCPC should all be satisfied.

Now I have another set of rules. Let's call them "type 2".
Type 2 rules let Prolog figure out, from the various facts
given, WHETHER a corporation is, for example, a CCPC. A type
2 rule might be:

tptype(Taxpayer, ccpc) :-
	tptype(Taxpayer, corporation),
	resident(Taxpayer, canada),
	[etc.... various other things which need to be tested,
	 for the corporation to be both Canadian-controlled and
	 private].

So if the person entering the facts has entered facts sufficient
to deduce that a corporation is a CCPC, without having explicitly
said so, any rules which depend on a corporation being a CCPC
can still be satisfied.

Now comes the problem. When I have both type 1 and type 2
rules in place, I get circularity. Putting in a cut doesn't
help if the rules are never satisfied (when the rule is tested
against a taxpayer who is an individual, for example).
(I can't put a cut right after the ":-", because there may be
lots of different facts which would cause tptype(Taxpayer, corporation)
to be true, and I want to test them all. I just don't want one of
them to come back and ask tptype(Taxpayer, corporation) again.)

Now, I've come up with a partial solution. I can say:
	tptype(Taxpayer, corporation) :-
		clause(tptype(Taxpayer, ccpc), true).
which stops the circularity. However, then I lose the deductive
ability, which means that for a chain of reasoning I have to
test each case individually with "clause". (For example, CCPC
implies private corporation and private corporation implies
corporation. But if I'm testing for the facts with "clause",
I have to have three rules: corporation if privatecorporation;
privatecorporation if ccpc; and corporation if ccpc.)

Is there any other solution which will stop the circularity?
Is there a way I can tell Prolog "if you've been here before
with these facts, you're in a loop, so fail", without saying,
as the cut does, that it should then fail for all of the
various definitions of the predicate?

Thanks in advance for any suggestions. I'm using C-Prolog 1.2a,
if it matters.

David Sherman
The Law Society of Upper Canada
Osgoode Hall
Toronto, Canada  M5H 2N6
(416) 947 3466
-- 
{ ihnp4!utzoo  pesnta  utcs  hcr  decvax!utcsri  } !lsuc!dave

cdsm@doc.ic.ac.uk (Chris Moss) (05/15/86)

In article <1211@lsuc.UUCP> dave@lsuc.UUCP (David Sherman) writes:
>I'm designing a large Prolog program for corporate tax planning
>under Canadian income tax law. I want to include the following
>definitions:
>
>tptype(Taxpayer, corporation) :- tptype(Taxpayer, ccpc).
>
>Let's call this a "type 1" definition. ... A type
>2 rule might be:
>
>tptype(Taxpayer, ccpc) :-
>	tptype(Taxpayer, corporation),
>Now comes the problem. When I have both type 1 and type 2
>rules in place, I get circularity. 

Well known problem. Structural solution as follows: split your predicate
into two parts, one of rules, the other facts which do not have any
recursive calls.  Add a reference from first to second. By this time
you will rarely if ever need directly recursive calls. 
e.g.
   tptype(Taxpayer, corporation) :- tptypefact(Taxpayer, ccpc).
   tptype(Taxpayer, ccpc) :-	tptypefact(Taxpayer, corporation).
   tptype(Taxpayer, Type) :- tptypefact(Taxpayer, Type).

Chris Moss, Imperial College London.
cdsm@ic.doc.ac.uk or cdsm@icdoc.uucp