https://www.oreilly.co.jp/books/9784873118727/
上記url の 6章の写経の続き。
「23, 4, 27, 17, 13, 10, 21, 29, 3, 32, 11, 19」から素数を抽出します。
#!/usr/local/python3/bin/python3 # -*- coding: utf-8 -*- import itertools # イテレータ関数群 import kanren from kanren.core import success, fail import sympy def main(): x = kanren.var() list_nums = (23, 4, 27, 17, 13, 10, 21, 29, 3, 32, 11, 19) print( 'List of primes in the list:' ) # 「membero, x, list_nums」= xに対するlist_numsの要素判定 # 「check_prime, x」= xに対する素数判定 # 多分「run(0, ...)」は解を無限に収集し,「run(7, ...)」は解を7個、収集する print( set( kanren.run(0, x, (kanren.membero, x, list_nums), (check_prime, x)) ) ) # 素数判定 def check_prime(x): if kanren.isvar(x): print("X0:",x) # 以下の condeseq() により # [eq(x,2)] or [eq(x,3)] or [eq(x,5)] or [eq(x,7)] or ... # が生成 # - sympy.ntheory.generate.prime(i)= i番目の素数を算出 # - it.count(1) = 開始値=1の無限イテレータ return kanren.core.condeseq([kanren.eq(x, p)] \ for p in map(sympy.ntheory.generate.prime, itertools.count(1) )) print("X1:",x) if sympy.ntheory.generate.isprime(x): # 素数判定 return success return fail if __name__ == '__main__': main()
↑こう書くと、↓こう出力されます
$ ./foo.py List of primes in the list: X0: ~_1 X1: 23 X1: 4 X1: 27 X1: 17 X1: 13 X1: 10 X1: 21 X1: 29 X1: 3 X1: 32 X1: 11 X1: 19 {3, 11, 13, 17, 19, 23, 29}
ただ、「if kanren.isvar(x)」内を殆ど通らない点が、気になります。