2010-07-18 53 views

回答

3
def add(n): 
    yield n 
    for m in add(n+1): 
     yield m 

遞歸發電機可以很容易地建立複雜的backtrackers:

def resolve(db, goals, cut_parent=0): 
    try: 
     head, tail = goals[0], goals[1:] 
    except IndexError: 
     yield {} 
     return 
    try: 
     predicate = (
      deepcopy(clause) 
       for clause in db[head.name] 
        if len(clause) == len(head) 
     ) 
    except KeyError: 
     return 
    trail = [] 
    for clause in predicate: 
     try: 
      unify(head, clause, trail) 
      for each in resolve(db, clause.body, cut_parent + 1): 
       for each in resolve(db, tail, cut_parent): 
        yield head.subst 
     except UnificationFailed: 
      continue 
     except Cut, cut: 
      if cut.parent == cut_parent: 
       raise 
      break 
     finally: 
      restore(trail) 
    else: 
     if is_cut(head): 
      raise Cut(cut_parent) 

... 

for substitutions in resolve(db, query): 
    print substitutions 

這是一個由遞歸生成器實現的Prolog引擎。 db是代表事實和規則的Prolog數據庫的字典。 unify()是統一函數,爲當前目標創建所有替換並將更改追加到追蹤中,以便稍後可以撤消它們。 restore()執行撤消操作,is_cut()測試當前目標是否爲'!',以便我們可以執行分支修剪。

+0

給出的添加示例沒有終止條件。你打算這麼做嗎? – Alice 2015-02-01 19:45:17

3

我不知道的意圖的「產量(n)或增加(N + 1)」,但遞歸發電機當然可能。您可能想閱讀下面的鏈接以瞭解可能的情況,特別是標題爲「遞歸生成器」的部分。

0

你的功能似乎我只想成爲綁定序列等表達:

N,N + 1,N + 2,...

def add(x): 
    while True: 
     yield x 
     x+=1 

for index in add(5): 
    if not index<100: break ## do equivalent of range(5,100) 
    print(index) 

這不是遞歸的,但我看到這裏不需要遞歸樣式。

基於其他的答案的鏈接,其中有發電機調用發電機,但不是遞歸上的遞歸版本:

from __future__ import generators 

def range_from(n): 
    yield n 
    for i in range_from(n+1): 
     yield i 

for i in range_from(5): 
    if not i<100: break ## until 100 (not including) 
    print i