Osnova


  1. Do pracovniho adresare si stahnete program rodokmen.pl. Načtěte program v interpretu (konzultujte).

  2. V interpretu Sicstus Prologu pokládejte dotazy:
    a) Je Petr otcem Lenky?
    b) Je Petr otcem Jana?
    c) Kdo je otcem Petra?
    d) Jaké děti má Pavla?
    e) Ma Petr dceru?
    f) Které dvojice otec-syn známe?

    Řešení
    (středníkem si vyžádáme další řešení)
    | ?- otec(petr,lenka).
    yes
    | ?- otec(petr,jan).  
    no
    | ?- otec(Kdo,petr).
    Kdo = adam ? ;
    no
    | ?- rodic(pavla,Dite).
    Dite = petr ? ;
    Dite = tomas ? ;
    no
    | ?- otec(petr,Dcera),zena(Dcera).
    Dcera = lenka ? ;
    no
    | ?- otec(Otec,Syn),muz(Syn).
    Syn = filip,
    Otec = petr ? ;
    Syn = jan,
    Otec = pavel ? ;
    Syn = petr,
    Otec = adam ? ;
    Syn = michal,
    Otec = tomas ? ;
    Syn = radek,
    Otec = michal ? ;
    no
    | ?- 
    

  3. Naprogramujte predikáty
    a) potomek(Potomek,Predek)
    b) prababicka(Prababicka,Pravnouce)
    c) nevlastni_bratr(Nevlastni_bratr,Nevlastni_sourozenec)

    Řešení
    potomek(Potomek,Predek):-rodic(Predek,Potomek).
    potomek(Potomek,Predek):-rodic(Predek,X),potomek(Potomek,X).
    
    prababicka(Prababicka,Pravnouce):-
            rodic(Prababicka,Prarodic),
            zena(Prababicka),
            rodic(Prarodic,Rodic),
            rodic(Rodic,Pravnouce).
    
    nevlastni_bratr(Bratr,Sourozenec):-
            rodic_v(X,Bratr),
            muz(Bratr),
            rodic_v(X,Sourozenec),
            Bratr \== Sourozenec,  /* tento test neni nutny, ale zvysuje efektivitu
    */
            rodic_v(Y,Bratr),
            Y \== X,
            rodic_v(Z,Sourozenec),
            Z \== X,
            Z \== Y.
    
     
    /* nevhodne umisteni testu - vypocet "bloudi" v neuspesnych vetvich */       
    nevlastni_bratr2(Bratr,Sourozenec):-
            rodic_v(X,Bratr),
            rodic_v(X,Sourozenec),
            rodic_v(Y,Bratr),
            rodic_v(Z,Sourozenec),
            Y \== X,
            Z \== X,
            Z \== Y,
            muz(Bratr).
    
  4. Prohledávání stavového prostoru:
    a) Zkuste předem odhadnout (odvodit) pořadí, v jakem budou nalezeni potomci Pavly?
    b) Jaký vliv má pořadí klauzulí a cílu v predikátu potomek/2 na jeho funkci?
    c) Nahraďte ve svých programech volání predikátu rodic/2 následujícím predikátem rodic_v/2
    rodic_v(X,Y):-rodic(X,Y),print(X),print('? ').
    
    Pozorujte rozdíly v délce výpočtu dotazu nevlastni_bratr(filip,X) při změně pořadí testů v definici predikátu nevlastni_bratr/2

    Řešení
    /* varianta 1a */
    
    potomek(Potomek,Predek):-rodic(Predek,Potomek).
    potomek(Potomek,Predek):-rodic(Predek,X),potomek(Potomek,X).
    
    /* varianta 1b - jine poradi odpovedi, neprimi potomci maji prednost */
    
    potomek(Potomek,Predek):-rodic(Predek,X),potomek(Potomek,X).
    potomek(Potomek,Predek):-rodic(Predek,Potomek).
    
    /* varianta 2a - leva rekurze ve druhe klauzuli,
    na dotaz potomek(X,pavla) vypise odpovedi, pak cykli */
    
    potomek(Potomek,Predek):-rodic(Predek,Potomek).
    potomek(Potomek,Predek):-potomek(Potomek,X),rodic(Predek,X).
    
    /* varianta 2b - leva rekurze v prvni klauzuli,
    na dotaz potomek(X,pavla) hned cykli */
    
    potomek(Potomek,Predek):-potomek(Potomek,X),rodic(Predek,X).
    potomek(Potomek,Predek):-rodic(Predek,Potomek).
    
    
    Po nahrazení predikátu rodic/2 predikatem rodic_v/2 v predikátech nevlastni_bratr/2 a nevlastni_bratr2/2 a spuštění uvidíme:
    
    | ?- nevlastni_bratr(X,Y). 
    petr? petr? petr? petr? eva? petr? jana? 
    X = filip,
    Y = lenka ? ;
    petr? pavel? pavel? adam? adam? tomas? tomas? michal? michal? eva? eva? jana?
    pavla? pavla? pavla? adam? pavla? pavla? pavla? pavla? pav
    la? pavla? lenka? 
    no
    | ?- nevlastni_bratr2(X,Y).
    petr? petr? petr? petr? eva? eva? petr? eva? petr? petr? petr? jana? eva? petr?
    jana? 
    X = filip,
    Y = lenka ? ;
    petr? petr? petr? petr? eva? jana? petr? eva? petr? petr? petr? jana? jana?
    petr? jana? pavel? pavel? pavel? pavel? adam? adam? adam? ad
    am? pavla? pavla? adam? pavla? tomas? tomas? tomas? tomas? michal? michal?
    michal? michal? eva? eva? petr? petr? eva? eva? petr? eva? ja
    na? jana? petr? petr? jana? jana? petr? jana? pavla? pavla? adam? adam? pavla?
    pavla? adam? pavla? pavla? adam? pavla? pavla? pavla? pav
    la? pavla? pavla? adam? pavla? pavla? pavla? pavla? lenka? lenka? lenka? lenka? 
    no
    | ?- 
    
    

^