end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

kanren for python による論理プログラミング (パズルの解法)

https://www.oreilly.co.jp/books/9784873118727/

またまた、上記url の 6章の写経の続き。

「パズル」と言っても、歯抜けの条件群を定義した上で、 ウサギの飼い主を求めます。

#!/usr/local/python3/bin/python3
# -*- coding: utf-8 -*-
from kanren import * 

    
def main():
    
    people = var()

    rules = lall(
        # people は4個の変数(人)を持つ
        (eq,      (var(),    var(),    var(),  var()      ),people),
        # Steveは青い車を持っており、peopleのメンバー
        (membero, ('Steve',  var(),    'blue', var()      ),people),
        # 猫を飼って、Canadaに住むメンバーがいる
        (membero, (var(),    'cat',    var(),  'Canada'   ),people),
        # MattherはUSAに住んでおり、peopleのメンバー
        (membero, ('Matthew',var(),    var(),  'USA'      ),people),
        # 黒い車を持っている人はAustraliaに住んでいるメンバーがいる
        (membero, (var(),    var(),    'black','Australia'),people),
        # Jachは猫を飼っており、peopleのメンバー
        (membero, ('Jack',   'cat',    var(),  var()      ),people),
        # AlfredはAustraliaに住んでおり、peopleのメンバー
        (membero, ('Alfred', var(),    var(),  'Australia'),people),
        # 犬を飼ってFranceに住んでいるメンバーがいる
        (membero, (var(),    'dog',    var(),  'France'   ),people),
        
        # ウサギを飼っているメンバーがいる
        (membero, (var(),    'rabbit', var(),  var()      ),people)
    )
  
    solutions = run(0, people, rules)

    # ウサギの飼い主は?
    output = [house for house in solutions[0] if 'rabbit' in house][0][0]
    print(output + ' is the owner of the rabbit')


    # ルール一覧の出力
    print('Here are all the details:') 
    attribs = ['Name', 'Pet', 'Color', 'Country'] 
    print('\n' + '\t\t'.join(attribs)) 
    print('=' * 57) 

    for item in solutions[0]: 
        print('\t\t'.join([str(x) for x in item])) 

    
if __name__ == '__main__':
    main()

↑こう書くと、↓こう表示されます

$ ./foo.py 
Matthew is the owner of the rabbit
Here are all the details:

Name            Pet             Color           Country
=========================================================
Steve           dog             blue            France
Jack            cat             ~_9             Canada
Matthew         rabbit          ~_11            USA
Alfred          ~_13            black           Australia