[1aa849]: doc / html / using_pyke.html Maximize Restore History

Download this file

using_pyke.html    508 lines (496 with data), 30.1 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
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
<!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>Using Pyke</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>Using Pyke</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="normal-nav"><a href="pyke_syntax/index.html">Pyke Syntax</a></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="using-pyke">
<h1 class="title">Using Pyke</h1>
<p>This describes how to call Pyke from within your Python program.</p>
<div class="section" id="initializing-pyke">
<h2>Initializing Pyke</h2>
<p>There are two steps to initializing a Pyke knowledge engine:</p>
<dl class="docutils">
<dt>knowledge_engine.engine(*paths, **kws)</dt>
<dd><p class="first">The Pyke inference engine is offered as a class so that you can
instantiate multiple copies of it with different rule bases to accomplish
different tasks.</p>
<p>Once you have a <tt class="docutils literal"><span class="pre">knowledge_engine.engine</span></tt> object; generally, all of
the functions that you need are provided directly by this object:</p>
<pre class="doctest-block">
&gt;&gt;&gt; from pyke import knowledge_engine
&gt;&gt;&gt; my_engine = knowledge_engine.engine('doc.examples')
</pre>
<p>Pyke requires that all Pyke source files be placed (either directly or
indirectly) under a Python <a class="reference external" href="http://www.python.org/doc/essays/packages.html">package</a> directory. These packages must be
on Python's search path for modules, and the directory for each dotted
name must include an <tt class="docutils literal"><span class="pre">__init__.py</span></tt> file.</p>
<p>Each <tt class="docutils literal"><span class="pre">paths</span></tt> argument represents a different Python package directory to
search for Pyke source files. These source packages may be passed either
as package names (as a string in Python's standard dotted notation), as
the packages themselves, or as any module within the package. Thus, the
example above could also be written:</p>
<pre class="doctest-block">
&gt;&gt;&gt; from doc import examples
&gt;&gt;&gt; my_engine = knowledge_engine.engine(examples)
</pre>
<p>or</p>
<pre class="doctest-block">
&gt;&gt;&gt; from doc.examples import some_module
&gt;&gt;&gt; my_engine = knowledge_engine.engine(some_module)
</pre>
<p>Pyke recursively walks each source package directory looking for Pyke
source files (<a class="reference external" href="pyke_syntax/kfb_syntax.html">.kfb files</a>, <a class="reference external" href="pyke_syntax/krb_syntax/index.html">.krb files</a>, and <a class="reference external" href="pyke_syntax/kqb_syntax.html">.kqb files</a>). Each
source file that it finds is compiled, if out of date, and then imported
(depending on the keyword arguments, see below). This causes all of the
<a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a> to be loaded and made ready to <a class="reference external" href="using_pyke.html#setting-up-each-case">activate</a>.</p>
<p>If you change some of your Pyke source files, you can create a new engine
object to compile and reload the generated Python modules without
restarting your program. But note that you'll need to rerun the
<tt class="docutils literal"><span class="pre">add_universal_fact</span></tt> calls that you made outside of your <a class="reference external" href="pyke_syntax/kfb_syntax.html">.kfb files</a>.</p>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">It is OK for your source package directory to be part of a zipped
<a class="reference external" href="http://peak.telecommunity.com/DevCenter/PythonEggs">Python egg file</a>. But, in this case, Pyke can't rebuild and recompile
the source files. It will just import the compiled file that is there
without complaining if the source file has a later modification time
than the compiled file.</p>
</div>
<p>All of the Python source files and pickle files generated from each source
package are placed, by default, in a <tt class="docutils literal"><span class="pre">compiled_krb</span></tt> package directly
subordinate to that source package. You may specify a different
destination package for any source package by passing that source package
along with the destination package name as a 2-tuple. The destination
package name may be specified as an absolute Python module path; or as a
relative path (with leading dots), relative to the source package. Thus,
specifying the default destination explicitly would look like:</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine = knowledge_engine.engine(('doc.examples', '.compiled_krb'))
</pre>
<p>You may specify the same destination package for multiple source packages.</p>
<p>The last component of the destination package will be created automatically
if it does not already exist.</p>
<p>You probably want to add <tt class="docutils literal"><span class="pre">compiled_krb</span></tt> (or whatever you've chosen to
call it) to your source code repository's list of files to ignore.</p>
<p>There are four optional keyword arguments that you may also pass to the
<tt class="docutils literal"><span class="pre">engine</span></tt> constructor:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">load_fc</span></tt> -- load forward-chaining rules</li>
<li><tt class="docutils literal"><span class="pre">load_bc</span></tt> -- load backward-chaining rules</li>
<li><tt class="docutils literal"><span class="pre">load_fb</span></tt> -- load fact bases and</li>
<li><tt class="docutils literal"><span class="pre">load_qb</span></tt> -- load question bases</li>
</ul>
<p class="last">These parameters must be passed as keyword parameters. They all default
to <tt class="docutils literal"><span class="pre">True</span></tt>.</p>
</dd>
<dt><em>some_engine</em>.add_universal_fact(kb_name, fact_name, arguments)</dt>
<dd><p class="first">The <tt class="docutils literal"><span class="pre">add_universal_fact</span></tt> function is called once per <a class="reference external" href="knowledge_bases/fact_bases.html#facts">fact</a>. These
<a class="reference external" href="knowledge_bases/fact_bases.html#facts">facts</a> are never deleted and apply to all <em>cases</em>.</p>
<p>Alternatively, you can place universal facts in a <a class="reference external" href="pyke_syntax/kfb_syntax.html">.kfb file</a> so that
they are loaded automatically.</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.add_universal_fact('family', 'son_of', ('bruce', 'thomas'))
</pre>
<p>Multiple facts with the same name are allowed.</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.add_universal_fact('family', 'son_of', ('david', 'bruce'))
</pre>
<p>But duplicate facts (with the same arguments) are silently ignored.</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.add_universal_fact('family', 'son_of', ('david', 'bruce'))
&gt;&gt;&gt; my_engine.get_kb('family').dump_universal_facts()
son_of('bruce', 'thomas')
son_of('david', 'bruce')
</pre>
<p class="last">These facts are accessed as <tt class="docutils literal"><span class="pre">kb_name.fact_name(arguments)</span></tt> within the
<a class="reference external" href="pyke_syntax/krb_syntax/index.html">.krb files</a>.</p>
</dd>
</dl>
</div>
<div class="section" id="setting-up-each-case">
<h2>Setting up Each Case</h2>
<p>Pyke is designed to be run multiple times for multiple <em>cases</em>. In
general each case has its own set of starting <a class="reference external" href="knowledge_bases/fact_bases.html#facts">facts</a> and may use different
<a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a>, depending upon the situation.</p>
<p>Three functions initialize each case:</p>
<dl class="docutils">
<dt><em>some_engine</em>.reset()</dt>
<dd>The <tt class="docutils literal"><span class="pre">reset</span></tt> function is called once to delete all of the <a class="reference external" href="knowledge_bases/fact_bases.html#case-specific-facts">case specific
facts</a> from the last run. It also deactivates all <a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a>.</dd>
<dt><em>some_engine</em>.assert_(kb_name, fact_name, arguments)</dt>
<dd><p class="first">Call <tt class="docutils literal"><span class="pre">assert_</span></tt> (or the equivalent, <tt class="docutils literal"><span class="pre">add_case_specific_fact</span></tt>,
see <a class="reference internal" href="#other-functions">Other Functions</a>, below) for each starting <a class="reference external" href="knowledge_bases/fact_bases.html#facts">fact</a> for this case.
Like universal facts, you may have multiple facts with the same name so
long as they have different arguments.</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.assert_('family', 'son_of', ('michael', 'bruce'))
&gt;&gt;&gt; my_engine.assert_('family', 'son_of', ('fred', 'thomas'))
&gt;&gt;&gt; my_engine.assert_('family', 'son_of', ('fred', 'thomas'))
</pre>
<p>Duplicates with universal facts are also ignored.</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.assert_('family', 'son_of', ('bruce', 'thomas'))
&gt;&gt;&gt; my_engine.get_kb('family').dump_specific_facts()
son_of('michael', 'bruce')
son_of('fred', 'thomas')
&gt;&gt;&gt; my_engine.get_kb('family').dump_universal_facts()
son_of('bruce', 'thomas')
son_of('david', 'bruce')
</pre>
<p>There is no difference within the <a class="reference external" href="pyke_syntax/krb_syntax/index.html">.krb files</a> of how universal facts
verses case specific facts are used. The only difference between the two
types of facts is that the case specific facts are deleted when a <tt class="docutils literal"><span class="pre">reset</span></tt>
is done.</p>
<pre class="last doctest-block">
&gt;&gt;&gt; my_engine.reset()
&gt;&gt;&gt; my_engine.get_kb('family').dump_specific_facts()
&gt;&gt;&gt; my_engine.get_kb('family').dump_universal_facts()
son_of('bruce', 'thomas')
son_of('david', 'bruce')
</pre>
</dd>
<dt><em>some_engine</em>.activate(*rb_names)</dt>
<dd><p class="first">Then call <tt class="docutils literal"><span class="pre">activate</span></tt> to activate the appropriate <a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a>. This
may be called more than once, if desired, or it can simply take multiple
arguments.</p>
<pre class="last doctest-block">
&gt;&gt;&gt; my_engine.activate('bc_example')
</pre>
</dd>
</dl>
<p>Your Pyke engine is now ready to prove goals for this case!</p>
</div>
<div class="section" id="proving-goals">
<h2>Proving Goals</h2>
<p>Two functions are provided that cover the easy cases. More general
functions are provided in <a class="reference internal" href="#other-functions">Other Functions</a>, below.</p>
<dl class="docutils">
<dt><em>some_engine</em>.prove_1(kb_name, entity_name, fixed_args, num_returns)</dt>
<dd><p class="first"><tt class="docutils literal"><span class="pre">Kb_name</span></tt> may name either a <a class="reference external" href="knowledge_bases/fact_bases.html">fact base</a>, <a class="reference external" href="knowledge_bases/question_bases.html">question base</a> or
<a class="reference external" href="knowledge_bases/rule_bases.html#rule-base-categories">rule base category</a>.</p>
<p>The <tt class="docutils literal"><span class="pre">entity_name</span></tt> is the fact name for fact bases, question name for
question bases or the name of the <a class="reference external" href="logic_programming/rules/backward_chaining.html">backward chaining</a> goal for
<a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a>.</p>
<p>The <tt class="docutils literal"><span class="pre">fixed_args</span></tt> are a tuple of Python values. These form the first
set of arguments to the proof. <tt class="docutils literal"><span class="pre">Num_returns</span></tt> specifies the number of
additional <a class="reference external" href="logic_programming/pattern_matching/pattern_variables.html">pattern variables</a> to be appended to these arguments for the
proof. The bindings of these pattern variables will be returned as a
tuple in the answer for the proof. For example:</p>
<blockquote>
<em>some_engine</em>.prove_1(<em>some_rule_base_category</em>, <em>some_goal</em>, (1, 2, 3), 2)</blockquote>
<p>Proves the goal:</p>
<blockquote>
<em>some_rule_base_category.some_goal</em> (1, 2, 3, $ans_0, $ans_1)</blockquote>
<p>And will return the bindings produced by the proof as (<tt class="docutils literal"><span class="pre">$ans_0</span></tt>,
<tt class="docutils literal"><span class="pre">$ans_1</span></tt>).</p>
<p class="last">Returns the first proof found as a 2-tuple: a tuple of the bindings for
the <tt class="docutils literal"><span class="pre">num_returns</span></tt> pattern variables, and a <a class="reference external" href="logic_programming/plans.html">plan</a>. The plan is <tt class="docutils literal"><span class="pre">None</span></tt>
if no plan was generated; otherwise, it is a Python function as
described <a class="reference external" href="#running-and-pickling-plans">below</a>.</p>
</dd>
</dl>
<blockquote>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.prove_1('bc_example', 'father_son', ('thomas', 'david'), 1)
((('grand',),), None)
</pre>
<p>Raises <tt class="docutils literal"><span class="pre">pyke.knowledge_engine.CanNotProve</span></tt> if no proof is found.</p>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.prove_1('bc_example', 'father_son', ('thomas', 'bogus'), 1)
Traceback (most recent call last):
...
pyke.knowledge_engine.CanNotProve: Can not prove bc_example.father_son(thomas, bogus, $ans_0)
</pre>
</blockquote>
<dl class="docutils">
<dt><em>some_engine</em>.prove_n(kb_name, entity_name, fixed_args, num_returns)</dt>
<dd><p class="first">This returns a context manager for a generator yielding 2-tuples, a tuple
whose length == <tt class="docutils literal"><span class="pre">num_returns</span></tt> and a <a class="reference external" href="logic_programming/plans.html">plan</a>, for each possible proof.
Like <tt class="docutils literal"><span class="pre">prove_1</span></tt>, the plan is None if no plan was generated. Unlike
<tt class="docutils literal"><span class="pre">prove_1</span></tt> it does not raise an exception if no proof is found.</p>
<pre class="last doctest-block">
&gt;&gt;&gt; from __future__ import with_statement
&gt;&gt;&gt; with my_engine.prove_n('bc_example', 'father_son', ('thomas',), 2) as gen:
... for ans in gen:
... print(ans)
(('bruce', ()), None)
(('david', ('grand',)), None)
</pre>
</dd>
</dl>
<div class="section" id="running-and-pickling-plans">
<h3>Running and Pickling Plans</h3>
<p>Once you've obtained a <a class="reference external" href="logic_programming/plans.html">plan</a> from <tt class="docutils literal"><span class="pre">prove_1</span></tt> or <tt class="docutils literal"><span class="pre">prove_n</span></tt>, you just call
it like a normal Python function. The arguments required are simply those
specified, if any, in the <a class="reference external" href="pyke_syntax/krb_syntax/bc_rule.html#taking-clause">taking clause</a> of the <a class="reference external" href="pyke_syntax/krb_syntax/bc_rule.html">rule</a> proving the top-level
goal.</p>
<p>You may call the plan function any number of times. You may even pickle
the plan for later use. The plans are constructed out of
<a class="reference external" href="http://docs.python.org/library/functools.html">functools.partial</a> functions, which had to be registered with <a class="reference external" href="http://docs.python.org/3.0/library/copyreg.html">copyreg</a>
before you could pickle them in older Python releases. But in Python3 it is
no longer necessary to register functools.partial to be able to pickle them.</p>
<p>No special code is required to unpickle a plan. Just unpickle and call it.
(Unpickling the plan only imports one small Pyke module to be able to run
the plan).</p>
</div>
<div class="section" id="tracing-rules">
<h3>Tracing Rules</h3>
<p>Individual rules may be traced to aid in debugging. The <tt class="docutils literal"><span class="pre">trace</span></tt> function
takes two arguments: the rule base name, and the name of the rule to trace:</p>
<blockquote>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.trace('bc_example', 'grand_father_son')
&gt;&gt;&gt; my_engine.prove_1('bc_example', 'father_son', ('thomas', 'david'), 1)
bc_example.grand_father_son('thomas', 'david', '$ans_0')
bc_example.grand_father_son succeeded with ('thomas', 'david', ('grand',))
((('grand',),), None)
</pre>
</blockquote>
<p>This can be done either before or after rule base activation and will remain
in effect until you call <tt class="docutils literal"><span class="pre">untrace</span></tt>:</p>
<blockquote>
<pre class="doctest-block">
&gt;&gt;&gt; my_engine.untrace('bc_example', 'grand_father_son')
&gt;&gt;&gt; my_engine.prove_1('bc_example', 'father_son', ('thomas', 'david'), 1)
((('grand',),), None)
</pre>
</blockquote>
</div>
<div class="section" id="krb-traceback">
<h3>Krb_traceback</h3>
<p>A handy traceback module is provided to convert Python functions, lines and
line numbers to the <a class="reference external" href="pyke_syntax/krb_syntax/index.html">.krb file</a> rule names, lines and line numbers in a
Python traceback. This makes it much easier to read the tracebacks that occur
during proofs.</p>
<p>The <tt class="docutils literal"><span class="pre">krb_traceback</span></tt> module has exactly the same functions as the standard
Python <a class="reference external" href="http://docs.python.org/library/traceback.html">traceback</a> module, but they convert the generated Python function
information into .krb file information. They also delete the intervening
Python functions between subgoal proofs.</p>
<blockquote>
<pre class="doctest-block">
&gt;&gt;&gt; import sys
&gt;&gt;&gt; from pyke import knowledge_engine
&gt;&gt;&gt; from pyke import krb_traceback
&gt;&gt;&gt;
&gt;&gt;&gt; my_engine = knowledge_engine.engine('doc.examples')
&gt;&gt;&gt; my_engine.activate('error_test')
&gt;&gt;&gt; try: # doctest: +ELLIPSIS
... my_engine.prove_1('error_test', 'goal', (), 0)
... except:
... krb_traceback.print_exc(None, sys.stdout) # sys.stdout needed for doctest
Traceback (most recent call last):
File &quot;&lt;doctest using_pyke.txt[34]&gt;&quot;, line 2, in &lt;module&gt;
my_engine.prove_1('error_test', 'goal', (), 0)
File &quot;...knowledge_engine.py&quot;, line 289, in prove_1
return next(iter(it))
File &quot;...knowledge_engine.py&quot;, line 273, in gen
for plan in it:
File &quot;...rule_base.py&quot;, line 46, in __next__
return next(self.iterator)
File &quot;...error_test.krb&quot;, line 26, in rule1
goal2()
File &quot;...error_test.krb&quot;, line 31, in rule2
goal3()
File &quot;...error_test.krb&quot;, line 36, in rule3
goal4()
File &quot;...error_test.krb&quot;, line 41, in rule4
check $bar &gt; 0
File &quot;...contexts.py&quot;, line 227, in lookup_data
raise KeyError(&quot;$%s not bound&quot; % var_name)
KeyError: '$bar not bound'
</pre>
</blockquote>
</div>
</div>
<div class="section" id="other-functions">
<h2>Other Functions</h2>
<p>There are a few more functions that may be useful in special situations.</p>
<p>The first two of these provide more general access to the <a class="reference external" href="knowledge_bases/fact_bases.html#facts">fact</a> lookup and
goal proof mechanisms. The catch is that you must first convert <strong>all</strong>
arguments into <a class="reference external" href="#creating-your-own-patterns">patterns</a> and create a <em>context</em> for these patterns. This is
discussed <a class="reference internal" href="#creating-your-own-patterns">below</a>.</p>
<dl class="docutils">
<dt><em>some_engine</em>.lookup(kb_name, entity_name, pattern_context, patterns)</dt>
<dd>This returns a context manager for a generator that binds <a class="reference external" href="#creating-your-own-patterns">patterns</a> to
successive <a class="reference external" href="knowledge_bases/fact_bases.html#facts">facts</a>. Yields <tt class="docutils literal"><span class="pre">None</span></tt> for each successful match.</dd>
<dt><em>some_engine</em>.prove(kb_name, entity_name, pattern_context, patterns)</dt>
<dd>Returns a context manager for a generator that binds <a class="reference external" href="#creating-your-own-patterns">patterns</a> to
successive proofs. Yields a <em>prototype_plan</em> or <tt class="docutils literal"><span class="pre">None</span></tt> for each
successful match. To turn the prototype_plan into a Python function,
use <em>prototype_plan</em>.create_plan(). This returns the <a class="reference external" href="logic_programming/plans.html">plan</a> function.</dd>
</dl>
<p>The remaining functions are:</p>
<dl class="docutils">
<dt><em>some_engine</em>.add_case_specific_fact(kb_name, fact_name, args)</dt>
<dd>This is an alternate to the <tt class="docutils literal"><span class="pre">assert_</span></tt> function.</dd>
<dt><em>some_engine</em>.get_kb(kb_name)</dt>
<dd>Finds and returns the <a class="reference external" href="knowledge_bases/index.html">knowledge base</a> by the name <tt class="docutils literal"><span class="pre">kb_name</span></tt>. Raises
<tt class="docutils literal"><span class="pre">KeyError</span></tt> if not found. Note that for <a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a>, this returns the
active <a class="reference external" href="knowledge_bases/rule_bases.html">rule base</a> where <tt class="docutils literal"><span class="pre">kb_name</span></tt> is the <a class="reference external" href="knowledge_bases/rule_bases.html#rule-base-categories">rule base category</a> name.
Thus, not all <a class="reference external" href="knowledge_bases/rule_bases.html">rule bases</a> are accessible through this call.</dd>
<dt><em>some_engine</em>.get_rb(rb_name)</dt>
<dd>Finds and returns the <a class="reference external" href="knowledge_bases/rule_bases.html">rule base</a> by the name <tt class="docutils literal"><span class="pre">rb_name</span></tt>. Raises
<tt class="docutils literal"><span class="pre">KeyError</span></tt> if not found. This works for any <a class="reference external" href="knowledge_bases/rule_bases.html">rule base</a>, whether it
is <a class="reference external" href="knowledge_bases/rule_bases.html#rule-base-activation">active</a> or not.</dd>
<dt><em>some_engine</em>.print_stats([f = sys.stdout])</dt>
<dd>Prints a brief set of statistics for each knowledge base to file <tt class="docutils literal"><span class="pre">f</span></tt>.
These are reset by the <tt class="docutils literal"><span class="pre">reset</span></tt> function. This will show how many facts
were asserted, and counts of how many forward-chaining rules were fired
and rerun, as well as counts of how many backward-chaining goals were
tried, and how many backward-chaining rules matched, succeeded and failed.
Note that one backward-chaining rule may succeed many times through
backtracking.</dd>
</dl>
<div class="section" id="creating-your-own-patterns">
<h3>Creating Your Own Patterns</h3>
<p>You'll need two more Pyke modules to create your own <a class="reference external" href="logic_programming/pattern_matching/index.html">patterns</a> and contexts:</p>
<blockquote>
<pre class="doctest-block">
&gt;&gt;&gt; from pyke import pattern, contexts
</pre>
</blockquote>
<p>There are four kinds of patterns:</p>
<dl class="docutils">
<dt>pattern.pattern_literal(data)</dt>
<dd>This matches the <tt class="docutils literal"><span class="pre">data</span></tt> provided.</dd>
<dt>pattern.pattern_tuple((elements), rest_var = None)</dt>
<dd>This matches a tuple. <tt class="docutils literal"><span class="pre">Elements</span></tt> must each be a pattern and must
match the first <em>n</em> elements of the tuple. <tt class="docutils literal"><span class="pre">Rest_var</span></tt> must be a
variable (or anonymous). It will match the rest of the tuple and is
always bound to a (possibly empty) tuple.</dd>
<dt>contexts.variable(name)</dt>
<dd>This will match anything the first time it is encountered and becomes
bound to that value. After that, it only matches this bound value each
additional time it is encountered. Calling the constructor twice with
the same name produces the same variable and must match the same value
in all of the places that it is used.</dd>
<dt>contexts.anonymous(name)</dt>
<dd>This will match anything each time it is encountered. Calling the
constructor many times with the same name is not a problem. The name
must start with an underscore.</dd>
</dl>
<p>Finally, to create a <em>pattern context</em>, you need:</p>
<blockquote>
contexts.simple_context()</blockquote>
<p>You'll need to save this context to lookup your variable values after each
proof is yielded. This is done by either:</p>
<blockquote>
<div class="line-block">
<div class="line"><em>some_context</em>.lookup_data(<em>variable_name</em>)</div>
<div class="line"><em>some_variable</em>.as_data(<em>some_context</em>)</div>
</div>
</blockquote>
<!-- 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="about_pyke/index.html">About Pyke</a><p>What pyke does for you, its features, steps to using pyke and
installation.</p>
</div>
<div class="right-item"><a href="logic_programming/index.html">Logic Programming Tutorial</a><p>A tutorial on logic programming in Pyke, including <em>statements</em>,
<em>pattern matching</em> and <em>rules</em>.</p>
</div>
<div class="right-item"><a href="knowledge_bases/index.html">Knowledge Bases</a><p>Knowledge is made up of both <em>facts</em> and <em>rules</em>. These are gathered
into named repositories called <em>knowledge bases</em>.</p>
</div>
<div class="right-item"><a href="pyke_syntax/index.html">Pyke Syntax</a><p>The syntax of Pyke's three different kinds of source files.</p>
</div>
<div class="right-item"><a href="using_pyke.html">Using Pyke</a><p>How your Python program uses Pyke. I.e., Pyke's API to Python.</p>
</div>
<div class="right-item"><a href="examples.html">Examples</a><p>An overview of the examples provided with Pyke.</p>
</div>
<div class="right-item"><a href="PyCon2008-paper.html">Applying Expert System Technology to Code Reuse with Pyke</a><p>Paper presented at the PyCon 2008 conference in Chicago.</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
Tue, Oct 20 2009.
</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>