2011-07-05 7 views
5

Suponga que tiene un programa Prolog diagnóstico de la enfermedad que se inicia con muchas relaciones entre las enfermedades y síntomas relacionados:¿Cómo aplicar el cuantificador universal en 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). 

¿Cómo puedo crear una regla con el 'has_disease (persona, Enfermedades)' cabeza que devolverá verdadero si el la persona tiene todos los síntomas de esa enfermedad? Utilizando el ejemplo anterior, el siguiente sería un ejemplo de salida:

has_disease(person1, Disease). 
    Disease = disease2. 

Respuesta

6

Bueno, es probable que haya una manera mucho más sencilla de hacer esto, ya que mis conocimientos de Prolog son menores en el mejor.

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). 

a ser llamado como sigue:

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

El predicado findall/3 se utilizó por primera vez para encontrar todos los síntomas de una persona, a continuación, de nuevo para encontrar todos los síntomas de una enfermedad tiene, entonces una comprobación rápida para ver si los síntomas de la enfermedad son un subconjunto de la persona.

La forma en que he escrito el predicado has_disease/2 le impide dar una lista de enfermedades. Así que creé has_diseases/2, que realiza otra findall sobre cualquier enfermedad que pueda encontrar, utilizando has_disease/2 como el cheque. Una llamada a setof/3 se utiliza por última vez para obtener resultados únicos en la lista de enfermedades y solicitarla por conveniencia.

NB. El atom/1 en la primitiva has_disease/2 es sólo para garantizar una variable no se pasa por Disease, ya que no funciona en ese caso, al menos no para mí.

1

Usted necesitará una forma de consultar todos los síntomas, por ejemplo, con findall(S,cause_of(S,disease),SS), donde SS será la lista de síntomas de esta enfermedad.

+1

¿Podría dar un ejemplo de cómo iba a hacerlo? –