Declaratieve Talen/oplossingenContradicties: verschil tussen versies
Naar navigatie springen
Naar zoeken springen
Geen bewerkingssamenvatting |
Geen bewerkingssamenvatting |
||
Regel 60: | Regel 60: | ||
tegen(P,Tegens) :- | tegen(P,Tegens) :- | ||
findall(Letter, antwoord(P,Letter,_), LetterLijst), | findall(Letter, antwoord(P,Letter,_), LetterLijst), | ||
findall(Pad, (member(X,LetterLijst), | findall(Pad, (member(X,LetterLijst), langste_pad(P,X,Pad)), Paden), | ||
sortlists(Paden,DeepLevelSorted), | sortlists(Paden,DeepLevelSorted), | ||
sort(DeepLevelSorted,Tegens). % verwijdert duplicates | sort(DeepLevelSorted,Tegens). % verwijdert duplicates | ||
Regel 91: | Regel 91: | ||
NewAcc = [ Y | Acc ], | NewAcc = [ Y | Acc ], | ||
pad(Persoon,Bron,Doel,Y,NewAcc,Bezocht)). | pad(Persoon,Bron,Doel,Y,NewAcc,Bezocht)). | ||
% vindt het langste pad voor de gegeven letter | |||
langste_pad(P,Letter,Pad) :- | |||
findall(Pad, pad(P,Letter,Letter,Letter,[],Pad), Paden), | |||
langste_rec(Paden,0,Acc,Pad). | |||
langste_rec([], _, Langste, Langste). | |||
langste_rec([Pad | Paden],Length,Acc,Langste) :- | |||
length(Pad,CurrLength), | |||
(CurrLength > Length -> | |||
NewAcc = Pad, | |||
langste_rec(Paden,CurrLength,NewAcc,Langste) | |||
; | |||
langste_rec(Paden,Length,Acc,Langste)). | |||
</pre> | </pre> | ||
--[[Gebruiker:Thomas Vochten|Thomas Vochten]] | --[[Gebruiker:Thomas Vochten|Thomas Vochten]] |
Versie van 11 jan 2014 15:39
% To Do een predicaat meetegen(P,A) schrijven dat teruggeeft of die % antwoordletter in contradictie is met een andere antwordleter. % In een graaf ziet een contradictie eruit indien er een lus is. % Algemene Strategie : we gaan voor de gegeven antwoordletter het pad % doorheen de graaf volgen en kijken of we een pad naar onszelf tegen % komen %Prolog feiten: antwoord(jan,c,[a,b,d,e]). antwoord(jan,i,[f,k,c,b]). antwoord(jan,j,[i,f,h,e]). antwoord(jan,k,[j,h,g,d]). buren(X,Y):-antwoord(_,X,Lijst), member(Y,Lijst). % buren in de andere richting zou je hier ook makkelijk kunnen % definieren, maar dit is in ons geval niet nodig. meetegen(P,A):-antwoord(P,A,_), doorloopGraaf(P,A,A,[A]),!. doorloopGraaf(P,A,B,Pad):- buren(A,X), ( \+ member(X,Pad)-> append(Pad,[X],New), doorloopGraaf(P,X,B,New) ; true ). %maak een predikaat tegen(P,Tegens) tegen(P,Tegens):- findall(X,doorloopGraaf(P,X,X,[]),Tegens).
--Greet
Alternatief omdat ik denk dat bovenstaande niet in het algemene geval werkt:
% Prolog-feiten antwoord(jan,c,[a,b,d,e]). antwoord(jan,i,[f,k,c,b]). antwoord(jan,j,[i,f,h,e]). antwoord(jan,k,[j,h,g,d]). % Atoom voor een quick-and-dirty manier om de recursie % van pad/6 te laten eindigen. pad_gevonden. % A is in contradictie met een andere letter % als er een kring bestaat die begint in A meetegen(P,A) :- pad(P,A,A,A,[],_). % bouw eerst alle lijsten op van letters die in contradictie zijn met elkaar % en verwijder dan alle dubbels die zijn ontstaan tegen(P,Tegens) :- findall(Letter, antwoord(P,Letter,_), LetterLijst), findall(Pad, (member(X,LetterLijst), langste_pad(P,X,Pad)), Paden), sortlists(Paden,DeepLevelSorted), sort(DeepLevelSorted,Tegens). % verwijdert duplicates % sorteer een lijst van lijsten sortlists(In,Out) :- sortlists(In,[],Out). sortlists([],Out,Out). sortlists([In | Rest],Acc,Out) :- sort(In,Sorted), NewAcc = [ Sorted | Acc ], sortlists(Rest,NewAcc,Out). % Voor Persoon is Y een buur van letter als Y voorkomt in de lijst voor die letter % en als Y ook een onderdeel is van een antwoord/3 feit. % Volgens deze logica is 'j' een buur van 'i', maar is 'e' geen buur van 'c' buren(Persoon,Letter,Y) :- antwoord(Persoon,Letter,Lijst), member(Y,Lijst), antwoord(Persoon,Y,_). % Er is een pad gevonden: output Pad pad(_,_,_,_,pad_gevonden,Pad,Pad). pad(Persoon,Bron,Doel,Vorige,Acc,Bezocht) :- buren(Persoon,Vorige,Y), % backtracking zorgt ervoor dat effectief alle buren worden overlopen \+ member(Y,Acc), % anders loopt Prolog vast in een kring (Doel == Y -> % pad gevonden: output deze reverse([ Y | Acc ],NewAcc), pad(Persoon,Bron,Doel,Y,pad_gevonden,NewAcc,Bezocht) ; NewAcc = [ Y | Acc ], pad(Persoon,Bron,Doel,Y,NewAcc,Bezocht)). % vindt het langste pad voor de gegeven letter langste_pad(P,Letter,Pad) :- findall(Pad, pad(P,Letter,Letter,Letter,[],Pad), Paden), langste_rec(Paden,0,Acc,Pad). langste_rec([], _, Langste, Langste). langste_rec([Pad | Paden],Length,Acc,Langste) :- length(Pad,CurrLength), (CurrLength > Length -> NewAcc = Pad, langste_rec(Paden,CurrLength,NewAcc,Langste) ; langste_rec(Paden,Length,Acc,Langste)).