[3315cb]: doc / html / pyke_syntax / krb_syntax / compound_premise.html Maximize Restore History

Download this file

compound_premise.html    385 lines (370 with data), 20.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Compound Premise Syntax</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="../../stylesheets/pyke.css" type="text/css" />
</head>
<body>
<table id="page-table">
<thead class="head">
<tr id="header1"><th id="header" colspan="3">
&nbsp;
</th></tr>
<tr id="header2">
<th id="crumb-left"></th>
<th id="crumb-line">
<div id="nav">
<ul>
<li><a href="../../index.html">Home</a></li>
<li>&gt;</li>
<li><a href="../index.html">Pyke Syntax</a></li>
<li>&gt;</li>
<li><a href="index.html">KRB Syntax</a></li>
<li>&gt;</li>
<li>Compound Premise</li>
</ul>
</div>
</th>
<th id="crumb-right"></th>
</tr>
</thead>
<tbody id="body">
<tr id="body-tr">
<td id="left-nav">
<div id="left-nav-div">
<div class="title-nav"><a href="../../index.html">Home</a></div><div class="nav-branch">
<div class="normal-nav"><a href="../../about_pyke/index.html">About Pyke</a></div>
<div class="normal-nav"><a href="../../logic_programming/index.html">Logic Programming</a></div>
<div class="normal-nav"><a href="../../knowledge_bases/index.html">Knowledge Bases</a></div>
<div class="title-nav"><a href="../index.html">Pyke Syntax</a></div><div class="nav-branch">
<div class="normal-nav"><a href="../kfb_syntax.html">KFB Syntax</a></div>
<div class="title-nav"><a href="index.html">KRB Syntax</a></div><div class="nav-branch">
<div class="normal-nav"><a href="fc_rule.html">Fc_rule</a></div>
<div class="normal-nav"><a href="bc_rule.html">Bc_rule</a></div>
<div class="normal-nav"><a href="pattern.html">Pattern</a></div>
<div class="normal-nav"><a href="compound_premise.html">Compound Premise</a></div>
<div class="normal-nav"><a href="python_premise.html">Python Premise</a></div>
</div>
<div class="normal-nav"><a href="../kqb_syntax.html">KQB Syntax</a></div>
</div>
<div class="normal-nav"><a href="../../using_pyke.html">Using Pyke</a></div>
<div class="normal-nav"><a href="../../examples.html">Examples</a></div>
<div class="normal-nav"><a href="../../PyCon2008-paper.html">PyCon 2008 Paper</a></div>
</div>
</div>
<div id="icons">
<div id="project-page">
<a href="http://sourceforge.net/projects/pyke/">Pyke Project Page</a>
</div>
Please Make a Donation:<br />
<a href="http://sourceforge.net/donate/index.php?group_id=207724">
<img src="http://images.sourceforge.net/images/project-support.jpg"
width="88" height="32" border="0"
alt="Support This Project" /> </a> <br /><br />
Hosted by: <br />
<a href="http://sourceforge.net/projects/pyke">
<img src="http://sflogo.sourceforge.net/sflogo.php?group_id=207724&amp;type=14"
width="150" height="40"
alt="Get Python Knowledge Engine (PyKE) at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a>
</div>
</td>
<td id="main-td">
<div id="main">
<a name="startcontent" id="startcontent"></a>
<div class="document" id="compound-premise-syntax">
<h1 class="title">Compound Premise Syntax</h1>
<p>There are three kinds of compound premises. These can be used in both
<a class="reference" href="fc_rule.html">forward-chaining rules</a> and <a class="reference" href="bc_rule.html">backward-chaining rules</a>, but the nested
premises within each of these are restricted to the kind of premises legal
for that kind of rule: <a class="reference" href="fc_rule.html#foreach-clause">fc_premise</a> for forward-chaining rules, and
<a class="reference" href="bc_rule.html#when-clause">bc_premise</a> for backward-chaining rules.</p>
<pre class="literal-block">
compound_premise ::= first_premise
| forall_premise
| notany_premise
</pre>
<div class="section">
<h2><a id="first-premise" name="first-premise">First Premise</a></h2>
<p>The <tt class="docutils literal"><span class="pre">first</span></tt> premise is used to prevent <a class="reference" href="../../logic_programming/rules/index.html#backtracking">backtracking</a> from finding subsequent
solutions to a set of premises. The <tt class="docutils literal"><span class="pre">first</span></tt> premise always fails on
backtracking (but does do backtracking <em>within</em> the nested premises).</p>
<pre class="literal-block">
first_premise ::= ['!'] 'first' premise
| ['!'] 'first' NL
INDENT
{premise NL}
DEINDENT
</pre>
<p>The <tt class="docutils literal"><span class="pre">!</span></tt> option can only be used in backward-chaining rules.</p>
<p>When used within backward-chaining rules, the nested premises may include any
type of <a class="reference" href="bc_rule.html#plan-spec">plan_spec</a>.</p>
</div>
<div class="section">
<h2><a id="forall-premise" name="forall-premise">Forall Premise</a></h2>
<p>The <tt class="docutils literal"><span class="pre">forall</span></tt> premise forces <a class="reference" href="../../logic_programming/rules/index.html#backtracking">backtracking</a> within the nested premises to
process all of the possible solutions found before the <tt class="docutils literal"><span class="pre">forall</span></tt> succeeds.
After the first success, the <tt class="docutils literal"><span class="pre">forall</span></tt> fails on backtracking.</p>
<pre class="literal-block">
forall_premise ::= 'forall' NL
INDENT
{premise NL}
DEINDENT
[ 'require' NL
INDENT
{premise NL}
DEINDENT ]
</pre>
<p>The premises within the <tt class="docutils literal"><span class="pre">require</span></tt> clause are tried for each solution found
to the <tt class="docutils literal"><span class="pre">forall</span></tt> clause. If these fail for any solution, then the entire
<tt class="docutils literal"><span class="pre">forall</span></tt> premise fails. Thus, the <tt class="docutils literal"><span class="pre">forall</span></tt> only succeeds if the
<tt class="docutils literal"><span class="pre">require</span></tt> premises are true for <em>all</em> solutions generated within the
<tt class="docutils literal"><span class="pre">forall</span></tt> clause. Thus, the <tt class="docutils literal"><span class="pre">forall</span></tt> clause may be read: &quot;Forall X,
require Y&quot;.</p>
<p>The <tt class="docutils literal"><span class="pre">forall</span></tt> always succeeds if the <tt class="docutils literal"><span class="pre">require</span></tt> clause is omitted (even if
no solutions are found to the nested premises). This can be used in
conjunction with <a class="reference" href="python_premise.html#python-statements">python_statements</a> to gather a list of results.</p>
<p>See <a class="reference" href="#notes-on-forall-and-notany-premises">Notes on Forall and Notany Premises</a> and <a class="reference" href="../../examples.html">Examples</a>, below.</p>
</div>
<div class="section">
<h2><a id="notany-premise" name="notany-premise">Notany Premise</a></h2>
<p>The <tt class="docutils literal"><span class="pre">notany</span></tt> premise only succeeds if no solution can be found to the nested
premises. <tt class="docutils literal"><span class="pre">Notany</span></tt> always fails on <a class="reference" href="../../logic_programming/rules/index.html#backtracking">backtracking</a>.</p>
<pre class="literal-block">
notany_premise ::= 'notany' NL
INDENT
{premise NL}
DEINDENT
</pre>
<p>See <a class="reference" href="#notes-on-forall-and-notany-premises">Notes on Forall and Notany Premises</a> and <a class="reference" href="../../examples.html">Examples</a>, below.</p>
</div>
<div class="section">
<h2><a id="notes-on-forall-and-notany-premises" name="notes-on-forall-and-notany-premises">Notes on Forall and Notany Premises</a></h2>
<ol class="arabic simple">
<li>All <a class="reference" href="pattern.html#pattern-variable">pattern variable</a> bindings made during the execution of a <tt class="docutils literal"><span class="pre">forall</span></tt>
or <tt class="docutils literal"><span class="pre">notany</span></tt> premise are undone before the premises following the
<tt class="docutils literal"><span class="pre">forall</span></tt> or <tt class="docutils literal"><span class="pre">notany</span></tt> are run.
Thus, <tt class="docutils literal"><span class="pre">forall</span></tt> and <tt class="docutils literal"><span class="pre">notany</span></tt> can be used to test
values produced by prior premises; but to generate values for subsequent
premises the values must be captured in Python variables within the
<tt class="docutils literal"><span class="pre">forall</span></tt> or <tt class="docutils literal"><span class="pre">notany</span></tt> clause before the <cite>pattern variables</cite> are unbound
(see <a class="reference" href="#computing-a-value-for-each-generated-value">Computing a Value for Each Generated Value</a>, below).</li>
<li>When used within <a class="reference" href="bc_rule.html">backward-chaining rules</a>, the only <a class="reference" href="bc_rule.html#plan-spec">plan_spec</a> allowed in
nested premises is the <tt class="docutils literal"><span class="pre">as</span></tt> clause.</li>
</ol>
</div>
<div class="section">
<h2><a id="examples" name="examples">Examples</a></h2>
<ul class="simple">
<li><a class="reference" href="#finding-the-first-solution-from-a-set-of-values">Finding the First Solution From a Set of Values</a></li>
<li><a class="reference" href="#testing-every-generated-value">Testing Every Generated Value</a></li>
<li><a class="reference" href="#computing-a-value-for-each-generated-value">Computing a Value for Each Generated Value</a></li>
<li><a class="reference" href="#iterating-on-tuples">Iterating on Tuples</a></li>
<li><a class="reference" href="#computing-values-for-all-generated-values-that-pass-a-test">Computing Values for All Generated Values that Pass a Test</a></li>
</ul>
<p>These examples use the following subgoals:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">generate_x($x)</span></tt> generates multiple solutions (as <tt class="docutils literal"><span class="pre">$x</span></tt>) that will be
looped over</li>
<li><tt class="docutils literal"><span class="pre">test_x($x)</span></tt> does some test on <tt class="docutils literal"><span class="pre">$x</span></tt></li>
<li><tt class="docutils literal"><span class="pre">compute_y($x,</span> <span class="pre">$y)</span></tt> takes <tt class="docutils literal"><span class="pre">$x</span></tt> as input and computes a <tt class="docutils literal"><span class="pre">$y</span></tt> value</li>
</ul>
<div class="section">
<h3><a id="finding-the-first-solution-from-a-set-of-values" name="finding-the-first-solution-from-a-set-of-values">Finding the First Solution From a Set of Values</a></h3>
<p>If you want the first <tt class="docutils literal"><span class="pre">$x</span></tt> that passes the <tt class="docutils literal"><span class="pre">test_x($x)</span></tt> test, you have two
options:</p>
<pre class="literal-block">
generate_x($x)
test_x($x)
...
</pre>
<p>And:</p>
<pre class="literal-block">
first
generate_x($x)
test_x($x)
...
</pre>
<p>The difference is that the first example will find other <tt class="docutils literal"><span class="pre">$x</span></tt> values that
pass <tt class="docutils literal"><span class="pre">test_x($x)</span></tt> on <a class="reference" href="../../logic_programming/rules/index.html#backtracking">backtracking</a>, while the second example will stop after
the first value is found and fail on backtracking.</p>
</div>
<div class="section">
<h3><a id="testing-every-generated-value" name="testing-every-generated-value">Testing Every Generated Value</a></h3>
<p>There are two general cases. You might want to verify that <tt class="docutils literal"><span class="pre">test_x($x)</span></tt>
<em>succeeds</em> for all generated <tt class="docutils literal"><span class="pre">$x</span></tt> values:</p>
<pre class="literal-block">
forall
generate_x($x)
require
test_x($x)
</pre>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">While <tt class="docutils literal"><span class="pre">$x</span></tt> is set and used within the <tt class="docutils literal"><span class="pre">forall</span></tt> premise to transfer
values from the <tt class="docutils literal"><span class="pre">generate_x($x)</span></tt> goal to the <tt class="docutils literal"><span class="pre">test_x($x)</span></tt> goal, it is
no longer set afterwards and can not be referenced in the premises
following the <tt class="docutils literal"><span class="pre">forall</span></tt> premise.</p>
</div>
<p>The second case that you might want to verify is that <tt class="docutils literal"><span class="pre">test_x($x)</span></tt> <em>fails</em>
for every generated <tt class="docutils literal"><span class="pre">$x</span></tt> value:</p>
<pre class="literal-block">
forall
generate_x($x)
require
notany
test_x($x)
</pre>
<p>Or, more simply:</p>
<pre class="literal-block">
notany
generate_x($x)
test_x($x)
</pre>
</div>
<div class="section">
<h3><a id="computing-a-value-for-each-generated-value" name="computing-a-value-for-each-generated-value">Computing a Value for Each Generated Value</a></h3>
<p>If you want a tuple of computed <tt class="docutils literal"><span class="pre">$y</span></tt> values for all of the <tt class="docutils literal"><span class="pre">$x</span></tt> values:</p>
<pre class="literal-block">
python y_list = []
forall
generate_x($x)
require
compute_x($x, $y)
python y_list.append($y)
$y_list = tuple(y_list)
</pre>
<p>This will only succeed if <tt class="docutils literal"><span class="pre">compute_y</span></tt> succeeds for every <tt class="docutils literal"><span class="pre">$x</span></tt> value.</p>
<p>If you want to skip over <tt class="docutils literal"><span class="pre">$x</span></tt> values that <tt class="docutils literal"><span class="pre">compute_y</span></tt> fails on, you
<em>might</em> try:</p>
<pre class="literal-block">
python y_list = []
forall
generate_x($x)
compute_x($x, $y)
python y_list.append($y)
$y_list = tuple(y_list)
</pre>
<p>But note that if <tt class="docutils literal"><span class="pre">compute_y</span></tt> computes multiple solutions for a single
<tt class="docutils literal"><span class="pre">$x</span></tt> value on <a class="reference" href="../../logic_programming/rules/index.html#backtracking">backtracking</a>, you would end up including all of these
solutions in your <tt class="docutils literal"><span class="pre">$y_list</span></tt>. To only get the first computed value for each
<tt class="docutils literal"><span class="pre">$x</span></tt> value:</p>
<pre class="literal-block">
python y_list = []
forall
generate_x($x)
first
compute_x($x, $y)
python y_list.append($y)
$y_list = tuple(y_list)
</pre>
</div>
<div class="section">
<h3><a id="iterating-on-tuples" name="iterating-on-tuples">Iterating on Tuples</a></h3>
<p>A simple common case of <tt class="docutils literal"><span class="pre">generate_x</span></tt> is when you are computing values for
each element of a tuple:</p>
<pre class="literal-block">
python y_list = []
forall
$x in $x_list
require
compute_x($x, $y)
python y_list.append($y)
$y_list = tuple(y_list)
</pre>
<p>This can also be done by creating a new subgoal that recurses on <tt class="docutils literal"><span class="pre">$x_list</span></tt>.
If you call the new subgoal <tt class="docutils literal"><span class="pre">compute_list</span></tt>, you would use it like this:</p>
<pre class="literal-block">
compute_list($x_list, $y_list)
</pre>
<p>And define it like this:</p>
<pre class="literal-block">
compute_list_done
use compute_list((), ())
compute_list_step
use compute_list(($x, *$x_rest), ($y, *$y_rest))
when
compute_y($x, $y)
compute_list($x_rest, $y_rest)
</pre>
<div class="important">
<p class="first admonition-title">Important</p>
<p>Note that there is an important difference between these two examples if
<tt class="docutils literal"><span class="pre">compute_y</span></tt> may find alternate <tt class="docutils literal"><span class="pre">$y</span></tt> values for any given <tt class="docutils literal"><span class="pre">$x</span></tt> value
on <a class="reference" href="../../logic_programming/rules/index.html#backtracking">backtracking</a>.</p>
<p>The first example will only generate one <tt class="docutils literal"><span class="pre">$y_list</span></tt>. If that <tt class="docutils literal"><span class="pre">$y_list</span></tt>
doesn't work for subsequent premises, the <tt class="docutils literal"><span class="pre">forall</span></tt> fails on backtracking,
so no overall solution will be found.</p>
<p class="last">The second example will not fail in this situation, but will produce all
possible combinations of solutions to <tt class="docutils literal"><span class="pre">compute_y</span></tt> for each <tt class="docutils literal"><span class="pre">$x</span></tt> on
backtracking until a resulting <tt class="docutils literal"><span class="pre">$y_list</span></tt> satisfies the subsequent
premises so that an overall solution <em>is</em> found.</p>
</div>
</div>
<div class="section">
<h3><a id="computing-values-for-all-generated-values-that-pass-a-test" name="computing-values-for-all-generated-values-that-pass-a-test">Computing Values for All Generated Values that Pass a Test</a></h3>
<p>Finally, if you want to gather only the computed <tt class="docutils literal"><span class="pre">$y</span></tt> values for <tt class="docutils literal"><span class="pre">$x</span></tt>
values that pass <tt class="docutils literal"><span class="pre">test_x($x)</span></tt>:</p>
<pre class="literal-block">
python y_list = []
forall
generate_x($x)
test_x($x)
require
compute_x($x, $y)
python y_list.append($y)
$y_list = tuple(y_list)
</pre>
<!-- ADD_LINKS MARKER -->
</div>
</div>
</div>
<!-- <div id="return-to-top">
<a href="#">Return to Top</a>
</div>
-->
</div>
</td>
<td id="right-nav">
<div id="right-nav-div">
<h3>More:</h3>
<div class="right-item"><a href="fc_rule.html">Fc_rule Syntax</a><p>The syntax of a forward-chaining rule.</p>
</div>
<div class="right-item"><a href="bc_rule.html">Bc_rule Syntax</a><p>The syntax of a backward-chaining rule.</p>
</div>
<div class="right-item"><a href="pattern.html">Pattern Syntax</a><p>The syntax of a pattern used to match data values.</p>
</div>
<div class="right-item"><a href="compound_premise.html">Compound Premise Syntax</a><p>The syntax of compound premises.</p>
</div>
<div class="right-item"><a href="python_premise.html">Python Premise Syntax</a><p>The syntax of a <em>python_premise</em>.</p>
</div>
</div>
</td>
</tr>
</tbody>
<tfoot id="foot">
<tr id="foot2">
<td id="copyright" colspan="3">
Copyright &copy; 2007-2009 Bruce Frederiksen
</td>
</tr>
</tfoot>
</table>
<div id="last-modified">
Page last modified
Mon, Oct 27 2008.
</div>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ?
"https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost +
"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-6310805-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
</body>
</html>