2011-07-05 3 views
5

Giả sử bạn có một chương trình Prolog chẩn đoán bệnh mà bắt đầu với nhiều mối quan hệ giữa bệnh tật và symptons:Làm thế nào để áp dụng định lượng phổ trong Prolog?

causes_of(symptom1, Disease) :- 
    Disease = disease1; 
    Disease = disease2. 
causes_of(symptom2, Disease) :- 
    Disease = disease2; 
    Disease = disease3. 
causes_of(symptom3, Disease) :- 
    Disease = disease4. 

has_symptom(person1, symptom1). 
has_symptom(person1, symptom2). 

Làm thế nào tôi có thể tạo ra một quy tắc với người đứng đầu 'has_disease (Person, bệnh) mà sẽ trả về true nếu người có tất cả các triệu chứng từ bệnh đó? Sử dụng ví dụ trên đây sẽ là kết quả mẫu:

has_disease(person1, Disease). 
    Disease = disease2. 

Trả lời

6

Vâng, có thể có một cách đơn giản hơn nhiều để thực hiện việc này, vì kỹ năng Prolog của tôi ít nhất là tốt nhất.

has_disease(Person, Disease) :- atom(Disease), 
    findall(Symptom, has_symptom(Person, Symptom), PersonSymptoms), 
    findall(DSymptom, causes_of(DSymptom, Disease), DiseaseSymptoms), 
    subset(DiseaseSymptoms, PersonSymptoms). 

has_diseases(Person, Diseases) :- 
    findall(Disease, (causes_of(_, Disease), has_disease(Person, Disease)), DiseaseList), 
    setof(Disease, member(Disease, DiseaseList), Diseases). 

Để được gọi như sau:

?- has_diseases(person1, D). 
D = [disease1, disease2, disease3]. 

Các findall/3 ngữ được sử dụng đầu tiên để tìm tất cả các triệu chứng một người có, sau đó một lần nữa để tìm tất cả các triệu chứng bệnh có, sau đó kiểm tra nhanh chóng để xem nếu các triệu chứng của bệnh là một tập hợp con của người đó.

Cách tôi đã viết thuộc tính has_disease/2 ngăn không cho nó đưa ra danh sách các bệnh. Vì vậy, tôi đã tạo has_diseases/2, thực hiện một số khác findall về bất kỳ bệnh nào mà nó có thể tìm thấy, sử dụng séc has_disease/2 làm séc. Cuộc gọi setof/3 được sử dụng cuối cùng để nhận kết quả duy nhất trên danh sách bệnh và yêu cầu nó thuận tiện.

NB. atom/1 trên nguyên thủy has_disease/2 chỉ để đảm bảo biến không được chuyển cho Disease, vì nó không hoạt động trong trường hợp đó, ít nhất là không cho tôi.

1

Bạn sẽ cần một cách để truy vấn tất cả các triệu chứng, ví dụ: với findall(S,cause_of(S,disease),SS), trong đó SS sẽ là danh sách các triệu chứng của bệnh này.

+1

Có thể cho ví dụ về cách tôi sẽ thực hiện việc này? –