Declaratieve Talen/oplossingenContradicties: verschil tussen versies
Naar navigatie springen
Naar zoeken springen
kGeen bewerkingssamenvatting |
Geen bewerkingssamenvatting |
||
Regel 37: | Regel 37: | ||
--[[Gebruiker:Greet|Greet]] | --[[Gebruiker:Greet|Greet]] | ||
Alternatief omdat ik denk dat bovenstaande niet in het algemene geval werkt: | |||
<pre> | |||
% 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), pad(P,X,X,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)). | |||
</pre> | |||
--[[Gebruiker:Thomas Vochten|Thomas Vochten]] |
Versie van 11 jan 2014 13:17
% 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), pad(P,X,X,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)).