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