2012-01-02 15 views
16

मैंने अभी कोर.लॉगिक के साथ खेलना शुरू कर दिया है, और इस पर काम करने के लिए मैं कुछ सरल कार्यान्वित करने की कोशिश कर रहा हूं जो कि एक समस्या के समान है जिसे मैं वर्तमान में पेशेवर रूप से काम कर रहा हूं। हालांकि, समस्या का एक हिस्सा मुझे फंस गया है ...core.logic में 'बाहरी शामिल' अनुकरण कैसे करें?

मेरे उदाहरण के सरलीकरण के रूप में, यदि मेरे पास वस्तुओं की सूची है, और उनमें से कुछ केवल कुछ देशों में उपलब्ध हैं, और कुछ विशिष्ट में उपलब्ध नहीं हैं देशों। मैं आइटम की सूची निर्दिष्ट सक्षम होने के लिए चाहते हैं, और अपवाद हैं, कुछ की तरह:

(defrel items Name Color) 
(defrel restricted-to Country Name) 
(defrel not-allowed-in Country Name) 

(facts items [['Purse 'Blue] 
       ['Car 'Red] 
       ['Banana 'Yellow]]) 

(facts restricted-to [['US 'Car]]) 

(facts not-allowed-in [['UK 'Banana] 
         ['France 'Purse]]) 

संभव हो तो, मैं था बल्कि नहीं निर्दिष्ट अनुमति-इन सभी देशों के लिए, प्रतिबंधों के साथ वस्तुओं के सेट के रूप में अपेक्षाकृत छोटा है, और मैं किसी दिए गए देश के लिए किसी आइटम के लिए अनुमति/बहिष्कृत करने के लिए एक ही परिवर्तन करने में सक्षम होना चाहता हूं।

मैं एक नियम है कि एक देश के लिए की आइटम/रंग सूची प्रदान करती है, तो निम्न बाधाओं के साथ कैसे लिख सकते हैं:

  • आइटम आइटम
  • देश/मद चाहिए की सूची में होना चाहिए 'नहीं-अनुमति के रखने वाले' सूची में नहीं जा
  • कोई एक:
    • में कोई भी देश नहीं है प्रतिबंधित करने कि आइटम
    • देश/आइटम जोड़ी restricted- में है के लिए सूची सूची

वहाँ किसी तरह यह करने के लिए है? क्या मैं पूरी तरह से गलत तरीके से चीजों के बारे में सोच रहा हूं?

उत्तर

14

आमतौर पर जब आप तर्क प्रोग्रामिंग में लक्ष्यों को अस्वीकार करना शुरू करते हैं, तो आपको गैर-रिलेशनल ऑपरेशंस (प्रोलॉग में कटौती, कोर.लॉगिक में कोंडा) तक पहुंचने की आवश्यकता होती है।

इस समाधान को केवल जमीन के तर्क के साथ बुलाया जाना चाहिए।

(defn get-items-colors-for-country [country] 
    (run* [q] 
    (fresh [item-name item-color not-country] 
     (== q [item-name item-color]) 
     (items item-name item-color) 
     (!= country not-country) 

     (conda 
     [(restricted-to country item-name) 
     (conda 
      [(not-allowed-in country item-name) 
      fail] 
      [succeed])] 
     [(restricted-to not-country item-name) 
     fail] 
     ;; No entry in restricted-to for item-name 
     [(not-allowed-in country item-name) 
     fail] 
     [succeed])))) 

(get-items-colors-for-country 'US) 
;=> ([Purse Blue] [Banana Yellow] [Car Red]) 

(get-items-colors-for-country 'UK) 
;=> ([Purse Blue]) 

(get-items-colors-for-country 'France) 
;=> ([Banana Yellow]) 

(get-items-colors-for-country 'Australia) 
;=> ([Purse Blue] [Banana Yellow]) 

Full solution

+0

तक 'जमीन तर्क', मैं तुम्हें एक मूल्य के बजाय क्वेरी चर मतलब यह मानें कि? माफी, लॉजिक प्रोग्रामिंग के साथ मेरा आखिरी ब्रश लगभग 25 साल पहले एक अंडरग्रेड प्रोलॉग कोर्स था ... –

+1

यह एक अनबाउंड या अनगिनत चर नहीं हो सकता है। एक मान ग्राउंड है यदि इसमें अनबाउंड लॉजिक वेरिएबल नहीं हैं (उदाहरण के लिए [1 2 0._] जमीन नहीं है)। यह कार्य प्रासंगिक होता है यदि फ़ंक्शन एक लक्ष्य है और आप तर्क चर के रूप में क्वेरी चर पारित कर रहे हैं। इस गलती में, 'आइटम-रंग-देश-देश' के लिए अपनी पहली तर्क जमीन होने की आवश्यकता है। लक्ष्य मेरे प्रारंभिक उत्तर से अधिक लचीला और composable है। उदाहरण के लिए हम अमेरिका में उपलब्ध पर्स के रंगों से पूछ सकते हैं। https://gist.github.com/1557417 – Ambrose

+0

स्पष्टीकरण के लिए धन्यवाद! –

2

Conda कोड complexifies सकता है, NAFC उपयोग कर, आप और अधिक आसानी से लक्ष्यों को पुन: व्यवस्थित अगर आप चाहते हैं कर सकते हैं। यह अभी भी गैर-संबंधपरक है! :)

(ns somenamespace 
    (:refer-clojure :exclude [==]) 
    (:use [clojure.core.logic][clojure.core.logic.pldb])) 

(db-rel items Name Color) 
(db-rel restricted-to Country Name) 
(db-rel not-allowed-in Country Name) 

(def stackoverflow-db 
    (db [items 'Purse 'Blue] 
     [items 'Car 'Red] 
     [items 'Banana 'Yellow] 
     [restricted-to 'US 'Car] 
     [not-allowed-in 'UK 'Banana] 
     [not-allowed-in 'France 'Purse])) 


(defn get-items-colors-for-country [country] 
    (with-db stackoverflow-db 
    (run* [it co] 
     (items it co) 
     (nafc not-allowed-in country it) 
     (conde 
      [(restricted-to country it)] 
      [(nafC#(fresh [not-c] (restricted-to not-c %)) it)])))) 

(get-items-colors-for-country 'US) 
;=> ([Purse Blue] [Banana Yellow] [Car Red]) 

(get-items-colors-for-country 'UK) 
;=> ([Purse Blue]) 

(get-items-colors-for-country 'France) 
;=> ([Banana Yellow]) 

(get-items-colors-for-country 'Australia) 
;=> ([Purse Blue] [Banana Yellow]) 

अधिक उदाहरण के लिए: https://gist.github.com/ahoy-jon/cd0f025276234de464d5

संबंधित मुद्दे