Path: utzoo!attcan!uunet!husc6!mailrus!cornell!rochester!daemon From: stuart Newsgroups: comp.lang.prolog Subject: Re: Need style advice Message-ID: <1988Jul17.003242.1874@cs.rochester.edu> Date: 17 Jul 88 04:32:41 GMT Organization: U of Rochester, CS Dept, Rochester, NY Lines: 90 From: stuart Summary: More information about intended behavior References: <1988Jul14.231619.22145@cs.rochester.edu>, <170@quintus.UUCP> > Richard O'Keefe responds to my query with: > Note that the code as written is not steadfast: > ?- foo_value(X, value_3). > will succeed for ANY value of X, even when forced_to_be_1(X). > Remember: a cut at the end of a clause is almost always in the wrong place. Urk. Yes. Ok, that's the first problem. My intent is to use the value in the head of the first satisfied clause, using value_3 only when no previous clause can be satisfied. Your reminder is appreciated, but it would be more useful if I were also made acquainted with how things *should* be done. > Would it be possible for you to tell us what the relation is supposed to > _mean_, rather than showing us the current version of the code? Yes, my apologies if this description includes irrelevant detail. I have a graph with two colors of arcs, and two kinds of colors of nodes. foo_value/2 is to give values to nodes based on graph connectivity and coloring. The first kind node color distinguishes between "forced_to_be_1" and otherwise. If a node is forced_to_be_1, it receives value_1, otherwise we consider its neighbors. We look, first, for neighbors from whom X can inherit value_2. If no such neighbors can be found, we look for neighbors from whom to inherit value_1. If we fond no neighbors from whom value_2 or value_1 can be inherited, we give X the value_3. This is what I intended to express through the ordering of clauses. (1) Is the decision forced, (2) Can we find a value_2, (3) Can we find a value_1, (4) In all other cases, value_3. There are two ways for X to inherit a value from a neighbor, and that is what the pairs of clauses (2&3 and 4&5) were intended to express. relation_one(X, Y) is satisfied when node X is connected to node Y by an arc of the first color, and node Y has a particular value of the second kind of node color. X receives a value based directly on the first kind of node coloring of Y. relation_two(X, Y) is satisfied when node X is connected to a node _ by an arc of the first color, and node _ is connected to node Y by an arc of the second color. (The second kind of node coloring is irrelevant in this case.) X receives the same value that Y receives. > For example, the following values for forced_to_be_1/1 and relation_one/2 > [ some clauses deleted ] > appears to satisfy the description given, yet both > relation_one(tom, mary), \+forced_to_be_1(mary) > and relation_one(tom, jim), forced_to_be_1(jim) > are true, so should foo_value(tom, value_2) or foo_value(tom, value_1)? foo_value(tom, value_2). My intent is to try the four steps I gave above, stopping the first time a step succeeds. I suppose I should stress that I want foo_value to succeed exactly *once* in all cases. > Presumably there is some finite number of Xs which you intend to assign > foo_values to. If that number is not too big, why not just write a > program to generate the table and write the results to a file, then > compile that file? Well, if there were only one graph of interest, I'd do that, but this *is* a (evidently incorrect) program to generate the table! (Actually, it's my attempt to express more-or-less declaratively what a C program is busy doing on a dynamically changing graph structure, but you get the idea.) **************** Clearly, I have not gone about things the right way. My suspicions that things could be improved motivated my query in the first place. I frankly hadn't noticed the "steadfast"ness bug. So, what is the recommended form for simple decision trees in Prolog? How do I obtain the intended behavior? Unless I receive strong urging to the contrary, I would like to *avoid* rewriting the clause bodies to something like the following: foo_value(X, a) :- pred_a(X). foo_value(X, b) :- \+pred_a(X), pred_b(X). foo_value(X, c) :- \+pred_a(X), \+pred_b(X), pred_c(X). foo_value(X, d) :- \+pred_a(X), \+pred_b(X), \+pred_c(X). This is "pure", but I find it harder to read and understand. I suspect that it's also considerably less efficient. If not so, please urge otherwise. Stu Friedberg {ames,cmcl2,rutgers}!rochester!stuart stuart@cs.rochester.edu