Home     Termíny     Cvičení     Projekty     Rezervace termínu
  1   2   3   4   5   6

1. cvičení

úterý 18.2.2008 a 26.2.2008 v 8:00 v B311


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
    | ?- 
    
    

  1. Jak se liší následující dotazy (na co se kdy ptáme)? Které uspějí (kladná odpověď), které neuspějí (záporná odpověď), a které jsou špatně (dojde k chybě)? Za jakých předpokladů by ty neúspěšné případně špatné uspěly?
    a) X = Y + 1
    b) X is Y + 1
    c) X = Y
    d) X == Y
    e) 1 + 1 = 2
    f) 2 = 1 + 1
    g) 1 + 1 = 1 + 1
    h) 1 + 1 is 1 + 1
    i) 1 + 2 =:= 2 + 1
    j) X \== Y
    k) X =\= Y
    l) 1 + 2 =\= 1 - 2
    m) 1 <= 2
    n) 1 =< 2
    o) sin(X) is sin(2)
    p) sin(X) = sin(2+Y)
    r) sin(X) =:= sin(2+Y)
    
    Vyzkoušejte :-)
    Nápověda: '='/2 unifikace, '=='/2 test na identitu, '=:='/2 aritmetická rovnost, '\=='/2 negace testu na identitu, '=\='/2 aritmetická nerovnost

  2. Jak se liší predikáty s1/3 a s2/3? Co umí s1/3 navíc oproti s2/3 a naopak?
    s1(0,X,X).
    s1(s(X),Y,s(Z)):-s1(X,Y,Z).
    
    s2(X,Y,Z):- Z is X + Y.
    
    s1/3 je vícesměrný - umí sčítat, odečítat, generovat součty, ale pracuje jen s nezápornými celými čísly
    s2/3 umí pouze sčítat, ale také záporná a reálná čísla

  3. Domácí úkol: upravte následující predikát s aritmetikou na vícesměrný (využijte některé metalogické predikáty pro testování "typů" argumentů, např. var/1, nonvar/1, number/1, integer/1 , definice těchto vestavěných predikátů najdete zde)
    soucet(X,Y,Z):- Z is X+Y.
    

^