% === 12.1 === oOA([],[]). % intuitivne: pokial je prvy argument instanciovany, tak pre aspon jednoprvkovy % zoznam tvaru [H|T] zmazeme vsetky vyskyty H v zozname T, cim dostaneme X; % nasledne volame oOA rekurzivne na X; k vysledku S, ktory dostaneme, pripojime % na zaciatok H a to nam da [H|S] ako vyslednu hodnotu pre druhy argument oOA([H|T],[H|S]) :- delete(T,H,X), oOA(X,S). % ... oOA maze zo zoznamu duplikaty a zachova vzdy iba prvy vyskyt hodnoty % === 12.2 === nd35(X) :- mod(X, 3) =\= 0, mod(X, 5) =\= 0. % dalo by sa pouzit aj is % === 12.3 === mem1(H,[H|_]). mem1(H,[_|T]) :- mem1(H,T). mem2(H,[H|_]) :- !. mem2(H,[_|T]) :- mem2(H,T). mem3(H,[K|_]) :- H==K. mem3(H,[K|T]) :- H\==K, mem3(H,T). % mem1 = je dokazatelne tolkokrat, kolko je vyskytov daneho prvku v zozname (+,+); % najpriamociarejsie, ale toto moze byt nevyhoda, ak nas zaujima iba % pritomnost/nepritomnost prvku v zozname % mem2 = je dokazatelne raz, ak sa prvok vyskytuje v zozname; ak by sme ale chceli % postupne generovat prvky zoznamu (-,+), nebude fungovat (preco?) % mem3 = nepouzitelne u (-,+) - nevygeneruje nic; u (+,+) funguje ako mem2 % === 12.4 === % === 12.5 === % vyber troch prvkov, na poradi zalezi % najprv urcime predikat, ktory bude schopny generovat variacie: % vyberieme prvy prvok, odstranime ho, zo zvysku vyberieme druhy prvok... variace_(L, [X,Y,Z]) :- member(X, L), delete(L, X, M), member(Y, M), delete(M, Y, N), member(Z, N). % teraz len vyuzijeme bagof, ktory nam vypocita vsetky variacie pomocou variace_ variace3(List, Var) :- bagof(X, variace_(List, X), Var). % kvoli neskratenemu vypisu u kombinace, ktory je dlhsi (bez neho by zobrazil % interpret len prvych niekolko prvkov) :- set_prolog_flag(toplevel_print_options, [max_depth(100)]). % vyber troch prvkov, na poradi nezalezi % zo zoznamu L vyberieme prvok X a tym ho rozdelime na zoznam pred prvkom X % (nezaujima nas, je to _) a zoznam po prvku Y (oznacime ho B); dalsi prvok % vyberame rovnakym sposobom z tohto zoznamu % % tymto zarucime, ze pre lubovolny vyber troch prvkov budu vzdy v presne urcenom % poradi a nemusime riesit ich rozne poradie kombinace_(L, [X,Y,Z]) :- append(_, [X|A], L), append(_, [Y|B], A), append(_, [Z|_], B). kombinace3(List, Var) :- bagof(X, kombinace_(List, X), Var). % === 12.6 === % ... % === 12.7 === % existuje viacero podobnych moznosti, ako toto riesit % pouzijeme pomocny predikat prvo(+Number, +Divisor), ktory bude postupne skusat % cislom od 2 po Number-1 prvocislo(Num) :- prvo(Num, 2). prvo(Num, Num) :- !. prvo(Num, D) :- Div < Num, mod(Num, D) =\= 0, D1 is D + 1, prvo(Num, D1). % === 12.8 === % cely obsah otvoreneho vstupneho prudu nacita do -Content read_stream(Content) :- get_char(X), (X == end_of_file -> Content = [] ; read_stream(Rest), Content = [X|Rest] ). contains(File, Char) :- see(File), read_stream(Contents), member(Char, Contents). seen.