Pyke 邏輯編程入門(17):知識庫之“特別庫”

來源:互聯網
上載者:User
特別庫

只有一個“特別的”知識庫,名叫 special。

特別知識庫裡裝的是各種輔助性知識,以有趣的形式,確定陳述是否真實。

特別庫裡的知識項是 Python 函數,在程式運行中做些“特別”的事情。

這些“特別”的函數是:

  • 函數 claim_goal
  • 函數 check_command
  • 函數 command
  • 函數 general_command
函數 Claim_goal

函數 claim_goal 沒有參數。

special.claim_goal()

它的行為方式,像是 Prolog 的 cut 操作。

一般有多個規則,用於嘗試證明目標(結論)是否成立。規則應用的順序,按其在 .krb 檔案中的排列,逐一嘗試。一個規則失敗,就接著試下一個。規則全部失敗,則目標失敗。

樣本

假設我要把數字 N 解釋成“N 只狗”,就用到以下規則:

one_dog    use n_dogs(1, '1 dog')n_dogs    use n_dogs($n, $phrase)    when        $phrase = "%d dogs" % $n

程式的邏輯有問題。當 n 等於 1 時,兩個規則都要用到,但第二個規則不能正確適用。這時,函數 special.claim_goal() 可以解決這個問題:

one_dog    use n_dogs(1, '1 dog')    when        special.claim_goal()n_dogs    use n_dogs($n, $phrase)    when        $phrase = "%d dogs" % $n

在 n 等於 1 時,special.claim_goal() 阻止適用第二個規則。

說明

規則 when 子句裡調用函數 special.claim_goal() 時,其餘的規則不再參與證明原目標。於是,如果 special.claim_goal() 引起回溯,目標立即失敗,不再試用別的規則。

這種結束的方式,就像 if-then-else 結構中的“else”的作用。只有當規則 when 子句中的前提條件真實正確時,才能在其後使用 special.claim_goal()

你不必在其後適用的規則中,添加額外的前提條件,去確保它們沒有發生。

如果上例中沒有函數 special.claim_goal(),你只好這樣寫:

one_dog    use n_dogs(1, '1 dog')n_dogs    use n_dogs($n, $phrase)    when        check $n != 1        $phrase = "%d dogs" % $n

這個簡單的例子,很容易在第二個規則中,加入命令 check。不過,一般地說,檢查以前出現的條件是很困難的,尤其如果涉及到多個規則,並且它們有各自的條件。

運行命令

其餘三個函數,在你的 Pyke 程式運行時,以命令運行處理其他程式。這三個函數執行後,有不同的輸出結果。

這三個函數,都使用 Python 標準庫函數 subprocess.Popen。

這三個函數,都有以下三個參數,傳遞給 subprocess.Popen:

  • 必須的參數 $command。

    • 它是個元組,告訴程式按照參數的值運行,例如 (ls, '-l')。
  • 可選的參數 $cwd。
    • 指定程式當前啟動並執行硬碟目錄。
    • 如果未設值,或設為 None,則當前工作目錄保持不變。
  • 可選的參數 $stdin。
    • 是個字串,指明程式的標準輸入。

      • 如果程式的輸入有多行,$stdin 必須包括嵌入的新行,如:“line 1/nline 2/n”。
    • 如果未設值,或設為 None,則該程式沒有標準輸入。

如果發生回溯,這些函數全部失敗。

函數 Check_command
special.check_command($command [, $cwd [, $stdin]])

如果 $command 程式運行返回 0,它適用成功;返回其他值,失敗。程式向 stdout 和 stderr 的輸出,無意義。

>>> from pyke import knowledge_engine>>> engine = knowledge_engine.engine()>>> engine.prove_1_goal('special.check_command((true))')({}, None)>>> engine.prove_1_goal('special.check_command((false))')Traceback (most recent call last):    ...CanNotProve: Can not prove special.check_command((false))
函數 Command
special.command($stdout, $command [, $cwd [, $stdin]])

它輸出到 stdout。$command 程式向 stderr 的輸出,無意義。

$stdout 是包含多行內容的元組,行尾的分行符號都刪除了。

如果程式傳回值不是 0,則引發意外 subprocess.CalledProcessError。

>>> from __future__ import with_statement>>> from pyke import pattern, contexts>>> def run_command(entity, command, cwd=None, stdin=None):...     with engine.prove_goal(...            'special.%s($output, $command, $cwd, $stdin)' % entity,...            command=command,...            cwd=cwd,...            stdin=stdin) /...       as gen:...         for vars, no_plan in gen:...             print vars['output']>>> run_command('command', ('echo', 'hi', 'mom'))('hi mom',)>>> run_command('command', ('ls',))   # doctest: +NORMALIZE_WHITESPACE('fact_bases.txt', 'index.txt', 'links', 'question_bases.txt', 'rule_bases.txt', 'special.txt')>>> run_command('command', ('ls', '-l', 'links')) # doctest: +ELLIPSIS('-rw-r--r-- 1 ... links',)>>> run_command('command', ('tail', '-n', '5', 'template.txt', '-'),...             '..',   # cwd (doc/source)...             'stdin: line 1/nstdin: line 2/nstdin: line 3/n')...     # doctest: +NORMALIZE_WHITESPACE('==> template.txt <==', '   } catch(err) {}', '  ', '', '', '', '', '==> standard input <==', 'stdin: line 1', 'stdin: line 2', 'stdin: line 3')>>> run_command('command', ('false',))Traceback (most recent call last):    ...CalledProcessError: Command 'false' returned non-zero exit status 1
special.general_command($output, $command [, $cwd [, $stdin]])

$command 程式給你全部輸出的最一般的形式。

$output 是有三個成員的元組:(exit_status, stdout, stderr)。stdout 和 stderr 都是有分行符號的字串。

>>> run_command('general_command', ('echo', 'hi', 'mom'))(0, 'hi mom/n', '')>>> run_command('general_command', ('cat', 'foobar'))(1, '', 'cat: foobar: No such file or directory/n')>>> run_command('general_command', ('tail', '-n', '5', '../../r2w.ini', 'foobar'))...     # doctest: +NORMALIZE_WHITESPACE(1, "==> ../../r2w.ini <==/ntarget_directory = 'html'/nmacros =     ''/n/n[uservalues]/nversion = '0.2'/n", "tail: cannot open `foobar' for reading: No such file or directory/n")

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.