Declaratieve Talen/Oplossing celautomaat: verschil tussen versies

Uit Wina Examenwiki
Naar navigatie springen Naar zoeken springen
Roald (overleg | bijdragen)
Geen bewerkingssamenvatting
Nick.dewaele (overleg | bijdragen)
nog een oplossing
 
(Een tussenliggende versie door een andere gebruiker niet weergegeven)
Regel 1: Regel 1:
====Een oplossing====
Deze oplossing werkte voor zover ik getest heb... Bij predicaat regels wordt ook overal de 'javelregel' toegevoegd.  
Deze oplossing werkte voor zover ik getest heb... Bij predicaat regels wordt ook overal de 'javelregel' toegevoegd.  
   
   
Regel 53: Regel 54:




----


Een andere oplossing:
====Een andere oplossing====
  % Vraag 1:
  % Vraag 1:
  volgendegen(Seq, Regels, Volgende) :-
  volgendegen(Seq, Regels, Volgende) :-
Regel 85: Regel 85:
  regels([_|Seqs], RegelAcc, Regels) :-
  regels([_|Seqs], RegelAcc, Regels) :-
  regels(Seqs, RegelAcc, Regels).
  regels(Seqs, RegelAcc, Regels).
[[Gebruiker:Roald|Roald]] 12 jan 2010 22:38 (UTC)
=== Nog een oplossing ===
--[[Gebruiker:Nick.dewaele|Nick.dewaele]] ([[Overleg gebruiker:Nick.dewaele|overleg]]) 30 dec 2017 19:01 (CET)
<strong>Deze is gebaseerd op het gedeeltelijk instantieren van de kop van een lijst (wordt wel duidelijk als je de debugger volgt)</strong>
<code>
exampleRules(R) :- R = [[o,o,o,o],[o,o,x,x], [o,x,o,o], [x,o,o,x], [x,o,x,x]].
% past een regel toe, gegeven een lijst regels. Res unificeert met het nieuwe symbool,
% en AppliedRule is de regel die toegepast werd
applyAppropRule(A,B,C,[[A,B,C,D]|_], D, [A,B,C,D]).
applyAppropRule(A,B,C,[[X,Y,Z,_]|Tail], Res, AppliedRule) :-
        A-B-C \= X-Y-Z,
        applyAppropRule(A,B,C,Tail, Res, AppliedRule).
% zoals gevraagd in de opgave
volgendegen(Seq, Rules, Res) :-
        nextLevel(Seq, Rules, Res, _).
% hulppredicaat voor 'volgendegen'. Deze zal zowel het resultaat teruggeven als de lijst van toegepaste regels (belangrijk voor het tweede deel)
nextLevel(Seq, Rules, Res, AppliedRules) :-
        append([o,o|Seq], [o,o], Seq2),
        length(Seq, L),
        LenRes is L + 2,
        length(Res, LenRes),
        subs(Seq2, Rules, [], Res, [], AppliedRules).
% voer 1 substitutie uit, waarbij je het resultaat Res 1 stapje verder instantieert.
% Dit geeft ook een lijst van toegepaste regels.
subs([A,B,C|T], Rules, Acc, Res, AccRules, AppliedRules) :-
        applyAppropRule(A,B,C,Rules, NewSymbol, AppliedRule),
        append(Acc,[NewSymbol], NewAcc),
        append(NewAcc, _, Res),
        subs([B,C|T], Rules, NewAcc, Res, [AppliedRule | AccRules], AppliedRules).
subs(L, _, _, _, AccRules, AccRules) :-
        L \= [_,_,_|_].       
% zoals gevraagd in de opgave
regels(L, Rules) :-
        search(L, <nowiki>[[o,o,o,o]]</nowiki>, UsedRules),
        sort(UsedRules, Rules).
% hulppredicaat voor 'regels'. AccRules geeft de regels die tot nu toe gebruikt zijn.
search([Seq,Seq2|Seqs], AccRules, FinalRules) :-
        append(AccRules, _, Rules),
        nextLevel(Seq, Rules, Seq2, ApplRules),
        append(AccRules, ApplRules, NewRules),
        search([Seq2|Seqs], NewRules, FinalRules).
       
search([_], AccRules, AccRules).
</code>

Huidige versie van 30 dec 2017 18:01

Een oplossing

Deze oplossing werkte voor zover ik getest heb... Bij predicaat regels wordt ook overal de 'javelregel' toegevoegd.

volgendegen(Seq,Regels,Volgende):-
	volgendegen2([o,o|Seq],Regels,Volgende).

volgendegen2([S1,S2],Regels,[V1,V2]):-
	member([S1,S2,o,V1],Regels),
	member([S2,o,o,V2],Regels).
volgendegen2([S1,S2,S3|Seq],Regels,[V1|Volgende]):-
	member([S1,S2,S3,V1],Regels),
	volgendegen2([S2,S3|Seq],Regels,Volgende).

regels([S1,S2],Regels):-
	 regelsseq(S1,Regels,S2).
regels([S1,S2|Sequenties],Regels):-
	 regels([S2|Sequenties],R1),
	 regelsseq(S1,R2,S2),
	 merge(R1,R2,R3),
	 remove_doubles(R3,Regels),
	 geldig(Regels).

% regels genereren voor 1 overgang van een sequentie naar zijn opvolger 
% bij eerste in sequentie 2 o's toevoegen voor het genereren begint
regelsseq(S1,Regels,S2):-
	 regelsseq2([o,o|S1],Regels,S2).

% op het einde van de sequentie 2 extra o's veronderstellen 
regelsseq2([o,o],[ [o,o,o,V] ],[V,V]).
regelsseq2([o,x],[[o,x,o,V1],[x,o,o,V2]],[V1,V2]).
regelsseq2([x,o],[[x,o,o,V1],[o,o,o,V2]],[V1,V2]).
regelsseq2([x,x],[[x,x,o,V1],[x,o,o,V2]],[V1,V2]).
regelsseq2([S1,S2,S3|Seq],Regels,[V1|Volgende]):-
	 regelsseq2([S2,S3|Seq],Regels,Volgende),
	 member([S1,S2,S3,V1],Regels).
regelsseq2([S1,S2,S3|Seq],[[S1,S2,S3,V1]|Regels],[V1|Volgende]):-
	 regelsseq2([S2,S3|Seq],Regels,Volgende),
	 \+member([S1,S2,S3,_],Regels).

% dubbels verwijderen uit een lijst van regels
remove_doubles([L],[L]).
remove_doubles([L|List],L2):-
	 remove_doubles(List,L2),
	 member(L,L2).
remove_doubles([L|List],[L|L2]):-
	 remove_doubles(List,L2),
	 \+member(L,L2).

% testen of een lijst van regels geen tegenstrijdige regels bevat
geldig([_]).
geldig([[X,Y,Z,_]|List]):-
	 geldig(List),
	 \+member([X,Y,Z,_],List).


Een andere oplossing

% Vraag 1:
volgendegen(Seq, Regels, Volgende) :-
	append([o,o|Seq],[o,o],Seq2),
	findall(Nieuw,
		(append(_,Skipped,Seq2),append([A,B,C],_,Skipped),
			member([A,B,C,Nieuw],Regels)
		),
		Volgende).

% Vraag 2:
regels(Sequenties, Regels) :-
	findall(Seq2,
		(member(Seq,Sequenties),
			append([o,o|Seq],[o,o],Seq2)
		),
		Padded),
	regels(Padded, [], Regels).
regels([_], Regels, Regels).
regels([[L,X,R|T1], [_,A,N|T2] | Rest], RegelAcc, Regels) :-
	!,
	(member([L,X,R,_], RegelAcc) ->
		forall(member([L,X,R,OudeRegel], RegelAcc),
			N = OudeRegel),	% Is de regel wel consistent?
		regels([[X,R|T1],[A,N|T2]|Rest], RegelAcc, Regels)
	;
		regels([[X,R|T1],[A,N|T2]|Rest], [[L,X,R,N]|RegelAcc], Regels)
	).
regels([_|Seqs], RegelAcc, Regels) :-
	regels(Seqs, RegelAcc, Regels).

Roald 12 jan 2010 22:38 (UTC)

Nog een oplossing

--Nick.dewaele (overleg) 30 dec 2017 19:01 (CET)

Deze is gebaseerd op het gedeeltelijk instantieren van de kop van een lijst (wordt wel duidelijk als je de debugger volgt)

exampleRules(R) :- R = [[o,o,o,o],[o,o,x,x], [o,x,o,o], [x,o,o,x], [x,o,x,x]].

% past een regel toe, gegeven een lijst regels. Res unificeert met het nieuwe symbool,
% en AppliedRule is de regel die toegepast werd
applyAppropRule(A,B,C,[[A,B,C,D]|_], D, [A,B,C,D]).
applyAppropRule(A,B,C,[[X,Y,Z,_]|Tail], Res, AppliedRule) :-
        A-B-C \= X-Y-Z,
        applyAppropRule(A,B,C,Tail, Res, AppliedRule).

% zoals gevraagd in de opgave
volgendegen(Seq, Rules, Res) :-
        nextLevel(Seq, Rules, Res, _).

% hulppredicaat voor 'volgendegen'. Deze zal zowel het resultaat teruggeven als de lijst van toegepaste regels (belangrijk voor het tweede deel)
nextLevel(Seq, Rules, Res, AppliedRules) :-
        append([o,o|Seq], [o,o], Seq2),
        length(Seq, L),
        LenRes is L + 2,
        length(Res, LenRes),
        subs(Seq2, Rules, [], Res, [], AppliedRules).

% voer 1 substitutie uit, waarbij je het resultaat Res 1 stapje verder instantieert. 
% Dit geeft ook een lijst van toegepaste regels.
subs([A,B,C|T], Rules, Acc, Res, AccRules, AppliedRules) :-
        applyAppropRule(A,B,C,Rules, NewSymbol, AppliedRule),
        append(Acc,[NewSymbol], NewAcc),
        append(NewAcc, _, Res),
        subs([B,C|T], Rules, NewAcc, Res, [AppliedRule | AccRules], AppliedRules).

subs(L, _, _, _, AccRules, AccRules) :-
        L \= [_,_,_|_].        

% zoals gevraagd in de opgave
regels(L, Rules) :-
        search(L, [[o,o,o,o]], UsedRules),
        sort(UsedRules, Rules).

% hulppredicaat voor 'regels'. AccRules geeft de regels die tot nu toe gebruikt zijn.
search([Seq,Seq2|Seqs], AccRules, FinalRules) :-
        append(AccRules, _, Rules),
        nextLevel(Seq, Rules, Seq2, ApplRules),
        append(AccRules, ApplRules, NewRules),
        search([Seq2|Seqs], NewRules, FinalRules).
        
search([_], AccRules, AccRules).