Declaratieve Talen/Oplossing Graaf-isomorfie: verschil tussen versies

Uit Wina Examenwiki
Naar navigatie springen Naar zoeken springen
WinaBot (overleg | bijdragen)
Beau (overleg | bijdragen)
juiste oef
Regel 1: Regel 1:
==== Oplossing ====
==== Een oplossing: ====
Dit is een mogelijke oplossing:


  verbonden(A,B) :- boog(A,B).
  import List
verbonden(A,B) :- boog(B,A).
   
   
  verplaatsKeien(Van, Naar, Aantal, Knopen, Waarden, NieuweWaarden) :-
  iso::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->[(t,u)]
        member(Van, Knopen),
-------------------------------------------------------
        member(Naar, Knopen),
iso graaf1 graaf2 =
        verbonden(Van, Naar),
let
        index(Knopen, Van, VanPos),
(knopen1,bogen1) = graaf1
        index(Knopen, Naar, NaarPos),
(knopen2,bogen2) = graaf2
        index(Waarden, VanAantal, VanPos),
cond1 = length knopen1 /= length knopen2
        index(Waarden, NaarAantal, NaarPos),
cond2 = length bogen1 /= length bogen2
        numlist(1,VanAantal, Poss),
in
        member(Aantal, Poss),
if cond1
        VanAantal2 is VanAantal - Aantal,
then error "Knooplijsten zijn van verschillende lengte!!!"
        NaarAantal2 is NaarAantal + Aantal - 1,
else if cond2
        setElementAt(Waarden,VanPos,VanAantal2, NieuweWaardenTmp),
    then error "Booglijsten zijn van verschillende lengte!!!"
        setElementAt(NieuweWaardenTmp,NaarPos,NaarAantal2, NieuweWaarden).
    else vergelijk bogen1 bogen2 (combs knopen1 knopen2)
   
   
  kei_bereikbaar(Knoop) :-
  iso2::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->Bool
        findall(K, knoop(K, _), Knopen),
-----------------------------------------------------
        findall(W, knoop(_, W), Waarden),
iso2 graaf1 graaf2 =
        kei_bereikbaar2(Knoop, Knopen, Waarden, []).
let
(knopen1,bogen1) = graaf1
(knopen2,bogen2) = graaf2
cond1 = length knopen1 /= length knopen2
cond2 = length bogen1 /= length bogen2
in
if cond1 || cond2
then False
else vergelijk2 bogen1 bogen2 (combs knopen1 knopen2)
 
vergelijk::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->[(t,u)]
--------------------------------------------------------------
vergelijk _ _ [] = error "Geen gelijkenis gevonden"
vergelijk _ _ [[]] = error "Geen gelijkenis gevonden"
vergelijk b1 b2 (comb:rest) | controleer b1 b2 comb = comb
    | otherwise = vergelijk b1 b2 rest
vergelijk2::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->Bool
------------------------------------------------------------
vergelijk2 _ _ [] = False
vergelijk2 _ _ [[]] = False
vergelijk2 b1 b2 (comb:rest) | controleer b1 b2 comb = True
    | otherwise = vergelijk2 b1 b2 rest
 
controleer::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[(t,u)]->Bool
--------------------------------------------------------
controleer [] [] _ = True
controleer (x:xs) lijst koppels =
let
(tvan,tnaar) = x
uvan = head [b|(a,b)<-koppels,a==tvan]
unaar = head [b|(a,b)<-koppels,a==tnaar]
in
if (zitInLijst (uvan,unaar) lijst)
then controleer xs (verwijderUitLijst (uvan,unaar) lijst) koppels
else False
where
zitInLijst::(Eq u)=>(u,u)->[(u,u)]->Bool
----------------------------------------
zitInLijst _ [] = False
zitInLijst (u,v) ((x,y):rest) | (u==x) && (v==y) = True
      | otherwise = zitInLijst (u,v) rest
verwijderUitLijst::(Eq u)=>(u,u)->[(u,u)]->[(u,u)]
--------------------------------------------------
verwijderUitLijst _ [] = []
verwijderUitLijst (u,v) ((x,y):rest) | (u==x) && (v==y) = rest
    | otherwise = (x,y):(verwijderUitLijst (u,v) rest)
   
   
  kei_bereikbaar2(Knoop, Knopen, Waarden, _) :-
  subiso::(Ord t,Ord u)=>([t],[(t,t)])->([u],[(u,u)])->Bool
        index(Knopen, Knoop, Pos),
  -------------------------------------------------------
        index(Waarden, Aantal, Pos),
subiso graaf1 graaf2 =
        Aantal > 0.
let
  kei_bereikbaar2(Knoop, Knopen, Waarden, Gedaan) :-
(knopen1,bogen1) = graaf1
        knoop(Van, _),
(knopen2,bogen2) = graaf2
        index(Knopen, Van, Pos),
in
        index(Waarden, VanAantal, Pos),
check graaf1 (maakDeelGraaf graaf2)
        VanAantal > 1,
where
        knoop(Naar, _),
check::(Ord u,Ord t)=>([t],[(t,t)])->[([u],[(u,u)])]->Bool
        % A -> B => nutteloos om B -> A te doen:
----------------------------------------------------------
        not(member((Naar, Van), Gedaan)),
check _ [] = False
        NieuwGedaan = [(Van, Naar) | Gedaan],
check g1 (sub:rest) | iso2 g1 sub = True
        verplaatsKeien(Van,Naar,_,Knopen,Waarden,NieuweWaarden),
    | otherwise  = check g1 rest
        kei_bereikbaar2(Knoop, Knopen, NieuweWaarden, NieuwGedaan).
   
   
  kei_goed :-
  maakDeelGraaf::(Ord u)=>([u],[(u,u)])->[([u],[(u,u)])]
        forall(knoop(Knoop, _), kei_bereikbaar(Knoop)).
-----------------------------------------------------
maakDeelGraaf graaf =
let
(knopen,bogen) = graaf
deelKnopen = maakDeelKnopen knopen
in
combineerMetBogen deelKnopen bogen
   
   
  kei_nijg :-
  combineerMetBogen::(Eq u)=>[ [u] ]->[(u,u)]->[([u],[(u,u)])]
        findall(K, knoop(K, _), Knopen),
----------------------------------------------------------
        findall(W, knoop(_, W), Waarden),
combineerMetBogen [] _ = []
        kei_nijg2(Knopen, Waarden, []).
combineerMetBogen (el:rest) bogen = (el,(bogen2 el bogen)):(combineerMetBogen rest bogen)
where
bogen2::(Eq u)=>[u]->[(u,u)]->[(u,u)]
-------------------------------------
bogen2 _ [] = []
bogen2 knopen (boog:rest) =
let
(van,naar) = boog
in
if ((van `elem` knopen) && (naar `elem` knopen))
then boog:(bogen2 knopen rest)
else bogen2 knopen rest
   
   
  kei_nijg2(_, Waarden, _) :-
  maakDeelKnopen::(Ord u)=>[u]->[ [u] ]
        forall(member(X, Waarden), X > 0).
  -------------------------------------
  kei_nijg2(Knopen, Waarden, Gedaan) :-
maakDeelKnopen knopen = nub [sort y|x<-(perms knopen),y<-inits x]
        knoop(Van, _),
 
        index(Knopen, Van, Pos),
combs::[t]->[u]->[ [(t,u)] ]
        index(Waarden, VanAantal, Pos),
----------------------------
        VanAantal > 1,
combs g1 g2 = combineer g1 (perms g2)
        knoop(Naar, _),
where
        % A -> B => nutteloos om B -> A te doen:
combineer::[t]->[ [u] ]->[ [(t,u)] ]
        not(member((Naar, Van), Gedaan)),
------------------------------------
        NieuwGedaan = [(Van, Naar) | Gedaan],
combineer _ [[]] = [[]]
        verplaatsKeien(Van,Naar,_,Knopen,Waarden,NieuweWaarden),
combineer lijst (x:xs) = (zip lijst x):(combineer lijst xs)
        kei_nijg2(Knopen, NieuweWaarden, NieuwGedaan).
   
   
  index([], _, _) :- 0 = 1.
  perms::[u]->[ [u] ]
  index([RijHoofd|_], Element, Index) :-
  -------------------
        RijHoofd = Element,
  perms [] = [[]]
        Index = 0.
  perms (x:xs) = concatMap (interleave x) (perms xs)
  index([RijHoofd|Rest], Element, Index) :-
        nonvar(Element),
        RijHoofd \= Element,
        index(Rest, Element, SubIndex),
        Index is 1 + SubIndex.
  index([_|Rest], Element, Index) :-
        nonvar(Index),
        SubIndex is Index - 1,
        index(Rest, Element, SubIndex).
   
   
  setElementAt([], _, _) :- 0 = 1.
  interleave::u->[u]->[ [u] ]
  setElementAt([_|Rest], 0, X, NieuweRij) :-
---------------------------
        NieuweRij = [X|Rest].
  interleave x [] = [ [x] ]
  setElementAt([RijHoofd|Rest], A, X, NieuweRij) :-
  interleave x (y:ys) = [x:y:ys]++map (y:) (interleave x ys)
        A > 0,
        A2 is A - 1,
        setElementAt(Rest,A2,X,Rest2),
        NieuweRij = [RijHoofd|Rest2].

Versie van 17 jun 2006 10:53

Een oplossing:

import List

iso::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->[(t,u)]
-------------------------------------------------------
iso graaf1 graaf2 = 
	let
		(knopen1,bogen1) = graaf1
		(knopen2,bogen2) = graaf2
		cond1 = length knopen1 /= length knopen2
		cond2 = length bogen1 /= length bogen2
	in
		if cond1
		then error "Knooplijsten zijn van verschillende lengte!!!"
		else if cond2
		     then error "Booglijsten zijn van verschillende lengte!!!"
		     else vergelijk bogen1 bogen2 (combs knopen1 knopen2)

iso2::(Eq t,Eq u)=>([t],[(t,t)])->([u],[(u,u)])->Bool
-----------------------------------------------------
iso2 graaf1 graaf2 =
	let
		(knopen1,bogen1) = graaf1
		(knopen2,bogen2) = graaf2
		cond1 = length knopen1 /= length knopen2
		cond2 = length bogen1 /= length bogen2
	in
		if cond1 || cond2
		then False
		else vergelijk2 bogen1 bogen2 (combs knopen1 knopen2)


vergelijk::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->[(t,u)]
--------------------------------------------------------------
vergelijk _ _ [] = error "Geen gelijkenis gevonden"
vergelijk _ _ [[]] = error "Geen gelijkenis gevonden"
vergelijk b1 b2 (comb:rest) | controleer b1 b2 comb = comb
			    | otherwise = vergelijk b1 b2 rest

vergelijk2::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[ [(t,u)] ]->Bool
------------------------------------------------------------
vergelijk2 _ _ [] = False
vergelijk2 _ _ [[]] = False
vergelijk2 b1 b2 (comb:rest) | controleer b1 b2 comb = True
			     | otherwise = vergelijk2 b1 b2 rest
controleer::(Eq t,Eq u)=>[(t,t)]->[(u,u)]->[(t,u)]->Bool
--------------------------------------------------------
controleer [] [] _ = True
controleer (x:xs) lijst koppels =
		let
			(tvan,tnaar) = x
			uvan = head [b|(a,b)<-koppels,a==tvan]
			unaar = head [b|(a,b)<-koppels,a==tnaar]
		in
			if (zitInLijst (uvan,unaar) lijst)
			then controleer xs (verwijderUitLijst (uvan,unaar) lijst) koppels
			else False
		where 
			zitInLijst::(Eq u)=>(u,u)->[(u,u)]->Bool
			----------------------------------------
			zitInLijst _ [] = False
			zitInLijst (u,v) ((x,y):rest) | (u==x) && (v==y) = True
						      | otherwise = zitInLijst (u,v) rest
			
			verwijderUitLijst::(Eq u)=>(u,u)->[(u,u)]->[(u,u)]
			--------------------------------------------------
			verwijderUitLijst _ [] = []
			verwijderUitLijst (u,v) ((x,y):rest) | (u==x) && (v==y) = rest
							     | otherwise = (x,y):(verwijderUitLijst (u,v) rest)

subiso::(Ord t,Ord u)=>([t],[(t,t)])->([u],[(u,u)])->Bool
-------------------------------------------------------
subiso graaf1 graaf2 =
	let
		(knopen1,bogen1) = graaf1
		(knopen2,bogen2) = graaf2
	in	
		check graaf1 (maakDeelGraaf graaf2)
	where
		check::(Ord u,Ord t)=>([t],[(t,t)])->[([u],[(u,u)])]->Bool
		----------------------------------------------------------
		check _ [] = False
		check g1 (sub:rest) | iso2 g1 sub = True
				    | otherwise   = check g1 rest

maakDeelGraaf::(Ord u)=>([u],[(u,u)])->[([u],[(u,u)])]
-----------------------------------------------------
maakDeelGraaf graaf =
	let
		(knopen,bogen) = graaf
		deelKnopen = maakDeelKnopen knopen
	in
		combineerMetBogen deelKnopen bogen

combineerMetBogen::(Eq u)=>[ [u] ]->[(u,u)]->[([u],[(u,u)])]
----------------------------------------------------------
combineerMetBogen [] _ = []
combineerMetBogen (el:rest) bogen = (el,(bogen2 el bogen)):(combineerMetBogen rest bogen)
	where
		bogen2::(Eq u)=>[u]->[(u,u)]->[(u,u)]
		-------------------------------------
		bogen2 _ [] = []
		bogen2 knopen (boog:rest) =
			let
				(van,naar) = boog
			in
				if ((van `elem` knopen) && (naar `elem` knopen))
				then boog:(bogen2 knopen rest)
				else bogen2 knopen rest

maakDeelKnopen::(Ord u)=>[u]->[ [u] ]
-------------------------------------
maakDeelKnopen knopen = nub [sort y|x<-(perms knopen),y<-inits x]
combs::[t]->[u]->[ [(t,u)] ]
----------------------------
combs g1 g2 = combineer g1 (perms g2)
	where
		combineer::[t]->[ [u] ]->[ [(t,u)] ]
		------------------------------------
		combineer _ [[]] = [[]]
		combineer lijst (x:xs) = (zip lijst x):(combineer lijst xs)

perms::[u]->[ [u] ]
-------------------
perms [] = [[]]
perms (x:xs) = concatMap (interleave x) (perms xs)

interleave::u->[u]->[ [u] ]
---------------------------
interleave x [] = [ [x] ]
interleave x (y:ys) = [x:y:ys]++map (y:) (interleave x ys)