Recent Changes · Search:

Functional Programming

Type Inference

Toss

  • (incorporates former Speagram)

Emacs

Kurs Pascala

Artificial General Intelligence

AI:

Algorithmic Game Theory: Prediction Markets (po polsku)

Programming in Java

kurs pracy w systemie Linux

Evolutionary Algorithms

Animation

Data Stores and Data Mining

Language Understanding

Systemy Inteligentnych Agentów

Przetwarzanie Języka Naturalnego

Programowanie Funkcjonalne

PmWiki

pmwiki.org

add user

edit SideBar

ProgFun.Zadania History

Hide minor edits - Show changes to output

June 07, 2011, at 03:48 PM by 90.156.82.87 -
Added lines 17-37:
!! Punktacja

Schemat tabelki z punktami:

||border=1
||!Imię i nazwisko||!Lista 1||||!Lista 2||||!Lista 3||||!Lista 4||||!Lista 5||||||!Lista 6||||!Lista 7||||!Lista 8||||!Lista 9||!Projekt||!Razem||||||
|| ||!pdst||!dod||!pdst||!dod||!pdst||!dod||!pdst||!dod||!pdst||!dod||!ob||!pdst||!dod||!pdst||!dod||!pdst||!dod||!dod||!pdst, dod||!suma||!wynik||!ocena
(:scoretable grades="ndst 2.75 dst 3.25 dst+ 3.75 db 4.25 db+ 4.75 bdb" comput="s/170.0*5.0":)
||maksymalna ilość punktów    || 12|| 6|| 12|| 9|| 12|| 8|| 12|| 8|| 9|| 4||  || 14|| 8|| 13|| 11|| 18|| 19|| 24|| 68, 12|| 279|| 8.2||
(:endscoretable:)

Punktacja wybranych zadań:
"Lista 8" zadania podstawowe: wykład 8 zad. 1: 3pkt, zad. 2: 2pkt (+1 pkt za interfejs z osobną kompilacją); wykład 9 zad. 1: 3pkt, zad. 2: 2pkt; lista zad. 2: 2pkt, zad. 3: 3pkt, zad. 4: 3pkt.

Maksymalna ilość punktów za zadania podstawowe: 102

Ilość punktów za dobrze obroniony projekt: 68

Prognoza oceny (punkty + 68) / (102 + 68) * 5.0

October 01, 2007, at 02:07 PM by lukstafi - Undo: it is top.
Changed line 762 from:
module Weird (B : sig end) = (struct
to:
module Weird (Top : sig end) = (struct
Changed lines 769-770 from:
module Gen (X : functor (B : sig end) -> S) = X (struct end);;
to:
module Gen (X : functor (Top : sig end) -> S) = X (struct end);;
October 01, 2007, at 01:59 PM by lukstafi - it was rather Bottom than Top, right?
Changed line 762 from:
module Weird (Top : sig end) = (struct
to:
module Weird (B : sig end) = (struct
Changed lines 769-770 from:
module Gen (X : functor (Top : sig end) -> S) = X (struct end);;
to:
module Gen (X : functor (B : sig end) -> S) = X (struct end);;
May 13, 2007, at 11:23 PM by lukstafi - zipper iterators
Added lines 270-271:
Rozwinięcie: [[http://www.lri.fr/Rapports-internes/2006/RR1428.pdf]]
Deleted lines 4-5:
óó
Changed line 123 from:
[@
to:
(:source lang=ocaml:)
Changed lines 126-127 from:
@]
to:
(:sourcend:)
Changed line 130 from:
[@
to:
(:source lang=ocaml:)
Changed lines 132-133 from:
@]
to:
(:sourcend:)
Changed line 136 from:
[@
to:
(:source lang=ocaml:)
Changed lines 138-139 from:
@]
to:
(:sourcend:)
Changed line 157 from:
[@
to:
(:source lang=ocaml:)
Changed lines 159-160 from:
@]
to:
(:sourcend:)
Changed line 163 from:
[@
to:
(:source lang=ocaml:)
Changed lines 165-166 from:
@]
to:
(:sourcend:)
Changed line 169 from:
[@
to:
(:source lang=ocaml:)
Changed lines 172-173 from:
@]
to:
(:sourcend:)
Changed line 181 from:
[@
to:
(:source lang=ocaml:)
Changed lines 185-186 from:
@]
to:
(:sourcend:)
Changed line 203 from:
[@
to:
(:source lang=ocaml:)
Changed lines 205-206 from:
@]
to:
(:sourcend:)
Changed line 209 from:
[@
to:
(:source lang=ocaml:)
Changed lines 213-214 from:
@]
to:
(:sourcend:)
Changed line 217 from:
[@
to:
(:source lang=ocaml:)
Changed lines 219-220 from:
@]
to:
(:sourcend:)
Changed line 227 from:
[@
to:
(:source lang=ocaml:)
Changed lines 230-231 from:
@]
to:
(:sourcend:)
Changed line 335 from:
[@
to:
(:source lang=ocaml:)
Changed lines 337-338 from:
@]
to:
(:sourcend:)
Changed line 359 from:
[@
to:
(:source lang=ocaml:)
Changed lines 363-364 from:
@]
to:
(:sourcend:)
Changed line 377 from:
[@
to:
(:source lang=ocaml:)
Changed lines 421-422 from:
@]
to:
(:sourcend:)
Changed line 425 from:
[@
to:
(:source lang=ocaml:)
Changed lines 427-428 from:
@]
to:
(:sourcend:)
Changed line 431 from:
[@
to:
(:source lang=ocaml:)
Changed lines 433-434 from:
@]
to:
(:sourcend:)
Changed line 444 from:
[@
to:
(:source lang=ocaml:)
Changed lines 446-447 from:
@]
to:
(:sourcend:)
Changed line 450 from:
[@
to:
(:source lang=ocaml:)
Changed lines 452-453 from:
@]
to:
(:sourcend:)
Changed line 456 from:
[@
to:
(:source lang=ocaml:)
Changed lines 459-460 from:
@]
to:
(:sourcend:)
Changed line 465 from:
[@
to:
(:source lang=ocaml:)
Changed lines 468-469 from:
@]
to:
(:sourcend:)
Changed line 481 from:
[@
to:
(:source lang=ocaml:)
Changed lines 483-484 from:
@]
to:
(:sourcend:)
Changed line 503 from:
[@
to:
(:source lang=ocaml:)
Changed lines 540-541 from:
@]
to:
(:sourcend:)
Changed line 545 from:
[@
to:
(:source lang=ocaml:)
Changed lines 558-559 from:
@]
to:
(:sourcend:)
Changed line 676 from:
[@
to:
(:source lang=ocaml:)
Changed lines 684-685 from:
@]
to:
(:sourcend:)
Changed line 725 from:
[@
to:
(:source lang=ocaml:)
Changed lines 745-746 from:
@]
to:
(:sourcend:)
Changed line 749 from:
[@
to:
(:source lang=ocaml:)
Changed lines 772-773 from:
@]
to:
(:sourcend:)
Changed line 777 from:
[@
to:
(:source lang=ocaml:)
Changed lines 782-783 from:
@]
to:
(:sourcend:)
Changed line 792 from:
[@
to:
(:source lang=ocaml:)
Changed lines 857-858 from:
@]
to:
(:sourcend:)
Changed line 864 from:
[@
to:
(:source lang=ocaml:)
Changed lines 899-900 from:
@]
to:
(:sourcend:)
Changed line 917 from:
[@
to:
(:source lang=ocaml:)
Changed lines 949-950 from:
@]
to:
(:sourcend:)
Changed lines 1-2 from:
Zadania na ćwiczenia będą się składać z: zadań z wykładów, zadań,
które będę podawał bezpośrednio na ćwiczeniach, i zadań, które będę
to:
Zadania na ćwiczenia będą się składać z: zadań z wykładów, zadań,
kt
óre będę podawał bezpośrednio na ćwiczeniach, i zadań, które będę
Changed lines 5-6 from:
ó
to:
óó
Changed lines 17-18 from:
* [[#l9 | lista 9]] argumenty etykietowane, domyślne wartości argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]], [[#z94 | zad.4]], [[#z95 | zad.5]], [[#z96 | zad.6]], [[#z97 | zad.7]])
to:
* [[#l9 | lista 9]] argumenty etykietowane, domyślne wartości argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]], [[#z94 | zad.4]], [[#z95 | zad.5]], [[#z96 | zad.6]], [[#z97 | zad.7]])
Changed lines 50-51 from:
Trójkąt o bokach a, b, c ma pole A dane wzorem:
to:
Trójkąt o bokach a, b, c ma pole A dane wzorem:
Changed lines 57-59 from:
Znajdź wszystkie trójkąty o bokach długości będącej liczbą całkowitą
nie większą od n, których pole też jest całkowitoliczbowe.
to:
Znajdź wszystkie trójkąty o bokach długości będącej liczbą całkowitą
nie większą od n, których pole też jest całkowitoliczbowe.
Changed line 75 from:
rozwiązanie ze stanu obliczeń, który może przechowywać dodatkowe
to:
rozwiązanie ze stanu obliczeń, który może przechowywać dodatkowe
Changed line 79 from:
O funkcji @@f@@ której pierwiastki będziesz obliczać możesz poczynić
to:
O funkcji @@f@@ której pierwiastki będziesz obliczać możesz poczynić
Changed lines 89-90 from:
zgodnie z komentarzem w pliku źródłowym:
to:
zgodnie z komentarzem w pliku źródłowym:
Changed lines 113-115 from:
"nieoszukany" wariant funkcji [@Printf.sprintf@]) w następujący sposób.
Napisz funkcje będące "dyrektywami wzorców":
* @@lit@@ dla literałów (stałych stringów)
to:
"nieoszukany" wariant funkcji [@Printf.sprintf@]) w następujący sposób.
Napisz funkcje będące "dyrektywami wzorców":
* @@lit@@ dla literałów (stałych stringów)
Changed lines 118-121 from:
* @@str@@ dla wstawiania stringów (odpow. "%s")
* @@lis@@ dla wstawiania list elementów.
Napisz funkcj
ę "format", która jako argument pobiera wzorzec zbudowany
z dyrektyw wzorców.
to:
* @@str@@ dla wstawiania stringów (odpow. "%s")
* @@lis@@ dla wstawiania list elementów.
Napisz funkcję
"format", która jako argument pobiera wzorzec zbudowany
z dyrektyw wzorców.
Changed lines 142-143 from:
zwróci string:
to:
zwróci string:
Changed lines 148-149 from:
(lub ze średnikami zamiast przecinków).
to:
(lub ze średnikami zamiast przecinków).
Changed lines 152-153 from:
Na którymś z kolejnych wykładów zostanie wprowadzone pojęcie listy
leniwej. My teraz zdefiniujemy szczególny
przypadek listy leniwej,
to:
Na którymś z kolejnych wykładów zostanie wprowadzone pojęcie listy
leniwej. My teraz zdefiniujemy szczególny
przypadek listy leniwej,
Changed line 192 from:
- dodawanie szeregów potęgowych
to:
- dodawanie szeregów potęgowych
Changed lines 194-195 from:
- mnożenie szeregów
- dzielenie szeregów (wzór wyprowadź rozwijając równanie F = Q * G, by
to:
- mnożenie szeregów
- dzielenie szeregów (wzór wyprowadź rozwijając równanie F = Q * G, by
Changed line 197 from:
- złożenie szeregów (F . G) (x) = F (G (x))
to:
- złożenie szeregów (F . G) (x) = F (G (x))
Changed line 199 from:
- trudniejsze: odwrotność funkcyjną szeregu, tzn. R w równaniu F(R(x)) = x
to:
- trudniejsze: odwrotność funkcyjną szeregu, tzn. R w równaniu F(R(x)) = x
Changed lines 201-204 from:
trudniejszy, wyznaczone z odpowiednich równań różniczkowych:

Np.
z równania na exp: "dy/dx = y, y(0) = 1" dostajemy
to:
trudniejszy, wyznaczone z odpowiednich równań różniczkowych:

Np.
z równania na exp: "dy/dx = y, y(0) = 1" dostajemy
Changed lines 227-228 from:
Wprowadź nazwę na typ szeregów:
to:
Wprowadź nazwę na typ szeregów:
Changed line 235 from:
przez toplevel odnosiły się do typów szeregów tylko przez nazwę
to:
przez toplevel odnosiły się do typów szeregów tylko przez nazwę
Changed lines 240-241 from:
Annotacja typem to wyrażenie lub wzorzec [@(expr : typ)@], którego typem jest
@@typ@@, o ile @@typ@@ jest szczególnym przypadkiem najogólniejszego typu
to:
Annotacja typem to wyrażenie lub wzorzec [@(expr : typ)@], którego typem jest
@@typ@@, o ile @@typ@@ jest szczególnym przypadkiem najogólniejszego typu
Changed line 245 from:
go z równości F*G = (f + xF1)*(g+xG1)), bez wyznaczania "za każdym
to:
go z równości F*G = (f + xF1)*(g+xG1)), bez wyznaczania "za każdym
Changed line 256 from:
współdzieleniu wspólnych części, w przypadku modyfikacji węzła drzewa
to:
współdzieleniu wspólnych części, w przypadku modyfikacji węzła drzewa
Changed line 263 from:
ruchy kursora do przemieszczania do sąsiadujących węzłów. Wtedy udaje
to:
ruchy kursora do przemieszczania do sąsiadujących węzłów. Wtedy udaje
Changed lines 265-266 from:
stałym czasie, dzięki strukturze, którą Gerard Huet nazwał "Zipper":
to:
stałym czasie, dzięki strukturze, którą Gerard Huet nazwał "Zipper":
Changed lines 276-277 from:
Typy algebraiczne (czyli warianty, sumy rozłączne produktów typów
algebraicznych) daj
ą bardzo wygodny sposób reprezentacji danych
to:
Typy algebraiczne (czyli warianty, sumy rozłączne produktów typów
algebraicznych) dają
bardzo wygodny sposób reprezentacji danych
Changed line 280 from:
funkcję, która dla zadanych danych wejściowych wygeneruje zadane dane
to:
funkcję, która dla zadanych danych wejściowych wygeneruje zadane dane
Changed line 286 from:
w szczególności z rozdziałem "Generalizing Decision Tree Learning to
to:
w szczególności z rozdziałem "Generalizing Decision Tree Learning to
Changed lines 298-299 from:
z pliku źródłowego).
to:
z pliku źródłowego).
Changed line 306 from:
tym samym argumentom przypisane są żne wyniki -- obecnie program
to:
tym samym argumentom przypisane są różne wyniki -- obecnie program
Changed line 320 from:
wygenerowane funkcje. Przykładowe możliwości to wykorzystanie modułów
to:
wygenerowane funkcje. Przykładowe możliwości to wykorzystanie modułów
Changed line 334 from:
Zbuduj dowolne drzewo rozpinające dla grafu danego jako lista par wierzchołek, lista wierzchołków przyległych. Zapamiętaj również pozostałe wierzchołki wychodzące z danego węzła.
to:
Zbuduj dowolne drzewo rozpinające dla grafu danego jako lista par wierzchołek, lista wierzchołków przyległych. Zapamiętaj również pozostałe wierzchołki wychodzące z danego węzła.
Changed lines 342-343 from:
Dzielimy wierzchołki drzewa na lekkie i ciężkie jak następuje: korzeń jest lekki, wszyscy synowie, którzy rozpinają poddrzewa o największym rozmiarze spośród poddrzew rodzeństwa, są ciężcy, pozostałe wierzchołki są lekkie. (Innymi słowy, dla każdego wierzchołka wewnętrznego oznaczamy tego syna, w którym podczepione jest największe poddrzewo, jako ciężkiego.) Oznaczamy krawędzie prowadzące do lekkich synów jako lekkie, a prowadzące do ciężkich synów jako ciężkie. Lekką głębokością wierzchołka v nazywamy ilość lekkich krawędzi na ścieżce od v do korzenia. Lekką głębokością drzewa nazywamy maksimum z lekkich głębokości jego wierzchołków. Napisz funkcję obliczającą lekką głębokość drzewa.
to:
Dzielimy wierzchołki drzewa na lekkie i ciężkie jak następuje: korzeń jest lekki, wszyscy synowie, którzy rozpinają poddrzewa o największym rozmiarze spośród poddrzew rodzeństwa, są ciężcy, pozostałe wierzchołki są lekkie. (Innymi słowy, dla każdego wierzchołka wewnętrznego oznaczamy tego syna, w którym podczepione jest największe poddrzewo, jako ciężkiego.) Oznaczamy krawędzie prowadzące do lekkich synów jako lekkie, a prowadzące do ciężkich synów jako ciężkie. Lekką głębokością wierzchołka v nazywamy ilość lekkich krawędzi na ścieżce od v do korzenia. Lekką głębokością drzewa nazywamy maksimum z lekkich głębokości jego wierzchołków. Napisz funkcję obliczającą lekką głębokość drzewa.
Changed lines 345-346 from:
W Pythonie mechanizm wyjątków pozwala zdefiniować klauzulę "else":
to:
W Pythonie mechanizm wyjątków pozwala zdefiniować klauzulę "else":
Changed lines 367-368 from:
w którym  nazwa @@X@@ jest związana z wartością @@GUARDED@@ w wyrażeniu @@BODY@@. O ile obliczanie @@GUARDED@@ nie spowodowało wyjątku, wynikiem całego wyrażenia jest wartość @@BODY@@. Jeśli obliczenie @@GUARDED@@ podniosło wyjątek @@EXCi@@, wynikiem całego wyrażenia jest wartość @@HANDLERi@@. Wyjątki podnoszone przez @@BODY@@ nie są przechwytywane!
to:
w którym  nazwa @@X@@ jest związana z wartością @@GUARDED@@ w wyrażeniu @@BODY@@. O ile obliczanie @@GUARDED@@ nie spowodowało wyjątku, wynikiem całego wyrażenia jest wartość @@BODY@@. Jeśli obliczenie @@GUARDED@@ podniosło wyjątek @@EXCi@@, wynikiem całego wyrażenia jest wartość @@HANDLERi@@. Wyjątki podnoszone przez @@BODY@@ nie są przechwytywane!
Changed lines 377-378 from:
Porównaj następujące dwie implementacje list leniwych:
to:
Porównaj następujące dwie implementacje list leniwych:
Changed lines 425-426 from:
Wytłumacz żnicę w złożoności pomiędzy obliczeniem
to:
Wytłumacz różnicę w złożoności pomiędzy obliczeniem
Changed lines 441-442 from:
naturalnych, tzn. funkcji które dla obliczenia argumentu @@n@@ potrzebują
(co najwyżej) wartości dla argumentów mniejszych od @@n@@.
to:
naturalnych, tzn. funkcji które dla obliczenia argumentu @@n@@ potrzebują
(co najwyżej) wartości dla argumentów mniejszych od @@n@@.
Changed line 473 from:
istotna). Napisz funkcję @@map_lBT@@ która leniwie mapuje drzewo @@lBT@@
to:
istotna). Napisz funkcję @@map_lBT@@ która leniwie mapuje drzewo @@lBT@@
Changed line 475 from:
@@itr@@ taką, jak w zadaniu 4 (a) z wykładu 5: która dla zadanej liczby
to:
@@itr@@ taką, jak w zadaniu 4 (a) z wykładu 5: która dla zadanej liczby
Changed lines 478-479 from:
funkcję @@nth_node@@, która dla danego drzewa i liczby @@n@@ zwraca etykietę
wierzchołka, który w drzewie zwróconym przez @@itr@@ miałby numer @@n@@.
to:
funkcję @@nth_node@@, która dla danego drzewa i liczby @@n@@ zwraca etykietę
wierzchołka, który w drzewie zwróconym przez @@itr@@ miałby numer @@n@@.
Changed lines 481-482 from:
począwszy od wierzchołka 1, traktując 0 jako szczególny przypadek:
to:
począwszy od wierzchołka 1, traktując 0 jako szczególny przypadek:
Changed line 487 from:
Jaka jest zaleta tej metody memoizacji w porównaniu z metodą
to:
Jaka jest zaleta tej metody memoizacji w porównaniu z metodą
Changed lines 545-546 from:
Użyjemy poręcznego typu do reprezentacji ciągów.
to:
Użyjemy poręcznego typu do reprezentacji ciągów.
Changed line 566 from:
* @@x_to_S@@ konwertującą ciąg do postaci ogólnej: [@x_to_S xs = S (x0, S(x1, S (x2, ...)))@] (używaj tej funkcji w kolejnych definicjach tylko w razie konieczności! np. w definicji map i map2)
to:
* @@x_to_S@@ konwertującą ciąg do postaci ogólnej: [@x_to_S xs = S (x0, S(x1, S (x2, ...)))@] (używaj tej funkcji w kolejnych definicjach tylko w razie konieczności! np. w definicji map i map2)
Changed lines 570-571 from:
Czemu są równe: [@exp (A x r)@], [@sqrt (G x q)@], [@log (G x q)@], [@n!@]?
to:
Czemu są równe: [@exp (A x r)@], [@sqrt (G x q)@], [@log (G x q)@], [@n!@]?
Changed line 573 from:
rozwiązywania równania [@y' = f (y, t), y(t0)=y0@], zazwyczaj
to:
rozwiązywania równania [@y' = f (y, t), y(t0)=y0@], zazwyczaj
Changed lines 582-583 from:
Zakoduj algorytm Lentza obliczania ułamków łańcuchowych:
to:
Zakoduj algorytm Lentza obliczania ułamków łańcuchowych:
Changed lines 593-594 from:
 Stop gdy C'_j_'*D'_j_' prawie równe 1.
to:
 Stop gdy C'_j_'*D'_j_' prawie równe 1.
Changed lines 607-608 from:
Porównaj wydajność wersji imperatywnej i funkcyjnej.
to:
Porównaj wydajność wersji imperatywnej i funkcyjnej.
Changed line 614 from:
Zastanów się nad podobieństwami i różnicami "dynamicznie
to:
Zastanów się nad podobieństwami i różnicami "dynamicznie
Changed line 617 from:
Zaimplementuj wznawialne wyjątki: mechanizm, w którym fragment
to:
Zaimplementuj wznawialne wyjątki: mechanizm, w którym fragment
Changed line 624 from:
Napisz rozwiązywaczkę do "gry w 8": gry, w której na prostokątnej
to:
Napisz rozwiązywaczkę do "gry w 8": gry, w której na prostokątnej
Changed line 627 from:
jest sprowadzenie planszy do sytuacji, w której kwadraty umieszczone
to:
jest sprowadzenie planszy do sytuacji, w której kwadraty umieszczone
Changed line 631 from:
kwadratów, przy czym jeden z zamienianych kwadratów musi mieć numer 0
to:
kwadratów, przy czym jeden z zamienianych kwadratów musi mieć numer 0
Changed line 634 from:
Testuj program dla duuużych plansz, stopniując trudność ilością ruchów
to:
Testuj program dla duuużych plansz, stopniując trudność ilością ruchów
Changed lines 636-637 from:
przypadkowych ruchów do konfiguracji będącej rozwiązaniem.
to:
przypadkowych ruchów do konfiguracji będącej rozwiązaniem.
Changed lines 645-654 from:
(listy) ruchów sprowadzających konfigurację początkową do danej.
Zmiana konfiguracji aktualnej na którąś z zapamiętanych pozostałych ma
by
ć wykonywana przez wycofanie części ruchów aktualnej konfiguracji
(zrobienie ruchów odwrotnych, w odwrotnej kolejności), aż do uzyskania
wspólnego odcinka początkowego (traktując głowę jako koniec listy) z
konfiguracją zapamiętaną, i następnie wykonanie brakujących ruchów
konfiguracji zapami
ętanej. Do znalezienia wspólnego odcinka
pocz
ątkowego wykorzystaj test równości fizycznej (==) (zapewnij
wspó
łdzielenie).
to:
(listy) ruchów sprowadzających konfigurację początkową do danej.
Zmiana konfiguracji aktualnej na którąś z zapamiętanych pozostałych ma
być
wykonywana przez wycofanie części ruchów aktualnej konfiguracji
(zrobienie ruchów odwrotnych, w odwrotnej kolejności), aż do uzyskania
wspólnego odcinka początkowego (traktując głowę jako koniec listy) z
konfiguracją zapamiętaną, i następnie wykonanie brakujących ruchów
konfiguracji zapami
ętanej. Do znalezienia wspólnego odcinka
początkowego wykorzystaj test równości fizycznej (==) (zapewnij
wspó
łdzielenie).
Changed lines 656-657 from:
Porównaj eksperymentalnie wydajność (faktyczną złożoność czasową)
wyznaczania
histogramu (np. zliczania wystąpień słów):
to:
Porównaj eksperymentalnie wydajność (faktyczną złożoność czasową)
wyznaczania
histogramu (np. zliczania wystąpień słów):
Changed lines 663-664 from:
Wykorzystując rozszerzenie składniowe [@let try@] (patrz zadanie 4 z listy 5), napisz funkcję, która pobiera listę nazw plików, i dla plików (w bieżącym katalogu), których zawartość da się przeczytać (czyli m. in. istnieją), tworzy ich kopię (dodając rozszerzenie ".copy") -- kopię stwórz otwierając nowy plik i zapisując w nim zawartość starego. Funkcja ma zwrócić konkatenację zawartości wszystkich plików (które dało się otworzyć) -- zakładamy, że są to pliki tekstowe z jedną linią tekstu. (Jeśli któryś z plików mających zawierać kopię już istnieje, funkcja ma przepuścić wyjątek.)
to:
Wykorzystując rozszerzenie składniowe [@let try@] (patrz zadanie 4 z listy 5), napisz funkcję, która pobiera listę nazw plików, i dla plików (w bieżącym katalogu), których zawartość da się przeczytać (czyli m. in. istnieją), tworzy ich kopię (dodając rozszerzenie ".copy") -- kopię stwórz otwierając nowy plik i zapisując w nim zawartość starego. Funkcja ma zwrócić konkatenację zawartości wszystkich plików (które dało się otworzyć) -- zakładamy, że są to pliki tekstowe z jedną linią tekstu. (Jeśli któryś z plików mających zawierać kopię już istnieje, funkcja ma przepuścić wyjątek.)
Changed lines 671-674 from:
a) Zapoznaj się z ideą "grafów indukcyjnych": [[http://web.engr.oregonstate.edu/~erwig/fgl/]] Zapisz wybrany algorytm grafowy nie zaimplementowany w artykule "Inductive Graphs and Functional Graph Algorithms": [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01]] w "języku grafów indukcyjnych".

b) Zapoznaj się z biblioteką "ocamlgraph": [[http://www.lri.fr/~filliatr/ocamlgraph/]]. (*) Napisz funktor dodający operację dekompozycji z "grafów indukcyjnych" do grafów z "ocamlgraph".
to:
a) Zapoznaj się z ideą "grafów indukcyjnych": [[http://web.engr.oregonstate.edu/~erwig/fgl/]] Zapisz wybrany algorytm grafowy nie zaimplementowany w artykule "Inductive Graphs and Functional Graph Algorithms": [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01]] w "języku grafów indukcyjnych".

b) Zapoznaj się z biblioteką "ocamlgraph": [[http://www.lri.fr/~filliatr/ocamlgraph/]]. (*) Napisz funktor dodający operację dekompozycji z "grafów indukcyjnych" do grafów z "ocamlgraph".
Changed lines 676-677 from:
Wygeneruj współdzielące kod moduły o sygnaturze:
to:
Wygeneruj współdzielące kod moduły o sygnaturze:
Changed lines 688-689 from:
tak, że @@compare@@ jest funkcją porównującą zgodną ze specyfikacją
[@Pervasives.compare@], przy czym symbol mniejszy to ten, który był
to:
tak, że @@compare@@ jest funkcją porównującą zgodną ze specyfikacją
[@Pervasives.compare@], przy czym symbol mniejszy to ten, który był
Changed lines 707-708 from:
Do efektywnego odwzorowania ze stringów w symbole wykorzystaj moduł @@Hashtbl@@.
to:
Do efektywnego odwzorowania ze stringów w symbole wykorzystaj moduł @@Hashtbl@@.
Changed lines 710-713 from:
Zobacz, w jaki sposób Will Farr wykorzystuje funktory do sparametryzowania swoich algorytmów względem implementacji obiektów, na których one działają: [[http://wmfarr.blogspot.com/2006/08/adventures-in-ocaml-land-barnes-hut.html]], [[http://wmfarr.blogspot.com/2006/10/automatic-differentiation-in-ocaml.html]] (wersja poprawiona [[http://wmfarr.blogspot.com/2006/10/correction-to-automatic.html]]). (Możesz też zobaczyć, w jaki sposób Jean-Christophe Filliatre implementuje algorytmy grafowe w oderwaniu od konkretnej "realizacji" grafów [[http://www.lri.fr/~filliatr/ocamlgraph/]].)

Podaj przykład praktycznej instancjacji funktora realizującego algorytm z dziedziny twojego projektu (tzn. nie implementującego kontener ani odwzorowanie) żnymi strukturami.
to:
Zobacz, w jaki sposób Will Farr wykorzystuje funktory do sparametryzowania swoich algorytmów względem implementacji obiektów, na których one działają: [[http://wmfarr.blogspot.com/2006/08/adventures-in-ocaml-land-barnes-hut.html]], [[http://wmfarr.blogspot.com/2006/10/automatic-differentiation-in-ocaml.html]] (wersja poprawiona [[http://wmfarr.blogspot.com/2006/10/correction-to-automatic.html]]). (Możesz też zobaczyć, w jaki sposób Jean-Christophe Filliatre implementuje algorytmy grafowe w oderwaniu od konkretnej "realizacji" grafów [[http://www.lri.fr/~filliatr/ocamlgraph/]].)

Podaj przykład praktycznej instancjacji funktora realizującego algorytm z dziedziny twojego projektu (tzn. nie implementującego kontener ani odwzorowanie) różnymi strukturami.
Changed line 720 from:
(lista elementów). Nie wymagaj od użytkownika podawania jakichś
to:
(lista elementów). Nie wymagaj od użytkownika podawania jakichś
Changed line 724 from:
Wytłumacz, jakie udogodnienie systemu modułów w OCamlu pozwala na
to:
Wytłumacz, jakie udogodnienie systemu modułów w OCamlu pozwala na
Changed lines 861-862 from:
Zrób ćwiczenie 10.8 z książki.
to:
Zrób ćwiczenie 10.8 z książki.
Changed lines 864-865 from:
Zaimplementuj przykład wykorzystania "mixin modules" z [[http://citeseer.ist.psu.edu/duggan96mixin.html |  Dominic Duggan, Constantinos Sourelis ''Mixin Modules'']] poszerzony o operację dodawania w module @@Num@@. Idea jest taka: typy i funkcje składamy z klocków zdefiniowanych w osobnych modułach, które można osobno kompilować. Poniżej dla wygody zaadoptowany do składni OCamla.
to:
Zaimplementuj przykład wykorzystania "mixin modules" z [[http://citeseer.ist.psu.edu/duggan96mixin.html |  Dominic Duggan, Constantinos Sourelis ''Mixin Modules'']] poszerzony o operację dodawania w module @@Num@@. Idea jest taka: typy i funkcje składamy z klocków zdefiniowanych w osobnych modułach, które można osobno kompilować. Poniżej dla wygody zaadoptowany do składni OCamla.
Changed lines 903-904 from:
Moduły "mixinowe" przerób na funktory wykorzystując pomysły z [[http://www.eecs.harvard.edu/~nr/pubs/maniaws-abstract.html | ML Module Mania: A Type-Safe, Separately Compiled, Extensible Interpreter]]. Być może konstrukcję da ci się uprościć wykorzystując dostępne w OCamlu moduły rekurencyjne (rekurencyjne będą oczywiście instancje funktorów @@Num@@ i @@Func@@, nie same te funktory, które muszą dać się osobno kompilować). UWAGA: nie ma potrzeby czytać całego artykułu Normana Ramseya, kluczem jest pojęcie "wieży typów" i "two-level types" oraz poskładanie kawałków przez funktory.
to:
Moduły "mixinowe" przerób na funktory wykorzystując pomysły z [[http://www.eecs.harvard.edu/~nr/pubs/maniaws-abstract.html | ML Module Mania: A Type-Safe, Separately Compiled, Extensible Interpreter]]. Być może konstrukcję da ci się uprościć wykorzystując dostępne w OCamlu moduły rekurencyjne (rekurencyjne będą oczywiście instancje funktorów @@Num@@ i @@Func@@, nie same te funktory, które muszą dać się osobno kompilować). UWAGA: nie ma potrzeby czytać całego artykułu Normana Ramseya, kluczem jest pojęcie "wieży typów" i "two-level types" oraz poskładanie kawałków przez funktory.
Changed lines 906-909 from:
Wieżą typów nazywam technikę budowania hierarchi typów przez wstawienie opcji "w innym przypadku..." Wieża typów to też jednonitkowa hierarchia typów.

"Two-level types" to generalnie rozci
ęcie definicji typu przez wprowadzenie parametrów, tak że definicję równoważną oryginalnej otrzymuje się przez podstawienie definiowanego typu pod parametr (fixpunkt). W zastosowaniach podstawia się coś co rekurencyjnie zależy od całości.
to:
Wieżą typów nazywam technikę budowania hierarchi typów przez wstawienie opcji "w innym przypadku..." Wieża typów to też jednonitkowa hierarchia typów.

"Two-level types" to generalnie rozcięcie definicji typu przez wprowadzenie parametr
ów, tak że definicję równoważną oryginalnej otrzymuje się przez podstawienie definiowanego typu pod parametr (fixpunkt). W zastosowaniach podstawia się coś co rekurencyjnie zależy od całości.
Changed lines 911-912 from:
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotyczące jednych przenoszą się na drugie. OCaml ma warianty polimorficzne, ale ciągle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bolączką (etykiety użytej w jednym typie rekordowym nie można użyć w innym w tym samym module). Naturalną ideą jest podtypowanie typów rekordowych, traktujące typ rekordowy z dodatkowymi etykietami jako podtyp wyjściowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystując koncepcje wieży typów i "two-level types" zbuduj przykładową hierarchię typów rekordowych i napisz funkcje demonstrujące praktyczne zachodzenie podtypowania. W jakiej mierze możliwe jest "wielodziedziczenie"?
to:
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotyczące jednych przenoszą się na drugie. OCaml ma warianty polimorficzne, ale ciągle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bolączką (etykiety użytej w jednym typie rekordowym nie można użyć w innym w tym samym module). Naturalną ideą jest podtypowanie typów rekordowych, traktujące typ rekordowy z dodatkowymi etykietami jako podtyp wyjściowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystując koncepcje wieży typów i "two-level types" zbuduj przykładową hierarchię typów rekordowych i napisz funkcje demonstrujące praktyczne zachodzenie podtypowania. W jakiej mierze możliwe jest "wielodziedziczenie"?
Changed lines 917-918 from:
"Zawiąż węzeł" (najpierw rozetnij ten za ciasno związany) następującej spłaszczonej wieży typów, tzn. podaj równoważną definicję, która się kompiluje:
to:
"Zawiąż węzeł" (najpierw rozetnij ten za ciasno związany) następującej spłaszczonej wieży typów, tzn. podaj równoważną definicję, która się kompiluje:
Changed lines 956-959 from:
# Przy pomocy typów zamkniętych, jak w poprzednim zadaniu (czyli np. jak w wyjściowym rozwiązaniu zadania 7, tylko z "płaskim otagowaniem" wariantami polimorficznymi -- bez zagnieżdżonych tagów i nietrywialnych projekcji / injekcji). Przykładowe rozwiązanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/variant-reuse.ps.gz |  Code reuse through polymorphic variants.]]

# Przy pomocy wariantów polimorficznych i typów otwartych. Typ otwarty w sygnaturze poprzedzamy słowem kluczowym @@private@@ (wymaga OCamla 3.09). Przykładowe rozwiązanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/privaterows-aplas2006.pdf | Private rows: abstracting the unnamed]].
to:
# Przy pomocy typów zamkniętych, jak w poprzednim zadaniu (czyli np. jak w wyjściowym rozwiązaniu zadania 7, tylko z "płaskim otagowaniem" wariantami polimorficznymi -- bez zagnieżdżonych tagów i nietrywialnych projekcji / injekcji). Przykładowe rozwiązanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/variant-reuse.ps.gz |  Code reuse through polymorphic variants.]]

# Przy pomocy wariantów polimorficznych i typów otwartych. Typ otwarty w sygnaturze poprzedzamy słowem kluczowym @@private@@ (wymaga OCamla 3.09). Przykładowe rozwiązanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/privaterows-aplas2006.pdf | Private rows: abstracting the unnamed]].
Changed lines 964-965 from:
Zamień funkcję [@map_reduce@] z [[#z12 | zad.2 listy 1]] na funkcję, która może (ale nie musi) pobrać gotową już listę par zamiast (a czasami dodatkowo do) listy dowolnych elementów i funkcji mapującej je na pary. Wykorzystaj argumenty opcjonalne [[http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html]] par. 4.1.1.
to:
Zamień funkcję [@map_reduce@] z [[#z12 | zad.2 listy 1]] na funkcję, która może (ale nie musi) pobrać gotową już listę par zamiast (a czasami dodatkowo do) listy dowolnych elementów i funkcji mapującej je na pary. Wykorzystaj argumenty opcjonalne [[http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html]] par. 4.1.1.
Changed lines 967-968 from:
Zdefiniuj hierarchię klas (albo typów klas) dla zwierząt, @@animal@@, @@camel@@, @@omnivore@@, @@bactrian_camel@@ oraz dla pożywienia @@food@@, @@grass@@, @@meat@@, @@green_grass@@. @@camel@@ i @@omnivore@@ są @@animal@@, @@grass@@ i @@meat@@ są @@food@@. @@green_grass@@ jest @@grass@@, @@bactrian_camel@@ jest @@camel@@. Zwierzęta mają metodę @@eat@@, każde zwierzę ma swoją dietę. @@omnivore@@ może jeść dowolne @@food@@. @@bactrian_camel@@ je @@green_grass@@. Zapewnij, że wszystkie zwierzęta dziedziczące z @@camel@@ mają dietę będącą podtypem @@grass@@ (nie mogą jeść @@meat@@) (ale może być ona zawężona, jak dla @@bactrian_camel@@). (Ogólnie zapewnij, że podtypowanie jest kowariantne względem diety.) Możesz wykorzystać klasy pomocnicze, klasyfikatory @@virtual@@, @@private@@, ograniczenia @@constraint@@, itd. ale postaraj się uzyskać możliwie proste rozwiązanie.
to:
Zdefiniuj hierarchię klas (albo typów klas) dla zwierząt, @@animal@@, @@camel@@, @@omnivore@@, @@bactrian_camel@@ oraz dla pożywienia @@food@@, @@grass@@, @@meat@@, @@green_grass@@. @@camel@@ i @@omnivore@@ są @@animal@@, @@grass@@ i @@meat@@ są @@food@@. @@green_grass@@ jest @@grass@@, @@bactrian_camel@@ jest @@camel@@. Zwierzęta mają metodę @@eat@@, każde zwierzę ma swoją dietę. @@omnivore@@ może jeść dowolne @@food@@. @@bactrian_camel@@ je @@green_grass@@. Zapewnij, że wszystkie zwierzęta dziedziczące z @@camel@@ mają dietę będącą podtypem @@grass@@ (nie mogą jeść @@meat@@) (ale może być ona zawężona, jak dla @@bactrian_camel@@). (Ogólnie zapewnij, że podtypowanie jest kowariantne względem diety.) Możesz wykorzystać klasy pomocnicze, klasyfikatory @@virtual@@, @@private@@, ograniczenia @@constraint@@, itd. ale postaraj się uzyskać możliwie proste rozwiązanie.
Changed lines 970-971 from:
Zdefiniuj "dwuargumentow&#261;" klas&#281; @@['a, 'b] cons@@ i "bezargumentow&#261;" klas&#281; @@['a, 'b] nil@@, definiuj&#261;ce obiekty typu [@ < null : bool; car : 'a; cdr : 'b > @]. (Oczywi&#347;cie wywo&#322;anie @@car@@ czy @@cdr@@ na obiekcie klasy @@nil@@ ma rzuci&#263; wyj&#261;tek.) Na bazie tych klas zdefiniuj typ homogenicznych (zwyk&#322;ych) list polimorficznych [@'a homo_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 5 (new nil))@], oraz typ list alternuj&#261;cych, zawieraj&#261;cych elementy z dwóch typów, na zmian&#281; [@('a, 'b) alt_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 'b' (new cons 5 (new nil))) @]. Sprawd&#378;, &#380;e przyk&#322;adowe warto&#347;ci rzeczywi&#347;cie maj&#261; zdefiniowane przez ciebie typy, a niechciane warto&#347;ci nie, np. &#380;e [@ new cons 2 (new cons 'b' (new cons 'a' (new nil))) @] nie jest list&#261; alternuj&#261;c&#261;. Zdefiniuj dziedzicz&#261;c&#261; z [@['a, 'b] cons@] klas&#281; [@['a, 'b] alt_cons@] pozwalaj&#261;c&#261; budowa&#263; tylko listy alternuj&#261;ce. Sprawd&#378;, &#380;e listy zbudowane z @@alt_cons@@ maj&#261; równie&#380; wcze&#347;niej zdefiniowany typ @@alt_list@@ i &#380;e wyra&#380;enie [@ new alt_cons 2 (new alt_cons 'b' (new alt_cons 'a' (new nil))) @] oraz inne nie b&#281;d&#261;ce listami alternuj&#261;cymi si&#281; nie typuj&#261;. Dodaj przez dziedziczenie metod&#281; @@length@@ do klas @@cons@@ i @@nil@@. Zdefiniuj klas&#281; list alternuj&#261;cych z d&#322;ugo&#347;ci&#261; @@alt_lcons@@ przez podwójne dziedziczenie. Uzasadnij, &#380;e zg&#322;oszone przez kompilator ostrze&#380;enia nie s&#261; w tym konkretnym przypadku b&#322;&#281;dami.
to:
Zdefiniuj "dwuargumentow&#261;" klas&#281; @@['a, 'b] cons@@ i "bezargumentow&#261;" klas&#281; @@['a, 'b] nil@@, definiuj&#261;ce obiekty typu [@ < null : bool; car : 'a; cdr : 'b > @]. (Oczywi&#347;cie wywo&#322;anie @@car@@ czy @@cdr@@ na obiekcie klasy @@nil@@ ma rzuci&#263; wyj&#261;tek.) Na bazie tych klas zdefiniuj typ homogenicznych (zwyk&#322;ych) list polimorficznych [@'a homo_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 5 (new nil))@], oraz typ list alternuj&#261;cych, zawieraj&#261;cych elementy z dw&#243;ch typ&#243;w, na zmian&#281; [@('a, 'b) alt_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 'b' (new cons 5 (new nil))) @]. Sprawd&#378;, &#380;e przyk&#322;adowe warto&#347;ci rzeczywi&#347;cie maj&#261; zdefiniowane przez ciebie typy, a niechciane warto&#347;ci nie, np. &#380;e [@ new cons 2 (new cons 'b' (new cons 'a' (new nil))) @] nie jest list&#261; alternuj&#261;c&#261;. Zdefiniuj dziedzicz&#261;c&#261; z [@['a, 'b] cons@] klas&#281; [@['a, 'b] alt_cons@] pozwalaj&#261;c&#261; budowa&#263; tylko listy alternuj&#261;ce. Sprawd&#378;, &#380;e listy zbudowane z @@alt_cons@@ maj&#261; r&#243;wnie&#380; wcze&#347;niej zdefiniowany typ @@alt_list@@ i &#380;e wyra&#380;enie [@ new alt_cons 2 (new alt_cons 'b' (new alt_cons 'a' (new nil))) @] oraz inne nie b&#281;d&#261;ce listami alternuj&#261;cymi si&#281; nie typuj&#261;. Dodaj przez dziedziczenie metod&#281; @@length@@ do klas @@cons@@ i @@nil@@. Zdefiniuj klas&#281; list alternuj&#261;cych z d&#322;ugo&#347;ci&#261; @@alt_lcons@@ przez podw&#243;jne dziedziczenie. Uzasadnij, &#380;e zg&#322;oszone przez kompilator ostrze&#380;enia nie s&#261; w tym konkretnym przypadku b&#322;&#281;dami.
Changed lines 976-977 from:
Zaprezentuj (zaimplementuj) model "subject - observer" na podstawie którego&#347; podr&#281;cznika do OCamla.
to:
Zaprezentuj (zaimplementuj) model "subject - observer" na podstawie kt&#243;rego&#347; podr&#281;cznika do OCamla.
Added lines 5-6:
&#243;
January 27, 2007, at 09:19 PM by 192.168.3.130 -
January 27, 2007, at 08:25 PM by 192.168.3.130 -
Changed line 33 from:
[@
to:
(:source lang=ocaml:)
Changed lines 38-39 from:
@]
to:
(:sourcend:)
Added lines 903-907:
!!!! Dodatkowe uwagi.
Wie&#380;&#261; typów nazywam technik&#281; budowania hierarchi typów przez wstawienie opcji "w innym przypadku..." Wie&#380;a typów to te&#380; jednonitkowa hierarchia typów.

"Two-level types" to generalnie rozci&#281;cie definicji typu przez wprowadzenie parametrów, tak &#380;e definicj&#281; równowa&#380;n&#261; oryginalnej otrzymuje si&#281; przez podstawienie definiowanego typu pod parametr (fixpunkt). W zastosowaniach podstawia si&#281; co&#347; co rekurencyjnie zale&#380;y od ca&#322;o&#347;ci.

Changed lines 904-905 from:
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotycz&#261;ce jednych przenosz&#261; si&#281; na drugie. Nowy OCaml ma warianty polimorficzne, ale ci&#261;gle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bol&#261;czk&#261; (etykiety u&#380;ytej w jednym typie rekordowym nie mo&#380;na u&#380;y&#263; w innym w tym samym module). Naturaln&#261; ide&#261; jest podtypowanie typów rekordowych, traktuj&#261;ce typ rekordowy z dodatkowymi etykietami jako podtyp wyj&#347;ciowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystuj&#261;c koncepcje wie&#380;y typów i "two-level types" zbuduj przyk&#322;adow&#261; hierarchi&#281; typów rekordowych i napisz funkcje demonstruj&#261;ce praktyczne zachodzenie podtypowania. W jakiej mierze mo&#380;liwe jest "wielodziedziczenie"?
to:
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotycz&#261;ce jednych przenosz&#261; si&#281; na drugie. OCaml ma warianty polimorficzne, ale ci&#261;gle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bol&#261;czk&#261; (etykiety u&#380;ytej w jednym typie rekordowym nie mo&#380;na u&#380;y&#263; w innym w tym samym module). Naturaln&#261; ide&#261; jest podtypowanie typów rekordowych, traktuj&#261;ce typ rekordowy z dodatkowymi etykietami jako podtyp wyj&#347;ciowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystuj&#261;c koncepcje wie&#380;y typów i "two-level types" zbuduj przyk&#322;adow&#261; hierarchi&#281; typów rekordowych i napisz funkcje demonstruj&#261;ce praktyczne zachodzenie podtypowania. W jakiej mierze mo&#380;liwe jest "wielodziedziczenie"?
Changed lines 901-902 from:
Modu&#322;y "mixinowe" przerób na funktory wykorzystuj&#261;c pomys&#322;y z [[http://www.eecs.harvard.edu/~nr/pubs/maniaws-abstract.html | ML Module Mania: A Type-Safe, Separately Compiled, Extensible Interpreter]]. By&#263; mo&#380;e konstrukcj&#281; da ci si&#281; upro&#347;ci&#263; wykorzystuj&#261;c dost&#281;pne w OCamlu modu&#322;y rekurencyjne (rekurencyjne b&#281;d&#261; oczywi&#347;cie instancje funktorów @@Num@@ i @@Func@@, nie same te funktory, które musz&#261; da&#263; si&#281; osobno kompilowa&#263;). UWAGA: nie ma potrzeby czyta&#263; ca&#322;ego artyku&#322;u Normana Ramseya, kluczem jest poj&#281;cie "wie&#380;y typów" i posk&#322;adanie kawa&#322;ków przez funktory.
to:
Modu&#322;y "mixinowe" przerób na funktory wykorzystuj&#261;c pomys&#322;y z [[http://www.eecs.harvard.edu/~nr/pubs/maniaws-abstract.html | ML Module Mania: A Type-Safe, Separately Compiled, Extensible Interpreter]]. By&#263; mo&#380;e konstrukcj&#281; da ci si&#281; upro&#347;ci&#263; wykorzystuj&#261;c dost&#281;pne w OCamlu modu&#322;y rekurencyjne (rekurencyjne b&#281;d&#261; oczywi&#347;cie instancje funktorów @@Num@@ i @@Func@@, nie same te funktory, które musz&#261; da&#263; si&#281; osobno kompilowa&#263;). UWAGA: nie ma potrzeby czyta&#263; ca&#322;ego artyku&#322;u Normana Ramseya, kluczem jest poj&#281;cie "wie&#380;y typów" i "two-level types" oraz posk&#322;adanie kawa&#322;ków przez funktory.
Changed lines 904-905 from:
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotycz&#261;ce jednych przenosz&#261; si&#281; na drugie. Nowy OCaml ma warianty polimorficzne, ale ci&#261;gle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bol&#261;czk&#261; (etykiety u&#380;ytej w jednym typie rekordowym nie mo&#380;na u&#380;y&#263; w innym w tym samym module). Naturaln&#261; ide&#261; jest podtypowanie typów rekordowych, traktuj&#261;ce typ rekordowy z dodatkowymi etykietami jako podtyp wyj&#347;ciowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystuj&#261;c koncepcje wie&#380;y typów czy te&#380; "two-level types" zbuduj przyk&#322;adow&#261; hierarchi&#281; typów rekordowych i napisz funkcje demonstruj&#261;ce praktyczne zachodzenie podtypowania.
to:
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotycz&#261;ce jednych przenosz&#261; si&#281; na drugie. Nowy OCaml ma warianty polimorficzne, ale ci&#261;gle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bol&#261;czk&#261; (etykiety u&#380;ytej w jednym typie rekordowym nie mo&#380;na u&#380;y&#263; w innym w tym samym module). Naturaln&#261; ide&#261; jest podtypowanie typów rekordowych, traktuj&#261;ce typ rekordowy z dodatkowymi etykietami jako podtyp wyj&#347;ciowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystuj&#261;c koncepcje wie&#380;y typów i "two-level types" zbuduj przyk&#322;adow&#261; hierarchi&#281; typów rekordowych i napisz funkcje demonstruj&#261;ce praktyczne zachodzenie podtypowania. W jakiej mierze mo&#380;liwe jest "wielodziedziczenie"?
Changed line 14 from:
* [[#l8 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]], [[#z87 | zad.7]])
to:
* [[#l8 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]], [[#z87 | zad.7]], [[#z88 | zad.8]])
Added lines 903-905:
!!! [[#z88]] Zadanie 8.
Warianty i rekordy to koncepcje w pewnym sensie dualne, dlatego zagadnienia dotycz&#261;ce jednych przenosz&#261; si&#281; na drugie. Nowy OCaml ma warianty polimorficzne, ale ci&#261;gle nie ma rekordów polimorficznych, dlatego "recykling" etykiet rekordów pozostaje bol&#261;czk&#261; (etykiety u&#380;ytej w jednym typie rekordowym nie mo&#380;na u&#380;y&#263; w innym w tym samym module). Naturaln&#261; ide&#261; jest podtypowanie typów rekordowych, traktuj&#261;ce typ rekordowy z dodatkowymi etykietami jako podtyp wyj&#347;ciowego typu rekordowego, w sensie [@type p3d = {x : float; y : float; z : float}@] "jest podtypem" [@type p2d = {x : float; y : float}@]. Wykorzystuj&#261;c koncepcje wie&#380;y typów czy te&#380; "two-level types" zbuduj przyk&#322;adow&#261; hierarchi&#281; typów rekordowych i napisz funkcje demonstruj&#261;ce praktyczne zachodzenie podtypowania.

December 12, 2006, at 01:46 AM by 83.27.170.4 - the end
Added lines 967-968:

!!! THE END.
Changed lines 15-16 from:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]], [[#z94 | zad.4]])
to:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]], [[#z94 | zad.4]], [[#z95 | zad.5]], [[#z96 | zad.6]], [[#z97 | zad.7]])
Changed lines 960-966 from:
Zdefiniuj "dwuargumentow&#261;" klas&#281; @@['a, 'b] cons@@ i "bezargumentow&#261;" klas&#281; @@['a, 'b] nil@@, definiuj&#261;ce obiekty typu [@ < null : bool; car : 'a; cdr : 'b > @]. (Oczywi&#347;cie wywo&#322;anie @@car@@ czy @@cdr@@ na obiekcie klasy @@nil@@ ma rzuci&#263; wyj&#261;tek.) Na bazie tych klas zdefiniuj typ homogenicznych (zwyk&#322;ych) list polimorficznych [@'a homo_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 5 (new nil))@], oraz typ list alternuj&#261;cych, zawieraj&#261;cych elementy z dwóch typów, na zmian&#281; [@('a, 'b) alt_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 'b' (new cons 5 (new nil))) @]. Sprawd&#378;, &#380;e przyk&#322;adowe warto&#347;ci rzeczywi&#347;cie maj&#261; zdefiniowane przez ciebie typy, a niechciane warto&#347;ci nie, np. &#380;e [@ new cons 2 (new cons 'b' (new cons 'a' (new nil))) @] nie jest list&#261; alternuj&#261;c&#261;. Zdefiniuj dziedzicz&#261;c&#261; z [@['a, 'b] cons@] klas&#281; [@['a, 'b] alt_cons@] pozwalaj&#261;c&#261; budowa&#263; tylko listy alternuj&#261;ce. Sprawd&#378;, &#380;e listy zbudowane z @@alt_cons@@ maj&#261; równie&#380; wcze&#347;niej zdefiniowany typ @@alt_list@@ i &#380;e wyra&#380;enie [@ new alt_cons 2 (new alt_cons 'b' (new alt_cons 'a' (new nil))) @] oraz inne nie b&#281;d&#261;ce listami alternuj&#261;cymi si&#281; nie typuj&#261;. Dodaj przez dziedziczenie metod&#281; @@length@@ do klas @@cons@@ i @@nil@@. Zdefiniuj klas&#281; list alternuj&#261;cych z d&#322;ugo&#347;ci&#261; @@alt_lcons@@ przez podwójne dziedziczenie. Uzasadnij, &#380;e zg&#322;oszone przez kompilator ostrze&#380;enia nie s&#261; w tym konkretnym przypadku b&#322;&#281;dami.
to:
Zdefiniuj "dwuargumentow&#261;" klas&#281; @@['a, 'b] cons@@ i "bezargumentow&#261;" klas&#281; @@['a, 'b] nil@@, definiuj&#261;ce obiekty typu [@ < null : bool; car : 'a; cdr : 'b > @]. (Oczywi&#347;cie wywo&#322;anie @@car@@ czy @@cdr@@ na obiekcie klasy @@nil@@ ma rzuci&#263; wyj&#261;tek.) Na bazie tych klas zdefiniuj typ homogenicznych (zwyk&#322;ych) list polimorficznych [@'a homo_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 5 (new nil))@], oraz typ list alternuj&#261;cych, zawieraj&#261;cych elementy z dwóch typów, na zmian&#281; [@('a, 'b) alt_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 'b' (new cons 5 (new nil))) @]. Sprawd&#378;, &#380;e przyk&#322;adowe warto&#347;ci rzeczywi&#347;cie maj&#261; zdefiniowane przez ciebie typy, a niechciane warto&#347;ci nie, np. &#380;e [@ new cons 2 (new cons 'b' (new cons 'a' (new nil))) @] nie jest list&#261; alternuj&#261;c&#261;. Zdefiniuj dziedzicz&#261;c&#261; z [@['a, 'b] cons@] klas&#281; [@['a, 'b] alt_cons@] pozwalaj&#261;c&#261; budowa&#263; tylko listy alternuj&#261;ce. Sprawd&#378;, &#380;e listy zbudowane z @@alt_cons@@ maj&#261; równie&#380; wcze&#347;niej zdefiniowany typ @@alt_list@@ i &#380;e wyra&#380;enie [@ new alt_cons 2 (new alt_cons 'b' (new alt_cons 'a' (new nil))) @] oraz inne nie b&#281;d&#261;ce listami alternuj&#261;cymi si&#281; nie typuj&#261;. Dodaj przez dziedziczenie metod&#281; @@length@@ do klas @@cons@@ i @@nil@@. Zdefiniuj klas&#281; list alternuj&#261;cych z d&#322;ugo&#347;ci&#261; @@alt_lcons@@ przez podwójne dziedziczenie. Uzasadnij, &#380;e zg&#322;oszone przez kompilator ostrze&#380;enia nie s&#261; w tym konkretnym przypadku b&#322;&#281;dami.

!!! [[#z96]] Zadanie 6.
&#262;wiczenie 32 z [[http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-mixins.html#toc19]].

!!! [[#z97]] Zadanie 7.
Zaprezentuj (zaimplementuj) model "subject - observer" na podstawie którego&#347; podr&#281;cznika do OCamla
.
Added lines 959-960:
!!! [[#z95]] Zadanie 5.
Zdefiniuj "dwuargumentow&#261;" klas&#281; @@['a, 'b] cons@@ i "bezargumentow&#261;" klas&#281; @@['a, 'b] nil@@, definiuj&#261;ce obiekty typu [@ < null : bool; car : 'a; cdr : 'b > @]. (Oczywi&#347;cie wywo&#322;anie @@car@@ czy @@cdr@@ na obiekcie klasy @@nil@@ ma rzuci&#263; wyj&#261;tek.) Na bazie tych klas zdefiniuj typ homogenicznych (zwyk&#322;ych) list polimorficznych [@'a homo_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 5 (new nil))@], oraz typ list alternuj&#261;cych, zawieraj&#261;cych elementy z dwóch typów, na zmian&#281; [@('a, 'b) alt_list@] -- przyk&#322;adowa warto&#347;&#263;: [@ new cons 2 (new cons 'b' (new cons 5 (new nil))) @]. Sprawd&#378;, &#380;e przyk&#322;adowe warto&#347;ci rzeczywi&#347;cie maj&#261; zdefiniowane przez ciebie typy, a niechciane warto&#347;ci nie, np. &#380;e [@ new cons 2 (new cons 'b' (new cons 'a' (new nil))) @] nie jest list&#261; alternuj&#261;c&#261;. Zdefiniuj dziedzicz&#261;c&#261; z [@['a, 'b] cons@] klas&#281; [@['a, 'b] alt_cons@] pozwalaj&#261;c&#261; budowa&#263; tylko listy alternuj&#261;ce. Sprawd&#378;, &#380;e listy zbudowane z @@alt_cons@@ maj&#261; równie&#380; wcze&#347;niej zdefiniowany typ @@alt_list@@ i &#380;e wyra&#380;enie [@ new alt_cons 2 (new alt_cons 'b' (new alt_cons 'a' (new nil))) @] oraz inne nie b&#281;d&#261;ce listami alternuj&#261;cymi si&#281; nie typuj&#261;. Dodaj przez dziedziczenie metod&#281; @@length@@ do klas @@cons@@ i @@nil@@. Zdefiniuj klas&#281; list alternuj&#261;cych z d&#322;ugo&#347;ci&#261; @@alt_lcons@@ przez podwójne dziedziczenie. Uzasadnij, &#380;e zg&#322;oszone przez kompilator ostrze&#380;enia nie s&#261; w tym konkretnym przypadku b&#322;&#281;dami.
Changed lines 15-16 from:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]])
to:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]], [[#z94 | zad.4]])
Changed line 861 from:
!!! [[#z87]] Zadanie 7.
to:
!!! [[#z87]] Zadanie 7. The Expression Problem (Part I)
Deleted lines 902-903:
P.S. Na nast&#281;pnej li&#347;cie rozwi&#261;&#380;emy ten problem bez wytaczania "ci&#281;&#380;kiej machinerii" wie&#380;y typów czy "two-level types" (ale zdecydowanie poza SMLem), przy u&#380;yciu wariantów polimorficznych.
Changed line 943 from:
!!! [[#z92]] Zadanie 2.
to:
!!! [[#z92]] Zadanie 2. The Expression Problem (Part II)
Changed lines 948-949 from:
# Przy pomocy wariantów polimorficznych i typów otwartych. Typ otwarty w sygnaturze poprzedzamy s&#322;owem kluczowym @@private@@ (wymaga OCamla 3.09). Porównaj [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/privaterows-aplas2006.pdf | Private rows: abstracting the unnamed]].
to:
# Przy pomocy wariantów polimorficznych i typów otwartych. Typ otwarty w sygnaturze poprzedzamy s&#322;owem kluczowym @@private@@ (wymaga OCamla 3.09). Przyk&#322;adowe rozwi&#261;zanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/privaterows-aplas2006.pdf | Private rows: abstracting the unnamed]].
Added line 952:
Added lines 957-958:
Zdefiniuj hierarchi&#281; klas (albo typów klas) dla zwierz&#261;t, @@animal@@, @@camel@@, @@omnivore@@, @@bactrian_camel@@ oraz dla po&#380;ywienia @@food@@, @@grass@@, @@meat@@, @@green_grass@@. @@camel@@ i @@omnivore@@ s&#261; @@animal@@, @@grass@@ i @@meat@@ s&#261; @@food@@. @@green_grass@@ jest @@grass@@, @@bactrian_camel@@ jest @@camel@@. Zwierz&#281;ta maj&#261; metod&#281; @@eat@@, ka&#380;de zwierz&#281; ma swoj&#261; diet&#281;. @@omnivore@@ mo&#380;e je&#347;&#263; dowolne @@food@@. @@bactrian_camel@@ je @@green_grass@@. Zapewnij, &#380;e wszystkie zwierz&#281;ta dziedzicz&#261;ce z @@camel@@ maj&#261; diet&#281; b&#281;d&#261;c&#261; podtypem @@grass@@ (nie mog&#261; je&#347;&#263; @@meat@@) (ale mo&#380;e by&#263; ona zaw&#281;&#380;ona, jak dla @@bactrian_camel@@). (Ogólnie zapewnij, &#380;e podtypowanie jest kowariantne wzgl&#281;dem diety.) Mo&#380;esz wykorzysta&#263; klasy pomocnicze, klasyfikatory @@virtual@@, @@private@@, ograniczenia @@constraint@@, itd. ale postaraj si&#281; uzyska&#263; mo&#380;liwie proste rozwi&#261;zanie.
Changed lines 955-956 from:
Zamie&#324; funkcj&#281; [@map_reduce@] z [[#z12 | zad.2 listy 1]] na funkcj&#281;, która mo&#380;e (ale nie musi) pobra&#263; gotow&#261; ju&#380; list&#281; par zamiast (a czasami dodatkowo do) listy dowolnych argumentów i funkcji mapuj&#261;cej je na pary. Wykorzystaj argumenty opcjonalne [[http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html]] par. 4.1.1.
to:
Zamie&#324; funkcj&#281; [@map_reduce@] z [[#z12 | zad.2 listy 1]] na funkcj&#281;, która mo&#380;e (ale nie musi) pobra&#263; gotow&#261; ju&#380; list&#281; par zamiast (a czasami dodatkowo do) listy dowolnych elementów i funkcji mapuj&#261;cej je na pary. Wykorzystaj argumenty opcjonalne [[http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html]] par. 4.1.1.
Changed lines 946-947 from:
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na dwa kolejne sposoby: przy pomocy wariantów polimorficznych i typów otwartych, oraz przy pomocy typów zamkni&#281;tych, jak w poprzednim zadaniu (czyli np. jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji). Przyk&#322;adowe rozwi&#261;zanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/variant-reuse.ps.gz |  Code reuse through polymorphic variants.]]
to:
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na trzy kolejne sposoby.

# Przy
pomocy typów zamkni&#281;tych, jak w poprzednim zadaniu (czyli np. jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji). Przyk&#322;adowe rozwi&#261;zanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/variant-reuse.ps.gz |  Code reuse through polymorphic variants.]]

# Przy pomocy wariantów polimorficznych i typów otwartych
. Typ otwarty w sygnaturze poprzedzamy s&#322;owem kluczowym @@private@@ (wymaga OCamla 3.09). Porównaj [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/privaterows-aplas2006.pdf | Private rows: abstracting the unnamed]].

# Przy pomocy klas, jak w [[http://pauillac.inria.fr/~remy/work/expr/]].

Changed line 36 from:
  'a list -> ('a -> 'b * 'c) -> ('d -> 'c -> 'd) -> 'd -> ('b * 'd) list =
to:
  ('a -> 'b * 'c) -> ('d -> 'c -> 'd) -> 'd -> 'a list -> ('b * 'd) list =
Changed lines 15-16 from:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]])
to:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]], [[#z93 | zad.3]])
Changed lines 31-34 from:
!!!! Dodatkowe wskazówki do zadania [@map_reduce@] z "listy 1":

Napisz funkcj
&#281;
to:
Zachowaj pe&#322;n&#261; polimorficzno&#347;&#263;, tzn. sygnatur&#281;:
Changed lines 34-37 from:
let map_reduce fmap freduce v0 xs = ...
to:
let map_reduce mapf redf red0 xs = ...
val map_reduce :
  'a list -> ('a -> 'b * 'c) -> ('d -> 'c -> 'd) -> 'd -> ('b * 'd) list =
  <fun>
Deleted lines 39-44:
obliczaj&#261;c&#261; list&#281; par klucz-warto&#347;&#263; przez "List.map fmap xs",
grupuj&#261;c&#261; warto&#347;ci o tym samym kluczu w listy "intermediate", oraz
zwracaj&#261;ce list&#281; par klucz-nowa warto&#347;&#263;, gdzie nowa warto&#347;&#263; =
[@List.fold_left freduce v0 intermediate@].

Added line 908:
Zapoznaj si&#281; z wariantami polimorficznymi [[http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html]], par. 4.2.
Added lines 947-951:

!!! [[#z93]] Zadanie 3.
Zamie&#324; funkcj&#281; [@map_reduce@] z [[#z12 | zad.2 listy 1]] na funkcj&#281;, która mo&#380;e (ale nie musi) pobra&#263; gotow&#261; ju&#380; list&#281; par zamiast (a czasami dodatkowo do) listy dowolnych argumentów i funkcji mapuj&#261;cej je na pary. Wykorzystaj argumenty opcjonalne [[http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html]] par. 4.1.1.

!!! [[#z94]] Zadanie 4.
Changed lines 676-677 from:
b) Zapoznaj si&#281; z bibliotek&#261; "ocamlgraph": [[http://www.lri.fr/~filliatr/ocamlgraph/]]. Napisz funktor dodaj&#261;cy operacj&#281; dekompozycji z "grafów indukcyjnych" do grafów z "ocamlgraph".
to:
b) Zapoznaj si&#281; z bibliotek&#261; "ocamlgraph": [[http://www.lri.fr/~filliatr/ocamlgraph/]]. (*) Napisz funktor dodaj&#261;cy operacj&#281; dekompozycji z "grafów indukcyjnych" do grafów z "ocamlgraph".
Changed line 950 from:
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na dwa kolejne sposoby: przy pomocy wariantów polimorficznych i typów otwartych, oraz przy pomocy typów zamkni&#281;tych, jak w poprzednim zadaniu (czyli tak jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji).
to:
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na dwa kolejne sposoby: przy pomocy wariantów polimorficznych i typów otwartych, oraz przy pomocy typów zamkni&#281;tych, jak w poprzednim zadaniu (czyli np. jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji). Przyk&#322;adowe rozwi&#261;zanie: [[http://www.math.nagoya-u.ac.jp/~garrigue/papers/variant-reuse.ps.gz |  Code reuse through polymorphic variants.]]
November 29, 2006, at 10:38 PM by 83.27.171.108 -
Changed lines 15-16 from:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2)
to:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2]])
Changed line 950 from:
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na dwa kolejne sposoby: przy pomocy wariantów polimorficznych i typów otwartych, oraz przy pomocy typów zamkni&#281;tych "two-level types", jak w poprzednim zadaniu (czyli tak jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji).
to:
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na dwa kolejne sposoby: przy pomocy wariantów polimorficznych i typów otwartych, oraz przy pomocy typów zamkni&#281;tych, jak w poprzednim zadaniu (czyli tak jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji).
November 29, 2006, at 10:36 PM by 83.27.171.108 -
Changed lines 15-16 from:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]])
to:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]], [[#z92 | zad.2)
Changed lines 913-914 from:
"Zawi&#261;&#380; w&#281;ze&#322;" nast&#281;puj&#261;cej sp&#322;aszczonej wie&#380;y typów, tzn. podaj równowa&#380;n&#261; definicj&#281;, która si&#281; kompiluje:
to:
"Zawi&#261;&#380; w&#281;ze&#322;" (najpierw rozetnij ten za ciasno zwi&#261;zany) nast&#281;puj&#261;cej sp&#322;aszczonej wie&#380;y typów, tzn. podaj równowa&#380;n&#261; definicj&#281;, która si&#281; kompiluje:
Added lines 948-950:

!!! [[#z92]] Zadanie 2.
Zaimplementuj przyk&#322;ad z zadania 7 listy 8 na dwa kolejne sposoby: przy pomocy wariantów polimorficznych i typów otwartych, oraz przy pomocy typów zamkni&#281;tych "two-level types", jak w poprzednim zadaniu (czyli tak jak w wyj&#347;ciowym rozwi&#261;zaniu zadania 7, tylko z "p&#322;askim otagowaniem" wariantami polimorficznymi -- bez zagnie&#380;d&#380;onych tagów i nietrywialnych projekcji / injekcji).
November 29, 2006, at 06:26 PM by 83.27.171.108 -
Changed lines 15-16 from:
* lista 9 argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty
to:
* [[#l9 | lista 9]] argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty ([[#z91 | zad.1]])
Added lines 909-947:

!! [[#l9]] Lista 9.

!!! [[#z91]] Zadanie 1.
"Zawi&#261;&#380; w&#281;ze&#322;" nast&#281;puj&#261;cej sp&#322;aszczonej wie&#380;y typów, tzn. podaj równowa&#380;n&#261; definicj&#281;, która si&#281; kompiluje:

[@
type number =
    [ `NCst of num (** numeric constant *)
    | `Ninf (** positive infinity *)
    | `Neginf (** negative infinity *)
    ]

type variable =
    [ `EVar of string (** (existential) variable *)
    | `UVar of string (** constant (universal
    variable) *)
    ]

type num_coef =
    [ `Mult of num * variable (** constant coefficient *)
    ]

type numeric =
    [ number | num_coef
    | `Add of num_coef list * number (** linear combination *)
    ]
;;

type construct =
    [ `TCons of string * typ list
    | `Fun of proper_typ * proper_typ
    ]

and proper_typ = [variable | construct]

and typ = [proper_typ | numeric]
;;
@]
November 29, 2006, at 04:47 AM by 83.27.171.108 -
Changed line 908 from:
P.S. Na nast&#281;pnej li&#347;cie rozwi&#261;&#380;emy to zadanie bez wytaczania "ci&#281;&#380;kiej machinerii" wie&#380;y typów czy "two-level types", przy u&#380;yciu wariantów polimorficznych.
to:
P.S. Na nast&#281;pnej li&#347;cie rozwi&#261;&#380;emy ten problem bez wytaczania "ci&#281;&#380;kiej machinerii" wie&#380;y typów czy "two-level types" (ale zdecydowanie poza SMLem), przy u&#380;yciu wariantów polimorficznych.
November 29, 2006, at 04:42 AM by 83.27.171.108 -
Added lines 907-908:

P.S. Na nast&#281;pnej li&#347;cie rozwi&#261;&#380;emy to zadanie bez wytaczania "ci&#281;&#380;kiej machinerii" wie&#380;y typów czy "two-level types", przy u&#380;yciu wariantów polimorficznych.
November 29, 2006, at 04:27 AM by 83.27.171.108 -
Added lines 865-906:

!!! [[#z87]] Zadanie 7.
Zaimplementuj przyk&#322;ad wykorzystania "mixin modules" z [[http://citeseer.ist.psu.edu/duggan96mixin.html |  Dominic Duggan, Constantinos Sourelis ''Mixin Modules'']] poszerzony o operacj&#281; dodawania w module @@Num@@. Idea jest taka: typy i funkcje sk&#322;adamy z klocków zdefiniowanych w osobnych modu&#322;ach, które mo&#380;na osobno kompilowa&#263;. Poni&#380;ej dla wygody zaadoptowany do sk&#322;adni OCamla.

[@
module Num =
mixin body
  type term = Const of int | Add of term * term
  type value = Num of int
  type env
  let rec eval tm (e:env) = match tm with
    | Const i -> Num i
    | Add (t1, t2) -> begin match eval t1, eval t2 with
      | Num i, Num j -> Num (i + j)
      | _ -> failwith "Num.eval: type mismatch"
      end
    | tm -> inner tm e
end (* Num *)

module Func =
mixin
  let bind (x, v, e) = fun y ->
    if x=y then v else e y
body
  type term = Var of string
    | Abs of string * term | App of term * term
  type value = Clos of term * env
  and env = string -> value
  let eval tm (e:env) = match tm with
    | Var x -> e x
    | Abs _ as f -> Clos (f, e)
    | App (rator, rand) e -> begin
      match eval rator e with
      | Clos (Abs (x, b), e') ->
        eval b (bind (x, eval rand e, e'))
      | _ -> failwith "Func.eval: type mismatch"
      end
    | _ -> inner tm e
end (* Func *)
@]

Modu&#322;y "mixinowe" przerób na funktory wykorzystuj&#261;c pomys&#322;y z [[http://www.eecs.harvard.edu/~nr/pubs/maniaws-abstract.html | ML Module Mania: A Type-Safe, Separately Compiled, Extensible Interpreter]]. By&#263; mo&#380;e konstrukcj&#281; da ci si&#281; upro&#347;ci&#263; wykorzystuj&#261;c dost&#281;pne w OCamlu modu&#322;y rekurencyjne (rekurencyjne b&#281;d&#261; oczywi&#347;cie instancje funktorów @@Num@@ i @@Func@@, nie same te funktory, które musz&#261; da&#263; si&#281; osobno kompilowa&#263;). UWAGA: nie ma potrzeby czyta&#263; ca&#322;ego artyku&#322;u Normana Ramseya, kluczem jest poj&#281;cie "wie&#380;y typów" i posk&#322;adanie kawa&#322;ków przez funktory.
November 29, 2006, at 03:41 AM by 83.27.171.108 -
Changed lines 14-16 from:
* [[#l8 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]])
* lista 9 argumenty etykietowane,
argumenty domy&#347;lne, tzw. warianty polimorficzne, obiekty
to:
* [[#l8 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]], [[#z87 | zad.7]])
* lista 9
argumenty etykietowane, domy&#347;lne warto&#347;ci argumentów, tzw. warianty polimorficzne, obiekty
Changed line 14 from:
* [[#l7 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]])
to:
* [[#l8 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]])
Changed lines 676-677 from:
b*) Zaimplementuj w OCamlu bibliotek&#281; dla grafów funkcyjnych (trwa&#322;ych, "persistent"), np. w oparciu o [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#IFL97]]
to:
b) Zapoznaj si&#281; z bibliotek&#261; "ocamlgraph": [[http://www.lri.fr/~filliatr/ocamlgraph/]]. Napisz funktor dodaj&#261;cy operacj&#281; dekompozycji z "grafów indukcyjnych" do grafów z "ocamlgraph".
Changed lines 713-714 from:
Zobacz, w jaki sposób Will Farr wykorzystuje funktory do sparametryzowania swoich algorytmów wzgl&#281;dem implementacji obiektów, na których one dzia&#322;aj&#261;: [[http://wmfarr.blogspot.com/2006/08/adventures-in-ocaml-land-barnes-hut.html]], [[http://wmfarr.blogspot.com/2006/10/automatic-differentiation-in-ocaml.html]] (wersja poprawiona [[http://wmfarr.blogspot.com/2006/10/correction-to-automatic.html]])
to:
Zobacz, w jaki sposób Will Farr wykorzystuje funktory do sparametryzowania swoich algorytmów wzgl&#281;dem implementacji obiektów, na których one dzia&#322;aj&#261;: [[http://wmfarr.blogspot.com/2006/08/adventures-in-ocaml-land-barnes-hut.html]], [[http://wmfarr.blogspot.com/2006/10/automatic-differentiation-in-ocaml.html]] (wersja poprawiona [[http://wmfarr.blogspot.com/2006/10/correction-to-automatic.html]]). (Mo&#380;esz te&#380; zobaczy&#263;, w jaki sposób Jean-Christophe Filliatre implementuje algorytmy grafowe w oderwaniu od konkretnej "realizacji" grafów [[http://www.lri.fr/~filliatr/ocamlgraph/]].)
November 27, 2006, at 07:24 PM by 83.8.60.106 - Powazny blad w przykladzie do zadania 2 lista 8
Changed line 706 from:
# Table1.compare s4 s3;;
to:
# Table2.compare s4 s3;;
Changed lines 15-16 from:
to:
* lista 9 argumenty etykietowane, argumenty domy&#347;lne, tzw. warianty polimorficzne, obiekty
Changed lines 14-15 from:
to:
* [[#l7 | lista 8]] modu&#322;y i funktory ([[#z81 | zad.1]], [[#z82 | zad.2]], [[#z83 | zad.3]], [[#z84 | zad.4]], [[#z85 | zad.5]], [[#z86 | zad.6]])
Changed lines 673-674 from:
a) Zapoznaj si&#281; z ide&#261; "grafów indukcyjnych": [[http://web.engr.oregonstate.edu/~erwig/fgl/]] Zapisz wybrany algorytm grafowy nie zaimplementowany w artykule "Inductive Graphs and Functional Graph Algorithms": [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01]] w "j&#281;zyku" grafów indukcyjnych.
to:
a) Zapoznaj si&#281; z ide&#261; "grafów indukcyjnych": [[http://web.engr.oregonstate.edu/~erwig/fgl/]] Zapisz wybrany algorytm grafowy nie zaimplementowany w artykule "Inductive Graphs and Functional Graph Algorithms": [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01]] w "j&#281;zyku grafów indukcyjnych".
Changed lines 666-862 from:
[[Attach:pa_lettry.cmo.zip | skompilowany i zzipowany plik z rozszerzeniem sk&#322;adniowym]]
to:
[[Attach:pa_lettry.cmo.zip | skompilowany i zzipowany plik z rozszerzeniem sk&#322;adniowym]]


!! [[#l8]] Lista 8.

!!! [[#z81]] Zadanie 1.
a) Zapoznaj si&#281; z ide&#261; "grafów indukcyjnych": [[http://web.engr.oregonstate.edu/~erwig/fgl/]] Zapisz wybrany algorytm grafowy nie zaimplementowany w artykule "Inductive Graphs and Functional Graph Algorithms": [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP01]] w "j&#281;zyku" grafów indukcyjnych.

b*) Zaimplementuj w OCamlu bibliotek&#281; dla grafów funkcyjnych (trwa&#322;ych, "persistent"), np. w oparciu o [[http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#IFL97]]

!!! [[#z82]] Zadanie 2.
Wygeneruj wspó&#322;dziel&#261;ce kod modu&#322;y o sygnaturze:

[@
module type SYMBOL_TABLE = sig
 type symbol
 val string_to_symbol : string -> symbol
 val symbol_to_string : symbol -> string
 val eq : symbol -> symbol -> bool
 val compare : symbol -> symbol -> int
end;;
@]

tak, &#380;e @@compare@@ jest funkcj&#261; porównuj&#261;c&#261; zgodn&#261; ze specyfikacj&#261;
[@Pervasives.compare@], przy czym symbol mniejszy to ten, który by&#322;
wcze&#347;niej widziany przez dany modu&#322;. Np.:

[@
# let s1 = Table1.string_to_symbol "Ala";;
val s1 : Table1.symbol = <abstr>
# let s2 = Table1.string_to_symbol "Becia";;
val s2 : Table1.symbol = <abstr>
# let s3 = Table2.string_to_symbol "Becia";;
val s3 : Table2.symbol = <abstr>
# let s4 = Table2.string_to_symbol "Ala";;
val s4 : Table1.symbol = <abstr>
# Table1.compare s1 s2;;
- : int = -1
# Table1.compare s4 s3;;
- : int = 1
@]

Do efektywnego odwzorowania ze stringów w symbole wykorzystaj modu&#322; @@Hashtbl@@.

!!! [[#z83]] Zadanie 3.
Zobacz, w jaki sposób Will Farr wykorzystuje funktory do sparametryzowania swoich algorytmów wzgl&#281;dem implementacji obiektów, na których one dzia&#322;aj&#261;: [[http://wmfarr.blogspot.com/2006/08/adventures-in-ocaml-land-barnes-hut.html]], [[http://wmfarr.blogspot.com/2006/10/automatic-differentiation-in-ocaml.html]] (wersja poprawiona [[http://wmfarr.blogspot.com/2006/10/correction-to-automatic.html]])

Podaj przyk&#322;ad praktycznej instancjacji funktora realizuj&#261;cego algorytm z dziedziny twojego projektu (tzn. nie implementuj&#261;cego kontener ani odwzorowanie) ró&#380;nymi strukturami.

!!! [[#z84]] Zadanie 4.
Napisz funktor konstruuj&#261;cy odwzorowania @@MyMap@@, pobieraj&#261;cy funktor
buduj&#261;cy zbiory oraz odpowiednie struktury dla kluczy i warto&#347;ci,
implementuj&#261;cy odwzorowania jako zbiory par (klucz, warto&#347;&#263;).
Przetestuj wykorzystuj&#261;c [@Set.Make@] z biblioteki standardowej. Do
zaimplementowania [@MyMap.find@] u&#380;yj @@inter@@ (intersection) i @@elements@@
(lista elementów). Nie wymagaj od u&#380;ytkownika podawania jakich&#347;
warto&#347;ci domy&#347;lnych / pocz&#261;tkowych w obrazie odwzorowania.

!!! [[#z85]] Zadanie 5.
Wyt&#322;umacz, jakie udogodnienie systemu modu&#322;ów w OCamlu pozwala na
nast&#281;puj&#261;c&#261; zwi&#281;z&#322;&#261; specyfikacj&#281;:

[@
module type DICT = functor (Key : Set.OrderedType) -> sig
 type 'a dict
 val domain : 'a dict -> Set.Make(Key).t
end;;

module type PRIO_QUEUE = functor (Elt : Set.OrderedType) -> sig
 type queue
 val contents : queue -> Set.Make(Elt).t
end;;

module QueuedDict (Data : Set.OrderedType)
 (MyDict : DICT) (MyPrioQueue : PRIO_QUEUE) =
struct
 module Dict = MyDict (Data)
 module PQ = MyPrioQueue (Data)
 module DataSet = Set.Make (Data)
 let queued_domain dict pq =
  DataSet.equal (Dict.domain dict) (PQ.contents pq)
end;;
@]

jednak w nast&#281;puj&#261;cym przyk&#322;adzie prowadzi do "katastrofy":

[@
let moonFull = let v = ref false in fun () -> v := not !v; !v
;;

module type S = sig
 type t
 val x : t
 val f : t -> t
 val g : t -> t -> bool
end;;

module Weird (Top : sig end) = (struct
 type t = int
 let x = if moonFull () then 1 else 2
 let f x = x + 2
 let g x y = (3*x + 2*y) / (x - y + 1) = 7
end : S);;

module Gen (X : functor (Top : sig end) -> S) = X (struct end);;

module W1 = Gen (Weird);; (* moon full now *)
module W2 = Gen (Weird);; (* moon no longer full now *)
W1.g W1.x W2.x;;
@]

Dlaczego to zachowanie jest niespodziewane? (Co my&#347;la&#322; sobie autor
modu&#322;u Weird?) Pouczaj&#261;ce s&#261; komunikaty o b&#322;&#281;dach:

[@
module W3 = Weird (struct end);;
module W4 = Weird (struct end);;
W3.g W3.x W4.x;;
4 = W1.x;;
@]

Zaimplementuj funktor QueuedDict w SMLu.

!!! [[#z86]] Zadanie 6.
Przeczytaj podrozdzia&#322; 10.2 z ksi&#261;&#380;ki Chrisa Okasaki "Purely
Functional Data Structures" z pomini&#281;ciem analizy z&#322;o&#380;ono&#347;ci na ko&#324;cu
paragrafu 10.2.1 (str. 156-157). Przeanalizuj fragment kodu (z
[[http://caml.inria.fr/pub/papers/xleroy-recursive_modules-03.pdf]]):

[@
module type ORDERED =
sig
 type t
 val eq: t -> t -> bool
 val lt: t -> t -> bool
 val leq: t -> t -> bool
end

module type HEAP =
sig
 module Elem: ORDERED
 type heap
 val empty: heap
 val isEmpty: heap -> bool
 val insert: Elem.t -> heap -> heap
 val merge: heap -> heap -> heap
 val findMin: heap -> Elem.t
 val deleteMin: heap -> heap
end

module Bootstrap (MakeH: functor (Element:ORDERED) ->
 HEAP with module Elem = Element)
 (Element: ORDERED) : HEAP with module Elem = Element =
struct
 module Elem = Element
 module rec BE
  : sig type t = E | H of Elem.t * PrimH.heap
        val eq: t -> t -> bool
        val lt: t -> t -> bool
        val leq: t -> t -> bool
  end = struct
    type t = E | H of Elem.t * PrimH.heap
    let leq (H(x, _)) (H(y, _)) = Elem.leq x y
    let eq (H(x, _)) (H(y, _)) = Elem.eq x y
    let lt (H(x, _)) (H(y, _)) = Elem.lt x y
  end
 and PrimH
  : HEAP with type Elem.t = BE.t
  = MakeH(BE)
 type heap = BE.t
 let empty = BE.E
 let isEmpty = function BE.E -> true | _ -> false
 let rec merge x y =
  match (x,y) with
      (BE.E, _) -> y
    | (_, BE.E) -> x
    | (BE.H(e1,p1) as h1), (BE.H(e2,p2) as h2) ->
        if Elem.leq e1 e2
        then BE.H(e1, PrimH.insert h2 p1)
        else BE.H(e2, PrimH.insert h1 p2)
 let insert x h =
  merge (BE.H(x, PrimH.empty)) h
 let findMin = function
    BE.E -> raise Not_found
  | BE.H(x, _) -> x
 let deleteMin = function
    BE.E -> raise Not_found
  | BE.H(x, p) ->
      if PrimH.isEmpty p then BE.E else begin
        let (BE.H(y, p1)) = PrimH.findMin p in
        let p2 = PrimH.deleteMin p in
        BE.H(y, PrimH.merge p1 p2)
      end
end
@]

Zrób &#263;wiczenie 10.8 z ksi&#261;&#380;ki.
November 21, 2006, at 01:38 AM by 83.27.146.211 -
Changed lines 659-660 from:
* imperatywnie przez iteracj&#281;, przy pomocy tablicy haszuj&#261;cej (modu&#322;
Hashtbl) klucz:s&#322;owo - warto&#347;&#263;:liczba wyst&#261;pie&#324;
to:
* imperatywnie przez iteracj&#281;, przy pomocy tablicy haszuj&#261;cej (modu&#322; Hashtbl) klucz:s&#322;owo - warto&#347;&#263;:liczba wyst&#261;pie&#324;
Changed lines 661-665 from:
* funkcyjnie iteracyjnie (symuluj&#261;c przypadki, gdy wyniki po&#347;rednie
te&#380; s&#261; potrzebne): podobnie jak w stylu imperatywnym ale z modu&#322;em Map
zamiast Hashtbl (zwini&#281;cie listy b&#281;d&#261;cej argumentem funkcji
wyznaczaj&#261;cej histogram)
to:
* funkcyjnie iteracyjnie (symuluj&#261;c przypadki, gdy wyniki po&#347;rednie te&#380; s&#261; potrzebne): podobnie jak w stylu imperatywnym ale z modu&#322;em Map zamiast Hashtbl (zwini&#281;cie listy b&#281;d&#261;cej argumentem funkcji wyznaczaj&#261;cej histogram)
November 21, 2006, at 01:24 AM by 83.27.146.211 -
Changed line 670 from:
[[Attach:pa_lettry.cmo | skompilowany plik z rozszerzeniem sk&#322;adniowym]]
to:
[[Attach:pa_lettry.cmo.zip | skompilowany i zzipowany plik z rozszerzeniem sk&#322;adniowym]]
November 21, 2006, at 01:19 AM by 83.27.146.211 -
Changed lines 13-14 from:
* [[#l7 | lista 7]] programowanie imperatywne ([[#z71 | zad.1]], [[#z72 | zad.2]], [[#z73 | zad.3]], [[#z74 | zad.4]])
to:
* [[#l7 | lista 7]] programowanie imperatywne ([[#z71 | zad.1]], [[#z72 | zad.2]], [[#z73 | zad.3]], [[#z74 | zad.4]], [[#z75 | zad.5]])
Added lines 657-667:
Porównaj eksperymentalnie wydajno&#347;&#263; (faktyczn&#261; z&#322;o&#380;ono&#347;&#263; czasow&#261;)
wyznaczania histogramu (np. zliczania wyst&#261;pie&#324; s&#322;ów):
* imperatywnie przez iteracj&#281;, przy pomocy tablicy haszuj&#261;cej (modu&#322;
Hashtbl) klucz:s&#322;owo - warto&#347;&#263;:liczba wyst&#261;pie&#324;
* funkcyjnie "jednorazowo" np. przez posortowanie i zwini&#281;cie posortowanej listy
* funkcyjnie iteracyjnie (symuluj&#261;c przypadki, gdy wyniki po&#347;rednie
te&#380; s&#261; potrzebne): podobnie jak w stylu imperatywnym ale z modu&#322;em Map
zamiast Hashtbl (zwini&#281;cie listy b&#281;d&#261;cej argumentem funkcji
wyznaczaj&#261;cej histogram)

!!! [[#z75]] Zadanie 5.
Added lines 669-670:

[[Attach:pa_lettry.cmo | skompilowany plik z rozszerzeniem sk&#322;adniowym]]
November 21, 2006, at 01:11 AM by 83.27.146.211 -
Changed lines 13-14 from:
* [[#l7 | lista 7]] programowanie imperatywne ([[#z71 | zad.1]], [[#z72 | zad.2]], [[#z73 | zad.3]])
to:
* [[#l7 | lista 7]] programowanie imperatywne ([[#z71 | zad.1]], [[#z72 | zad.2]], [[#z73 | zad.3]], [[#z74 | zad.4]])
Added lines 655-657:

!!! [[#z74]] Zadanie 4.
Wykorzystuj&#261;c rozszerzenie sk&#322;adniowe [@let try@] (patrz zadanie 4 z listy 5), napisz funkcj&#281;, która pobiera list&#281; nazw plików, i dla plików (w bie&#380;&#261;cym katalogu), których zawarto&#347;&#263; da si&#281; przeczyta&#263; (czyli m. in. istniej&#261;), tworzy ich kopi&#281; (dodaj&#261;c rozszerzenie ".copy") -- kopi&#281; stwórz otwieraj&#261;c nowy plik i zapisuj&#261;c w nim zawarto&#347;&#263; starego. Funkcja ma zwróci&#263; konkatenacj&#281; zawarto&#347;ci wszystkich plików (które da&#322;o si&#281; otworzy&#263;) -- zak&#322;adamy, &#380;e s&#261; to pliki tekstowe z jedn&#261; lini&#261; tekstu. (Je&#347;li który&#347; z plików maj&#261;cych zawiera&#263; kopi&#281; ju&#380; istnieje, funkcja ma przepu&#347;ci&#263; wyj&#261;tek.)
November 16, 2006, at 12:21 AM by 83.27.150.197 -
Changed lines 7-14 from:
* [[#l1 | lista 1]] funkcje wy&#380;szego rz&#281;du i manipulowanie listami
* [[#l2 | lista 2]] jak wy&#380;ej
*
[[#l3 | lista 3]] funkcje jako warto&#347;ci, budowanie funkcji z funkcji
*
[[#l4 | lista 4]] typy algebraiczne (warianty)
* [[#l5 | lista 5]] przerywnikowa
* [[#l6 | lista 6]] leniwe
(korekurencyjne) struktury danych
*
[[#l7 | lista 7]] programowanie imperatywne
to:
* [[#l1 | lista 1]] funkcje wy&#380;szego rz&#281;du i manipulowanie listami ([[#z11 | zad.1]], [[#z12 | zad.2]])
*
[[#l2 | lista 2]] jak wy&#380;ej ([[#z21 | zad.1]], [[#z22 | zad.2]], [[#z23 | zad.3]])
* [[#l3 | lista 3]] funkcje jako warto&#347;ci, budowanie funkcji z funkcji ([[#z31 | zad.1]], [[#z32 | zad.2]])
* [[#l4 | lista 4]] typy algebraiczne (warianty) ([[#z41 | zad.1]], [[#z42 | zad.2]])
* [[#l5 | lista 5]] przerywnikowa ([[#z51 | zad.1]], [[#z52 | zad.2]], [[#z53 | zad.3]], [[#z54 | zad.4]])
* [[#l6 | lista 6]] leniwe (korekurencyjne) struktury danych ([[#z61 | zad.1]], [[#z62 | zad.2]], [[#z63 | zad.3]], [[#z64 | zad.4]])
* [[#l7 | lista 7]] programowanie
imperatywne ([[#z71 | zad.1]], [[#z72 | zad.2]], [[#z73 | zad.3]])
Changed lines 17-18 from:
!!! Zadanie 1.
to:
!!! [[#z11]] Zadanie 1.
Changed lines 21-22 from:
!!! Zadanie 2.
to:
!!! [[#z12]] Zadanie 2.
Changed lines 45-46 from:
!!! Zadanie 1.
to:
!!! [[#z21]] Zadanie 1.
Changed lines 61-62 from:
!!! Zadanie 2.
to:
!!! [[#z22]] Zadanie 2.
Changed line 83 from:
!!! Zadanie 3. Napisz funkcj&#281; licz&#261;c&#261; domkni&#281;cie zwrotne i przechodnie grafu. Graf
to:
!!! [[#z23]] Zadanie 3. Napisz funkcj&#281; licz&#261;c&#261; domkni&#281;cie zwrotne i przechodnie grafu. Graf
Changed lines 111-112 from:
!!! Zadanie 1.
to:
!!! [[#z31]] Zadanie 1.
Changed lines 151-152 from:
!!! Zadanie 2.
to:
!!! [[#z32]] Zadanie 2.
Changed lines 252-253 from:
!!! Zadanie 1.
to:
!!! [[#z41]] Zadanie 1.
Changed lines 275-276 from:
!!! Zadanie 2. (Propozycja projektu.)
to:
!!! [[#z42]] Zadanie 2. (Propozycja projektu.)
Changed line 331 from:
!!! Zadanie 1.
to:
!!! [[#z51]] Zadanie 1.
Changed line 334 from:
!!! Zadanie 2.
to:
!!! [[#z52]] Zadanie 2.
Changed line 342 from:
!!! Zadanie 3.
to:
!!! [[#z53]] Zadanie 3.
Changed line 345 from:
!!! Zadanie 4.
to:
!!! [[#z54]] Zadanie 4.
Changed lines 376-377 from:
!!! Zadanie 1.
to:
!!! [[#z61]] Zadanie 1.
Changed lines 438-439 from:
!!! Zadanie 2.
to:
!!! [[#z62]] Zadanie 2.
Changed line 491 from:
!!! Zadanie 3. (Problem Hamminga)
to:
!!! [[#z63]] Zadanie 3. (Problem Hamminga)
Changed line 545 from:
!!! Zadanie 4. Ci&#261;gi liczbowe.
to:
!!! [[#z64]] Zadanie 4. Ci&#261;gi liczbowe.
Changed line 601 from:
!!! Zadanie 1.
to:
!!! [[#z71]] Zadanie 1.
Changed line 610 from:
!!! Zadanie 2.
to:
!!! [[#z72]] Zadanie 2.
Changed line 624 from:
!!! Zadanie 3.
to:
!!! [[#z73]] Zadanie 3.
November 16, 2006, at 12:05 AM by 83.27.150.197 -
Changed lines 7-14 from:
* [[#l1 | lista 1]]
* [[#l2 | lista 2]]
* [[#l3 | lista 3
]]
* [[#l4 | lista 4]]
* [[#l5 | lista 5]]
* [[#l6 | lista 6]]
*
[[#l7 | lista 7]]
to:
* [[#l1 | lista 1]] funkcje wy&#380;szego rz&#281;du i manipulowanie listami
* [[#l2 | lista 2
]] jak wy&#380;ej
* [[#l3 | lista 3
]] funkcje jako warto&#347;ci, budowanie funkcji z funkcji
*
[[#l4 | lista 4]] typy algebraiczne (warianty)
* [[#l5 | lista 5]] przerywnikowa
* [[#l6 | lista 6]] leniwe (korekurencyjne) struktury danych
* [[#l7 | lista 7]] programowanie imperatywne

Added lines 623-654:

!!! Zadanie 3.
Napisz rozwi&#261;zywaczk&#281; do "gry w 8": gry, w której na prostok&#261;tnej
planszy roz&#322;o&#380;one s&#261; kwadraty ponumerowane kolejnymi liczbami
naturalnymi, ale bez zwi&#261;zku liczby z po&#322;o&#380;eniem kwadratu, a celem
jest sprowadzenie planszy do sytuacji, w której kwadraty umieszczone
s&#261; kolejno, tzn. na prawo od kwadratu z numerem i jest i+1, chyba &#380;e i
jest na prawym brzegu, wtedy i+1 jest pierwszym kwadratem w kolejnym
wierszu. Dopuszczalnymi ruchami s&#261; zamiany przyleg&#322;ych kraw&#281;dzi&#261;
kwadratów, przy czym jeden z zamienianych kwadratów musi mie&#263; numer 0
(tzw. puste pole).

Testuj program dla duuu&#380;ych plansz, stopniuj&#261;c trudno&#347;&#263; ilo&#347;ci&#261; ruchów
zaburzaj&#261;cych: generuj testow&#261; konfiguracj&#281; wyj&#347;ciow&#261; stosuj&#261;c n
przypadkowych ruchów do konfiguracji b&#281;d&#261;cej rozwi&#261;zaniem.

!!!! Wymagania co do programu:

Program ma przechowywa&#263; dok&#322;adnie dwie tablice zawieraj&#261;ce
konfiguracje planszy: jedn&#261; z konfiguracj&#261; wyj&#347;ciow&#261; (pocz&#261;tkow&#261;) i
drug&#261; z konfiguracj&#261; aktualnie rozpatrywan&#261;. Program ma wykorzystywa&#263;
funkcj&#281; heurystyczn&#261;, mierz&#261;c&#261; odleg&#322;o&#347;&#263; aktualnej konfiguracji od
docelowej. Pozosta&#322;e konfiguracje maj&#261; by&#263; pami&#281;tane jako ci&#261;gi
(listy) ruchów sprowadzaj&#261;cych konfiguracj&#281; pocz&#261;tkow&#261; do danej.
Zmiana konfiguracji aktualnej na któr&#261;&#347; z zapami&#281;tanych pozosta&#322;ych ma
by&#263; wykonywana przez wycofanie cz&#281;&#347;ci ruchów aktualnej konfiguracji
(zrobienie ruchów odwrotnych, w odwrotnej kolejno&#347;ci), a&#380; do uzyskania
wspólnego odcinka pocz&#261;tkowego (traktuj&#261;c g&#322;ow&#281; jako koniec listy) z
konfiguracj&#261; zapami&#281;tan&#261;, i nast&#281;pnie wykonanie brakuj&#261;cych ruchów
konfiguracji zapami&#281;tanej. Do znalezienia wspólnego odcinka
pocz&#261;tkowego wykorzystaj test równo&#347;ci fizycznej (==) (zapewnij
wspó&#322;dzielenie).
November 15, 2006, at 09:42 PM by 83.27.150.197 -
Added lines 545-598:
!!! Zadanie 4. Ci&#261;gi liczbowe.
U&#380;yjemy por&#281;cznego typu do reprezentacji ci&#261;gów.

[@
type 'a sequence =
    (* constant sequence: Cs h ~= [h; h; h; ...] *)
 | Cs of 'a
    (* generic sequence: S (x, xs) ~= x::xs *)
 | S of 'a * 'a sequence lazy_t
    (* differential sequence: for ds ~= [d0; d1; d2; ...], A(x0, ds) ~= [x0;
        x0+d0; x0+d0+d1; x0+d0+d1+d2; ...] *)
 | A of 'a * 'a sequence lazy_t
    (* generalized geometric progression: for ds ~= [d0; d1; d2; ...],
        G(x0,ds) ~= [x0; x0*d0; x0*d0*d1; x0*d0*d1*d2; ...] *)
 | G of 'a * 'a sequence lazy_t
;;
@]

Napisz funkcje:

* @@neg@@ zmieniaj&#261;c&#261; znak ka&#380;dego wyrazu ci&#261;gu na przeciwny: [@neg [x0; x1; x2; ...] = [-x0; -x1; -x2; ...]@]
* @@head@@, @@tail@@ zwracaj&#261;ce pierwszy element oraz ci&#261;g pocz&#261;wszy od drugiego elementu
* @@x_to_S@@ konwertuj&#261;c&#261; ci&#261;g do postaci ogólnej: [@x_to_S xs = S (x0, S(x1, S (x2, ...)))@] (u&#380;ywaj tej funkcji w kolejnych definicjach tylko w razie konieczno&#347;ci! np. w definicji map i map2)
* dodawanie po osiach, mno&#380;enie przez sta&#322;&#261;, mno&#380;enie po osiach
* sumy cz&#281;&#347;ciowe: n-tym wyrazem sumy cz&#281;&#347;ciowej [@sums [x0; x1; x2; ...]@] jest [@x0+x1+x2+...+xn@]

Czemu s&#261; równe: [@exp (A x r)@], [@sqrt (G x q)@], [@log (G x q)@], [@n!@]?

Zakoduj algorytm Rungego-Kutty drugiego rz&#281;du iteracyjnego
rozwi&#261;zywania równania [@y' = f (y, t), y(t0)=y0@], zazwyczaj
prezentowany tak:

 k'_1_' = h * f(y'_n_'; t'_n_')
 k'_2_' = h * f(y'_n_' + k'_1_'/2; t'_n_' + h/2)
 y'_n+1_' = y'_n_' + k'_2_'

zastosuj "podniesienie" funkcji @@f@@ z liczb na ci&#261;gi, [@(map2 f s1 s2)@].

Zakoduj algorytm Lentza obliczania u&#322;amków &#322;a&#324;cuchowych:

 f = b'_0_' + a'_1_' / (b'_1_' + a'_2_' / (b'_2_' + a'_3_' / (b'_3_' + ...)))

o nast&#281;puj&#261;cej specyfikacji imperatywnej:

 Set f'_0_' = b'_0_'; C'_0_' = f'_0_'; D'_0_' = 0;
 for j = 1; 2; ...
 Set D'_j_' = 1/(b'_j_' + a'_j_'*D'_j-1_')
 Set C'_j_' = b'_j_' + a'_j_'/C'_j-1_'
 Set f'_j_' = f'_j-1_'(C'_j_'*D'_j_')
 Stop gdy C'_j_'*D'_j_' prawie równe 1.

Oblicz przy jego pomocy e'^z^' = 1 + (z / (1 - z / (2 + z / (3 - ...)))) dla z=1 (i [@ 'a = float @]).

Changed lines 13-14 from:
to:
* [[#l7 | lista 7]]
Changed lines 543-568 from:
@]
to:
@]

!! [[#l7]] Lista 7.

!!! Zadanie 1.
Napisz wersje imperatywn&#261; i czysto funkcyjn&#261; procedury generuj&#261;cej
losow&#261; permutacj&#281; ci&#261;gu. Procedur&#281; zaimplementuj jako funkcj&#281;
pobieraj&#261;c&#261; strumie&#324; liczb ca&#322;kowitych (domy&#347;lnie liczb losowych z
przedzia&#322;u 0..M dla du&#380;ego M) oraz, w przypadku imperatywnym tablic&#281;,
a w przypadku funkcyjnym list&#281;. Postaraj si&#281; uzyska&#263; poprawne (&#380;adna
permutacja nie powinna by&#263; faworyzowana) i wydajne implementacje.
Porównaj wydajno&#347;&#263; wersji imperatywnej i funkcyjnej.

!!! Zadanie 2.
!!!! a)
Zapoznaj si&#281; z poj&#281;ciem leksykalnego vs. dynamicznego zakresu wi&#261;za&#324;
(zmiennych), na przyk&#322;ad z 1. i 2. rozdzia&#322;u artyku&#322;u "A Syntactic Theory of Dynamic Binding" Luc Moreau
[[http://www.ecs.soton.ac.uk/~lavm/papers/tapsoft97.ps.gz]]
Zastanów si&#281; nad podobie&#324;stwami i ró&#380;nicami "dynamicznie
zakresowanych" zmiennych i referencji.
!!!! b*)
Zaimplementuj wznawialne wyj&#261;tki: mechanizm, w którym fragment
programu obs&#322;uguj&#261;cy wyj&#261;tek mo&#380;e przekaza&#263; fragmentowi zg&#322;aszaj&#261;cemu
wyj&#261;tek informacj&#281; potrzebn&#261; do kontynuowania oblicze&#324; (da si&#281; to
zrobi&#263; w OCamlu, bez tzw. kontynuacji). (Zadanie to rozwi&#261;za&#322; Oleg
Kiselyov).
November 12, 2006, at 06:37 AM by 83.27.168.133 -
Added lines 489-542:

!!! Zadanie 3. (Problem Hamminga)
Wygeneruj n pierwszych liczb w postaci 2'^a'_1_'^'3'^a'_2_'^'5'^a'_3_'^'...p'_k_''^a'_k_'^', tzn.
nie dziel&#261;cych si&#281; przez liczby pierwsze wi&#281;ksze od k-tej liczby
pierwszej, dla danego k.

Idea rozwi&#261;zania polega na generowaniu listy liczb tej postaci. Aby
wygenerowa&#263; kolejn&#261; liczb&#281;, znajdujemy najmniejsz&#261; ju&#380; wygenerowan&#261;
liczb&#281; x'_1_' tak&#261;, &#380;e 2x'_1_' jest wi&#281;ksza od ostatniego elementu ju&#380;
wygenerowanej listy, tak samo dla x'_2_' i 3x'_2_', etc. Do listy dodajemy
minimum z 2x'_1_', 3x'_2_', ..., p'_k_'x'_k_'.

Rozwi&#261;&#380; zadanie buduj&#261;c list&#281; leniw&#261; (na bazie modu&#322;u @@Lazy@@),
zawieraj&#261;c&#261; kolejne liczby zadanej postaci: uzupe&#322;nij brakuj&#261;c&#261;
linijk&#281; kodu:

[@
type 'a llist = LNil | LCons of 'a * 'a llist lazy_t;;
let rec ltake n = function
 | LCons (a, ll) when n > 0 -> a::(ltake (n-1) (Lazy.force ll))
 | _ -> []
;;
let rec lfrom n = LCons (n, lazy (lfrom (n+1)));;
let rec lfilter f = function
 | LNil -> LNil
 | LCons (n, ll) ->
    if f n then LCons (n, lazy (lfilter f (Lazy.force ll)))
    else lfilter f (Lazy.force ll)
;;
let primes =
 let rec sieve = function
    LCons(p,nf) -> LCons(p, lazy (sieve (sift p (Lazy.force nf))))
  | LNil -> failwith "Impossible! Internal error."
 and sift p = lfilter (function n -> n mod p <> 0)
in sieve (lfrom 2)
;;

let times ll n = lmap (fun i -> i * n) ll;;

let rec merge xs ys = match xs, ys with
 | LCons (x, xr), LCons (y, yr) ->
    if x < y then LCons (x, lazy (merge (Lazy.force xr) ys))
    else if x > y then LCons (y, lazy (merge xs (Lazy.force yr)))
    else LCons (x, lazy (merge (Lazy.force xr) (Lazy.force yr)))
 | r, LNil | LNil, r -> r
;;

let hamming k =
 let pr = ltake k primes in
 let rec h = LCons (1, lazy (
  <TODO> )) in
 h
;;
@]
Changed lines 5-8 from:
! lista 1

!!
Zadanie 1.
to:
!! [[#contents]] Listy:

* [[#l1 | lista 1]]
* [[#l2 | lista 2]]
* [[#l3 | lista 3]]
* [[#l4 | lista 4]]
* [[#l5 | lista 5]]
* [[#l6 | lista 6]]

!! [[#l1]] Lista 1

!
!! Zadanie 1.
Changed lines 20-21 from:
!! Zadanie 2.
to:
!!! Zadanie 2.
Changed lines 28-29 from:
!!! Dodatkowe wskazówki do zadania [@map_reduce@] z "listy 1":
to:
!!!! Dodatkowe wskazówki do zadania [@map_reduce@] z "listy 1":
Changed lines 42-45 from:
! lista 2

!! Zadanie 1.
to:
!! [[#l2]] Lista 2

!!! Zadanie 1.
Changed lines 60-61 from:
!! Zadanie 2.
to:
!!! Zadanie 2.
Changed line 82 from:
!! Zadanie 3. Napisz funkcj&#281; licz&#261;c&#261; domkni&#281;cie zwrotne i przechodnie grafu. Graf
to:
!!! Zadanie 3. Napisz funkcj&#281; licz&#261;c&#261; domkni&#281;cie zwrotne i przechodnie grafu. Graf
Changed lines 87-88 from:
!!! Instalacja rozszerzenia sk&#322;adniowego:
to:
!!!! Instalacja rozszerzenia sk&#322;adniowego:
Changed lines 108-111 from:
! Lista 3.

!! Zadanie 1.
to:
!! [[#l3]] Lista 3.

!!! Zadanie 1.
Changed lines 150-151 from:
!! Zadanie 2.
to:
!!! Zadanie 2.
Changed lines 225-226 from:
!!! Dalsze uwagi.
to:
!!!! Dalsze uwagi.
Changed lines 249-252 from:
! Lista 4

!!Zadanie 1.
to:
!! [[#l4]] Lista 4

!!! Zadanie 1.
Changed lines 274-275 from:
!! Zadanie 2. (Propozycja projektu.)
to:
!!! Zadanie 2. (Propozycja projektu.)
Changed lines 328-330 from:
! Lista 5

!! Zadanie 1.
to:
!! [[#l5]] Lista 5

!!! Zadanie 1.
Changed line 333 from:
!! Zadanie 2.
to:
!!! Zadanie 2.
Changed line 341 from:
!! Zadanie 3.
to:
!!! Zadanie 3.
Changed line 344 from:
!! Zadanie 4.
to:
!!! Zadanie 4.
Changed lines 373-376 from:
! Lista 6.

!! Zadanie 1.
to:
!! [[#l6]] Lista 6.

!!! Zadanie 1.
Changed lines 437-438 from:
!! Zadanie 2.
to:
!!! Zadanie 2.
Changed lines 428-429 from:
Zadanie 2.
to:
!! Zadanie 2.
Added lines 363-478:

! Lista 6.

!! Zadanie 1.

Porównaj nast&#281;puj&#261;ce dwie implementacje list leniwych:

[@
(* implementation by function closures *)

type 'a lflist = LFNil | LFCons of 'a * (unit -> 'a lflist);;

let rec lfzip = function
 | LFNil, LFNil -> LFNil
 | LFCons (a1, lf1), LFCons (a2, lf2) ->
    LFCons ((a1, a2), fun () -> lfzip (lf1 (), lf2 ()))
 | _ -> raise (Invalid_argument "lfzip")
;;
let rec lfmap f = function
 | LFNil -> LFNil
 | LFCons (a, lf) -> LFCons (f a, fun () -> lfmap f (lf ()))
;;
let rec lffib = LFCons (1, fun () -> lfmap (fun (a,b)-> a+b) (lfzip
 (lffib, LFCons (1, fun () -> lffib))))
;;
let rec lftake n = function
 | LFCons (a, lf) when n > 0 -> a::(lftake (n-1) (lf ()))
 | _ -> []
;;

(* implementation by native lazy values *)

type 'a llist = LNil | LCons of 'a * 'a llist lazy_t;;

let rec lzip = function
 | LNil, LNil -> LNil
 | LCons (a1, ll1), LCons (a2, ll2) ->
    LCons ((a1, a2), lazy (lzip (Lazy.force ll1, Lazy.force ll2)))
 | _ -> raise (Invalid_argument "lzip")
;;
let rec lmap f = function
 | LNil -> LNil
 | LCons (a, ll) -> LCons (f a, lazy (lmap f (Lazy.force ll)))
;;
let rec lfib = LCons (1, lazy (lmap (fun (a,b)-> a+b) (lzip
 (lfib, LCons (1, lazy lfib)))))
;;
let rec ltake n = function
 | LCons (a, ll) when n > 0 -> a::(ltake (n-1) (Lazy.force ll))
 | _ -> []
;;
@]

Wyt&#322;umacz ró&#380;nic&#281; w z&#322;o&#380;ono&#347;ci pomi&#281;dzy obliczeniem

[@
lftake 17 lffib;;
@]

a

[@
ltake 17 lfib;;
@]

Zadanie 2.
Zaimplementuj "czysto funkcyjny" mechanizm memoizacji funkcji
pierwotnie rekurencyjnych (primitive recursive) na liczbach
naturalnych, tzn. funkcji które dla obliczenia argumentu @@n@@ potrzebuj&#261;
(co najwy&#380;ej) warto&#347;ci dla argumentów mniejszych od @@n@@.
Funkcje pierwotnie rekurencyjne reprezentuj przy pomocy
nierekurencyjnych funkcji wy&#380;szego rz&#281;du o typie:

[@
(int -> int) -> int -> int
@]

gdzie pierwszy argument ma oznacza&#263; t&#281; sam&#261; funkcj&#281;, np.

[@
let fib f n = if n < 2 then 1 else f (n-1) + f (n-2);;
@]

Napisz funkcj&#281; @@memoize@@ tak&#261;, &#380;e np.

[@
let fib_memo = memoize fib;;
- : int -> int = <fun>
@]

b&#281;dzie wydajn&#261; wersj&#261; funkcji Fibonacciego.
W implementacji wykorzystaj leniwe drzewa binarne jak w zadaniu 4 do
wyk&#322;adu 5, ale oparte o natywne warto&#347;ci leniwe:

[@
type 'a lBT = LEmpty
 | LNode of 'a * 'a lBT lazy_t * 'a lBT lazy_t;;
@]

(na podstawie zadania 1. wyt&#322;umacz, dlaczego ta modyfikacja jest
istotna). Napisz funkcj&#281; @@map_lBT@@ która leniwie mapuje drzewo @@lBT@@
(podobnie do powy&#380;szej funkcji @@lmap@@ dla list leniwych). Napisz funkcj&#281;
@@itr@@ tak&#261;, jak w zadaniu 4 (a) z wyk&#322;adu 5: która dla zadanej liczby
ca&#322;kowitej @@n@@ konstruuje niesko&#324;czone leniwe drzewo binarne z korzeniem
o etykiecie @@n@@ i z dwoma poddrzewami [@itr(2*n)@] i [@itr(2*n+1)@]. Napisz
funkcj&#281; @@nth_node@@, która dla danego drzewa i liczby @@n@@ zwraca etykiet&#281;
wierzcho&#322;ka, który w drzewie zwróconym przez @@itr@@ mia&#322;by numer @@n@@.
Wykorzystaj te trzy funkcje do napisania @@memoize@@. Drzewo buduj
pocz&#261;wszy od wierzcho&#322;ka 1, traktuj&#261;c 0 jako szczególny przypadek:

[@
f (fun _ -> raise Not_found) 0
@]

Jaka jest zaleta tej metody memoizacji w porównaniu z metod&#261;
"wype&#322;niania tablicy"?
November 07, 2006, at 01:12 PM by 83.27.155.114 -
Added lines 319-362:
! Lista 5

!! Zadanie 1.
Napisz funkcj&#281; dokonuj&#261;c&#261; transpozycji macierzy reprezentowanych jako listy list.

!! Zadanie 2.
Zbuduj dowolne drzewo rozpinaj&#261;ce dla grafu danego jako lista par wierzcho&#322;ek, lista wierzcho&#322;ków przyleg&#322;ych. Zapami&#281;taj równie&#380; pozosta&#322;e wierzcho&#322;ki wychodz&#261;ce z danego w&#281;z&#322;a.
U&#380;yj typu:

[@
type 'a span_tree = Node of 'a * 'a span_tree list * 'a list
@]

!! Zadanie 3.
Dzielimy wierzcho&#322;ki drzewa na lekkie i ci&#281;&#380;kie jak nast&#281;puje: korze&#324; jest lekki, wszyscy synowie, którzy rozpinaj&#261; poddrzewa o najwi&#281;kszym rozmiarze spo&#347;ród poddrzew rodze&#324;stwa, s&#261; ci&#281;&#380;cy, pozosta&#322;e wierzcho&#322;ki s&#261; lekkie. (Innymi s&#322;owy, dla ka&#380;dego wierzcho&#322;ka wewn&#281;trznego oznaczamy tego syna, w którym podczepione jest najwi&#281;ksze poddrzewo, jako ci&#281;&#380;kiego.) Oznaczamy kraw&#281;dzie prowadz&#261;ce do lekkich synów jako lekkie, a prowadz&#261;ce do ci&#281;&#380;kich synów jako ci&#281;&#380;kie. Lekk&#261; g&#322;&#281;boko&#347;ci&#261; wierzcho&#322;ka v nazywamy ilo&#347;&#263; lekkich kraw&#281;dzi na &#347;cie&#380;ce od v do korzenia. Lekk&#261; g&#322;&#281;boko&#347;ci&#261; drzewa nazywamy maksimum z lekkich g&#322;&#281;boko&#347;ci jego wierzcho&#322;ków. Napisz funkcj&#281; obliczaj&#261;c&#261; lekk&#261; g&#322;&#281;boko&#347;&#263; drzewa.

!! Zadanie 4.
W Pythonie mechanizm wyj&#261;tków pozwala zdefiniowa&#263; klauzul&#281; "else":

[@
try:
  GUARDED
except EXC1:
  HANDLER1
...
except EXCn:
  HANDLERn
else:
  CLOSING
@]

Fragment @@CLOSING@@ jest obliczany tylko, je&#347;li nie nast&#261;pi&#322; &#380;aden wyj&#261;tek. W OCamlu bardzo przyda&#322;by si&#281; nast&#281;puj&#261;cy wariant tej konstrukcji:

[@
let try X = GUARDED
in BODY
with EXC1 -> HANDLER1 | ... | EXCn -> HANDLERn
@]

w którym  nazwa @@X@@ jest zwi&#261;zana z warto&#347;ci&#261; @@GUARDED@@ w wyra&#380;eniu @@BODY@@. O ile obliczanie @@GUARDED@@ nie spowodowa&#322;o wyj&#261;tku, wynikiem ca&#322;ego wyra&#380;enia jest warto&#347;&#263; @@BODY@@. Je&#347;li obliczenie @@GUARDED@@ podnios&#322;o wyj&#261;tek @@EXCi@@, wynikiem ca&#322;ego wyra&#380;enia jest warto&#347;&#263; @@HANDLERi@@. Wyj&#261;tki podnoszone przez @@BODY@@ nie s&#261; przechwytywane!

a) Przet&#322;umacz konstrukcj&#281; [@let try@] na standardowe konstrukcje OCamla, co pozwoli doda&#263; j&#261; jako rozszerzenie sk&#322;adniowe (rzeczywi&#347;cie takie rozszerzenie jest dost&#281;pne).

b) Czy w twoim t&#322;umaczeniu pozycja @@BODY@@ jest ogonowo-rekurencyjna (tail-recursive)? Je&#347;li nie jeste&#347; pewien, sprawd&#378; to eksperymentalnie.
November 06, 2006, at 10:38 PM by 83.27.155.114 -
Changed lines 106-110 from:
- @@lit@@ dla litera&#322;ów (sta&#322;ych stringów)
- @@eol@@ dla wstawiania ko&#324;ca linii
- @@int@@ dla wstawiania liczb ca&#322;k. (odpow. "%i")
- @@str@@ dla wstawiania stringów (odpow. "%s")
- @@lis@@ dla wstawiania list elementów.
to:
* @@lit@@ dla litera&#322;ów (sta&#322;ych stringów)
* @@eol@@ dla wstawiania ko&#324;ca linii
* @@int@@ dla wstawiania liczb ca&#322;k. (odpow. "%i")
* @@str@@ dla wstawiania stringów (odpow. "%s")
* @@lis@@ dla wstawiania list elementów.
November 06, 2006, at 09:06 PM by 83.27.155.114 -
Changed lines 1-318 from:
[[Attach:funind.ml]]
to:
Zadania na &#263;wiczenia b&#281;d&#261; si&#281; sk&#322;ada&#263; z: zada&#324; z wyk&#322;adów, zada&#324;,
które b&#281;d&#281; podawa&#322; bezpo&#347;rednio na &#263;wiczeniach, i zada&#324;, które b&#281;d&#281;
wysy&#322;a&#322; i/lub zamieszcza&#322; na stronie.

! lista 1

!! Zadanie 1.

Napisz funkcj&#281; sortuj&#261;c&#261; listy "mergesort" lub "quicksort".

!! Zadanie 2.

Napisz funkcj&#281; wy&#380;szego rz&#281;du "map_reduce" wzorowan&#261; na

http://labs.google.com/papers/mapreduce.html

wraz z przyk&#322;adowym (testowym) zastosowaniem. (Zauwa&#380;, &#380;e "reduce = fold".)

!!! Dodatkowe wskazówki do zadania [@map_reduce@] z "listy 1":

Napisz funkcj&#281;

[@
let map_reduce fmap freduce v0 xs = ...
@]

obliczaj&#261;c&#261; list&#281; par klucz-warto&#347;&#263; przez "List.map fmap xs",
grupuj&#261;c&#261; warto&#347;ci o tym samym kluczu w listy "intermediate", oraz
zwracaj&#261;ce list&#281; par klucz-nowa warto&#347;&#263;, gdzie nowa warto&#347;&#263; =
[@List.fold_left freduce v0 intermediate@].


! lista 2

!! Zadanie 1.

Wykorzystaj rozszerzenie sk&#322;adniowe "list comprehension":

http://cl-informatik.uibk.ac.at/teaching/ss06/ocaml/content/listcompr.ml

Trójk&#261;t o bokach a, b, c ma pole A dane wzorem:

[@
s = (a+b+c)/2
A = sqrt(s*(s-a)*(s-b)*(s-c))
@]

Znajd&#378; wszystkie trójk&#261;ty o bokach d&#322;ugo&#347;ci b&#281;d&#261;cej liczb&#261; ca&#322;kowit&#261;
nie wi&#281;ksz&#261; od n, których pole te&#380; jest ca&#322;kowitoliczbowe.

!! Zadanie 2.

Napisz funkcj&#281; @@until@@ realizuj&#261;c&#261; iteracj&#281;:
[@until termCheck iter init@] oblicza [@iter^n(init)@] t. &#380;e [@termCheck (iter^n(init)) = true@]
oraz [@termCheck (iter^i(init)) = false@] dla [@1 <= i < n@].

Wykorzystaj t&#281; funkcj&#281; do znajdywania miejsc zerowych. Napisz
odpowiednie funkcje: @@termCheck@@, @@iterMethod@@, @@initApprox@@, @@report@@, takie,
&#380;e funkcja:

[@
findRoot f = report (until termCheck (iterMethod f) (initApprox f))
@]

zwraca miejsce zerowe funkcji @@f@@ (funkcja @@report@@ ma wydobywa&#263;
rozwi&#261;zanie ze stanu oblicze&#324;, który mo&#380;e przechowywa&#263; dodatkowe
informacje). Zaimplementuj dwa rozwi&#261;zania, np. wykorzystuj&#261;ce metod&#281;
bisekcji i metod&#281; Newtona. Przetestuj je na kilku przyk&#322;adach.

O funkcji @@f@@ której pierwiastki b&#281;dziesz oblicza&#263; mo&#380;esz poczyni&#263;
upraszczaj&#261;ce za&#322;o&#380;enia, np. &#380;e jest rosn&#261;ca.

!! Zadanie 3. Napisz funkcj&#281; licz&#261;c&#261; domkni&#281;cie zwrotne i przechodnie grafu. Graf
dany jest jako lista przyleg&#322;o&#347;ci: lista par wierzcho&#322;ek, lista jego
dzieci. (Mo&#380;esz wykorzysta&#263; "list comprehension i funkcj&#281;
[@fixpoint = (until equals)@] dla odpowiednio zdefiniowanej @@equals@@.)

!!! Instalacja rozszerzenia sk&#322;adniowego:

zgodnie z komentarzem w pliku &#378;ród&#322;owym:

[@
 The syntax extension for list comprehension.

  HOW TO COMPILE
  $ ocamlc -c -I +camlp4 -pp "camlp4o q_MLast.cmo pa_extend.cmo -loc loc" listcompr.ml

  HOW TO USE
  # #load "camlp4o.cma";;
  # #load "listcompr.cmo";;
  # [ x + y | x <- [1;2;3] when x > 1; y <- [4;5;6] ];;

  The original code was posted by Anton Moscal to caml-list:

    Date: 2000-01-21 (08:43)
    Subject: Re: Q: camlp4 use?
@]

! Lista 3.

!! Zadanie 1.

Napisz bezpieczny typowo odpowiednik funckji @@sprintf@@ z C (albo
"nieoszukany" wariant funkcji [@Printf.sprintf@]) w nast&#281;puj&#261;cy sposób.
Napisz funkcje b&#281;d&#261;ce "dyrektywami wzorców":
- @@lit@@ dla litera&#322;ów (sta&#322;ych stringów)
- @@eol@@ dla wstawiania ko&#324;ca linii
- @@int@@ dla wstawiania liczb ca&#322;k. (odpow. "%i")
- @@str@@ dla wstawiania stringów (odpow. "%s")
- @@lis@@ dla wstawiania list elementów.
Napisz funkcj&#281; "format", która jako argument pobiera wzorzec zbudowany
z dyrektyw wzorców.
Niech @@$$@@ b&#281;dzie infiks-owym operatorem z&#322;o&#380;enia funkcji
zdefiniowanym na wyk&#322;adzie. Wtedy przyk&#322;adowo wywo&#322;anie:

[@
let fs = format (lit "Napis " $$ str $$ lit " oraz lista list liczb "
  $$ lis (lis int) $$ eol)
@]

ma zdefiniowa&#263; funkcj&#281; o typie:

[@
string -> int list list -> string
@]

i zastosowanie

[@
fs "graf" [[1; 2]; [1]; []]
@]

zwróci string:

[@
"Napis graf oraz lista list liczb [[1, 2], [1], []]\n"
@]

(lub ze &#347;rednikami zamiast przecinków).

!! Zadanie 2.

Na którym&#347; z kolejnych wyk&#322;adów zostanie wprowadzone poj&#281;cie listy
leniwej. My teraz zdefiniujemy szczególny przypadek listy leniwej,
strumie&#324; (niesko&#324;czon&#261; list&#281; leniw&#261;). Strumie&#324; to procedura,
zwracaj&#261;ca kolejny element ze strumienia i reszt&#281; (ogon) strumienia.
Aby to "naiwne" podej&#347;cie zadzia&#322;a&#322;o, musimy przekaza&#263; OCamlowi
parametr -rectypes, uruchamiaj&#261;c go komend&#261; @@ocaml -rectypes@@.

[@
type 'a stream = unit -> 'a * 'a stream
@]

Strumie&#324; liczb naturalnych:

[@
let nats = let rec aux i () = i, aux (i+1) in aux 0
@]

Podgl&#261;danie strumienia:

[@
let rec take n s =
 if n <= 0 then [] else let hd, tl = s () in hd :: (take (n-1) tl)
@]

Napisz funkcje do manipulacji szeregami pot&#281;gowymi zaimplementowanymi
jako strumienie. Zadeklaruj dla nich odpowiednie operatory infiksowe,
np. [@~-$, +$, -$, *.$, *$, /$, ...@] &#379;eby podkre&#347;li&#263; dok&#322;adny charakter
oblicze&#324;, wykorzystaj liczby wymierne num z biblioteki Num.
(Potrzebujemy j&#261; "zlinkowa&#263;", np. w trybie interaktywnym komend&#261;
[@#load "nums.cma";;@].)

[@
let display n s = String.concat " + "
 (List.map2 (fun i v -> (Num.string_of_num v)^"x^"^(string_of_int i))
  (take n nats) (take n s))
@]

Napisz funkcje:
- szereg pot&#281;gowy sta&#322;ej
- negacj&#281; szeregu pot&#281;gowego
- dodawanie szeregów pot&#281;gowych
- mno&#380;enie szeregu przez sta&#322;&#261;
- mno&#380;enie szeregów
- dzielenie szeregów (wzór wyprowad&#378; rozwijaj&#261;c równanie F = Q * G, by
wyznaczy&#263; q i Q1 dla Q = q + x*Q1)
- z&#322;o&#380;enie szeregów (F . G) (x) = F (G (x))
- pochodn&#261; szeregu
- trudniejsze: odwrotno&#347;&#263; funkcyjn&#261; szeregu, tzn. R w równaniu F(R(x)) = x
- ca&#322;k&#281; szeregu i szeregi dla funkcji exp, sin, cos, sqrt -
trudniejszy, wyznaczone z odpowiednich równa&#324; ró&#380;niczkowych:

Np. z równania na exp: "dy/dx = y, y(0) = 1" dostajemy

[@
exp = 1 + (integral exp)
@]

co w naszej implementacji zapisuje si&#281; jako:

[@
let ni = Num.num_of_int
let rec exp () =
 let h,t = integral exp () in h +/ ni 1, t
@]

Wyt&#322;umacz, dlaczego przy alternatywnej definicji:

[@
let rec exp' () = (cst 1 +$ integral exp') ()
@]

wywo&#322;anie [@exp' ()@] si&#281; zap&#281;tla.

!!! Dalsze uwagi.

Wprowad&#378; nazw&#281; na typ szeregów:

[@
type 'a stream = unit -> 'a * 'a stream;;
type series = Num.num stream;;
@]

oraz wprowad&#378; annotacje typami w programie tak, aby typy zwracane
przez toplevel odnosi&#322;y si&#281; do typów szeregów tylko przez nazw&#281;
"series". Kiedy wyra&#380;enia z szeregami s&#261; na tyle "wysokiego poziomu",
&#380;e system rozpoznaje, &#380;e chodzi nam o "series", bez dodatkowych
annotacji z naszej strony?

Annotacja typem to wyra&#380;enie lub wzorzec [@(expr : typ)@], którego typem jest
@@typ@@, o ile @@typ@@ jest szczególnym przypadkiem najogólniejszego typu
jaki ma @@expr@@.

Zapisz funkcj&#281; mno&#380;&#261;c&#261; szeregi prostym wzorem rekurencyjnym (wyprowad&#378;
go z równo&#347;ci F*G = (f + xF1)*(g+xG1)), bez wyznaczania "za ka&#380;dym
razem" odcinka pocz&#261;tkowego.


! Lista 4

!!Zadanie 1.

Programuj&#261;c czysto funkcyjnie nie mamy mo&#380;liwo&#347;ci bezpo&#347;redniego
modyfikowania struktur danych. Oznacza to, &#380;e przekszta&#322;caj&#261;c
struktury, musimy dokonywa&#263; ich kopiowania. Okazuje si&#281;, &#380;e dzi&#281;ki
wspó&#322;dzieleniu wspólnych cz&#281;&#347;ci, w przypadku modyfikacji w&#281;z&#322;a drzewa
wystarczy skopiowa&#263; &#347;cie&#380;k&#281; od korzenia do modyfikowanego wierzcho&#322;ka
(jak w funkcji pomocniczej "insert2bst" z wyk&#322;adu).
Jednak je&#347;li dokonujemy na strukturze bardzo cz&#281;stych zmian, jak np. w
edytorze, woleliby&#347;my unikn&#261;&#263; kopiowania zupe&#322;nie. Wyobra&#378;my sobie
edytor strukturalny, np. edytor drzewa XML. W takim edytorze
modyfikujemy drzewo tylko lokalnie, w pozycji kursora. Ograniczmy
ruchy kursora do przemieszczania do s&#261;siaduj&#261;cych w&#281;z&#322;ów. Wtedy udaje
si&#281; wykona&#263; ka&#380;d&#261; operacj&#281; (modyfikacj&#281; i przemieszczanie kursora) w
sta&#322;ym czasie, dzi&#281;ki strukturze, któr&#261; Gerard Huet nazwa&#322; "Zipper":

[[Attach:zipper.pdf]]

Doko&#324;cz artyku&#322; Gerarda Hueta: napisz brakuj&#261;ce funkcje manipulacji
"zipperami" z memoizacj&#261; (punkt 3.1).

[[Attach:zippers.ml]]

!! Zadanie 2. (Propozycja projektu.)

Typy algebraiczne (czyli warianty, sumy roz&#322;&#261;czne produktów typów
algebraicznych) daj&#261; bardzo wygodny sposób reprezentacji danych
strukturalnych. Podejmiemy ambitne zadanie z maszynowego uczenia si&#281;:
indukcj&#281; funkcji, czyli b&#281;dziemy konstruowa&#263; jak najoszcz&#281;dniejsz&#261;
funkcj&#281;, która dla zadanych danych wej&#347;ciowych wygeneruje zadane dane
wyj&#347;ciowe. Zapoznaj si&#281; z artyku&#322;em Markusa Mottla "Using Algebraic
Datatypes as Uniform Representation for Structured Data":

http://ocaml.info/oefai/papers/algebraic_dts/index.html,

w szczególno&#347;ci z rozdzia&#322;em "Generalizing Decision Tree Learning to
Algebraic Datatypes":

http://ocaml.info/oefai/papers/algebraic_dts/algebraic_dts003.html

i doko&#324;cz moj&#261; prototypow&#261; implementacj&#281; [[(Attach:)funind.ml]]
(bezpo&#347;rednio opart&#261; na wspomnianym rozdziale z pracy Markusa Mottla) (konstruktywna krytyka
mile widziana :-)).

Zadania:

a) Napisz test-zastosowanie (odpowiednik akapitu [@(* *** example *** *)@]
z pliku &#378;ród&#322;owego).

b) Przyjrzyj si&#281;, czy formu&#322;y matematyczne (wzory na entropi&#281;)
zgadzaj&#261; si&#281; z odpowiednimi funkcjami OCamla.

Bardziej czasoch&#322;onne zadania:

c) Wprowad&#378; obs&#322;ug&#281; sytuacji, gdy dane nie opisuj&#261; funkcji (tzn. gdy
tym samym argumentom przypisane s&#261; ró&#380;ne wyniki -- obecnie program
wysypuje si&#281; wtedy). Dopisz obs&#322;ug&#281; ga&#322;&#281;zi domy&#347;lnych " _ -> ". Patrz:
paragraf 3.3 artyku&#322;u.

d) Dopisz normalizacj&#281; "lewej strony" (patrz paragraf 3.1.2 artyku&#322;u).

Dalsze propozycje:

e) Rozszerz algorytm o obs&#322;ug&#281; zmiennych liczbowych (zapoznaj si&#281; z
odpowiednimi mechanizmami budowy drzew decyzyjnych).

f) Mo&#380;esz zmierzy&#263; si&#281; z problemem indukcji funkcji rekurencyjnych.

g) Zbuduj system automatycznie kompiluj&#261;cy i wykorzystuj&#261;cy
wygenerowane funkcje. Przyk&#322;adowe mo&#380;liwo&#347;ci to wykorzystanie modu&#322;ów
trybu interaktywnego budowanych w czasie kompilacji OCamla, albo
wykorzystanie MetaOCamla.

h) Zaimplementuj zastosowanie programu, np. w systemie eksperckim.

[[Attach:funind.ml]]

November 06, 2006, at 03:17 PM by 83.27.155.114 -
Added line 1:
[[Attach:funind.ml]]
Edit · History · Print · Recent Changes · Search · Links
Page last modified on June 07, 2011, at 03:48 PM