/* Nur count ---- sequentiell Eingang (pquery (count Roads)) parallel Ergebnis (query (tie (getValue (dloop2 Roads "" (fun (darray2elem1 DARRAY2ELEM) (count darray2elem1)))) (fun (first2 ELEMENT) (second3 ELEMENT) (+ first2 second3)))) [pquery,[count,Roads]] [pquery,[tie,[getValue,[dloop2,Roads,"",[fun,[darray2elem1,DARRAY2ELEM],[count,darray2elem1]]]],[fun,[first2,ELEMENT],[second3,ELEMENT],[+,first2,second3]]]] ---- Count mit Filter ---- sequentiell Eingang (pquery (count (filter (feed Roads) (fun (streamelem1 STREAMELEM) (contains (attr streamelem1 Type) "primary"))))) ---- Prolog-Darstellung ---- [pquery,[count,[filter,[feed,roads],[fun,[streamelem1,sTREAMELEM],[contains,[attr,streamelem1,type],"primary"]]]]] ---- parallel Ergebnis ---- (query (tie (getValue (dloop2 Roads "" (fun (darray2elem1 DARRAY2ELEM) (count (filter (feed darray2elem1) (fun (streamelem2 STREAMELEM) (contains (attr streamelem2 Type) "primary"))))))) (fun (first3 ELEMENT) (second4 ELEMENT) (+ first3 second4)))) ---- Prolog-Darstellung (Eingangs query darf keine grossengeschriebenen Elemente mehr enthalten) ---- [pquery,[count,[filter,[feed,Roads],[fun,[streamelem1,STREAMELEM],[contains,[attr,streamelem1,Type],"primary"]]]]] ##ENDE [pquery,[tie,[getValue,[dloop2,Roads,"",[fun,[darray2elem1,DARRAY2ELEM],[count,[filter,[feed,darray2elem1],[fun,[streamelem2,STREAMELEM],[contains,[attr,streamelem2,Type],"primary"]]]]]]],[fun,[first3,ELEMENT],[second4,ELEMENT],[+,first3,second4]]]] ---- */ query_to_parallel(QueryNL, ParallelNL) :- write('Query: '), write(QueryNL), nl, /* Relations aus Query ausschneiden */ splitFromRelations(QueryNL, Relations), write('Relations: '), writeln(Relations), /* ersetzen der Relations im Query durch elemXX */ replaceRelationInQuery(Relations, elem, QueryNL, QueryRelsNewNL, 0), write('QueryRelsNew: '), write(QueryRelsNewNL), nl, /* Trenne Funktion bzw. Value-Expression von query-command */ QueryRelsNewNL = [QueryCommand | [FunktionNL]], write('Funktion: '), write(FunktionNL), nl, /* TransformRegel aufrufen inkl. Pruefung auf Tie[]-Notwendigkeit */ queryToParallelTieDecision(Relations, FunktionNL, ParallelNL), write('Ergebnis: '), write(ParallelNL), nl . /* Entscheidet anhand der zu startenden Funktion welche Fakten fuer die parallele Transformation benutzt werden */ queryToParallelTieDecision(Relations, FunktionNL, Parallel) :- /* Fall mit Tie[] Operator, wenn Funktion ein count o. sum an 1. Stelle enthaelt */ flatten(FunktionNL, FunktionFlat), FunktionFlat = [Head | Tail], (Head == count; Head == sum), secondoPrologParallelQueryTie(Relations, FunktionNL, Parallel) . queryToParallelTieDecision(Relations, FunktionNL, Parallel) :- /* Fall mit Tie[] Operator, wenn Funktion ein min o. max an 1. Stelle enthaelt */ flatten(FunktionNL, FunktionFlat), FunktionFlat = [Head | Tail], (Head == min; Head == max), (Head == min -> secondoPrologParallelQueryMin(Relations, FunktionNL, Parallel) ; Head == max -> secondoPrologParallelQueryMax(Relations, FunktionNL, Parallel) ) . queryToParallelTieDecision(Relations, FunktionNL, Parallel) :- /* Fall mit Tie[] Operator, wenn Funktion ein avg an 1. Stelle enthaelt. Laeuft aktuell noch falsch, muss auf Summe(Summe(attribut)) dividiert durch Summe(count(attribut)) */ flatten(FunktionNL, FunktionFlat), FunktionFlat = [Head | Tail], Head == avg, secondoPrologParallelQueryAvg(Relations, FunktionNL, Parallel) . queryToParallelTieDecision(Relations, FunktionNL, Parallel) :- /* Fall ohne Tie[] Operator */ flatten(FunktionNL, FunktionFlat), FunktionFlat = [Head | Tail], Head \= count, Head \= avg, Head \= max, Head \= min, Head \= sum, secondoPrologParallelQuery(Relations, FunktionNL, Parallel) . /* Fuegt gefundene Relationen in eine Liste */ splitFromRelations(Query, Relations) :- writeln('Start Split'), flatten(Query, QueryList), writeln('Flatten'), findRelations(QueryList, [], Relations) . /* Relationen anhand drei bestimmter Regeln in Funktion identifizieren 1. hinter feed befindet sich gekennzeichnete 2. Wenn bereits gefundene und noch feed vorhanden dann wieder hinter feed 3. Wenn keine gefunden und kein feed dann ist letztes ELement eine */ findRelations([],_,_). /* feed existiert */ findRelations(QList, TmpRels, Relations) :- member(feed, QList), nth0(FeedIdx, QList, feed), TempIdx is FeedIdx+1, nth0(TempIdx, QList, Relation), atom_chars(Relation, RelChars), write('QList: '), writeln(QList), write('Rel Chars1: '), writeln(RelChars), (member('<', RelChars) -> append(TmpRels,[Relation],NewTmpRels), selectchk(feed, QList, RestList), /* write('Treffer < 1: '), writeln(RestList), write('NewTmpRels 1: '), writeln(NewTmpRels),*/ findRelations(RestList, NewTmpRels, Relations) ; selectchk(feed, QList, RestList), /* write('kein Treffer < 1: '), writeln(RestList), write('NewTmpRels 1: '), writeln(TmpRels),*/ findRelations(RestList, TmpRels, Relations) ) . /* feed existiert nicht und TmpRels belegt */ findRelations(QList, TmpRels, Relations) :- \+member(feed, QList), \+length(TmpRels, 0), Relations = TmpRels . /* feed existiert nicht und TmpRels unbelegt */ findRelations(QList, TmpRels, Relations) :- \+member(feed, QList), length(TmpRels, 0), last(QList, Relation), atom_chars(Relation, RelChars), write('Rel Chars2: '), writeln(RelChars), member('<', RelChars), append([],[Relation],Relations) . /* Ersetzt die Liste von Relationen im Query durch einen Platzhalter mit gezaehltem Index*/ replaceRelationInQuery([], elem, Query, _, _). replaceRelationInQuery([Head | Tail], elem, Query, QueryNew, Idx) :- Tail = [], plus(11, Idx, IdxNew), atom_number(IdxAtom, IdxNew), atom_concat(elem, IdxAtom, ReplaceValue), /* write('Query End: '), writeln(Query), write('ReplValue End: '), writeln(ReplaceValue), */ nb_setval('hit', 0), replaceAtom(Head, ReplaceValue, Query, TMPQuery), QueryNew = TMPQuery . replaceRelationInQuery([Head | Tail], elem, Query, QueryNew, Idx) :- plus(11, Idx, IdxNew), atom_number(IdxAtom, IdxNew), atom_concat(elem, IdxAtom, ReplaceValue), /* write('ReplValue : '), writeln(ReplaceValue),*/ nb_setval('hit', 0), replaceAtom(Head, ReplaceValue, Query, TMPQuery), replaceRelationInQuery(Tail, elem, TMPQuery, QueryNew, IdxNew) . remove_at(X,[X|Xs],1,Xs). remove_at(X,[Y|Xs],K,[Y|Ys]) :- K > 1, K1 is K - 1, remove_at(X,Xs,K1,Ys). /* subs(Suchwert, Ersetzungswert, InitialListeNL, ErsetzungsListeNL). Ermoeglicht das ersetzen 'eines' Treffers. alle anderen werden wieder in Ergebnis-NestedList gepackt alternativ: */ replaceAtom(_, _, [], []). replaceAtom(X, Y, [H1|T1], [H2|T2]) :- (H1 == X -> nb_getval('hit', Hit), plus(1, Hit, HitNew), nb_setval('hit', HitNew), (HitNew =< 1 -> H2 = Y, replaceAtom(X, Y, T1, T2) ; H1 = H2, replaceAtom(X, Y, T1, T2) ) ; is_list(H1) -> replaceAtom(X, Y, H1, H2), replaceAtom(X, Y, T1, T2) ; H1 = H2, replaceAtom(X, Y, T1, T2) ). /* Ersetzt alle Treffer mit uebergebenem Wert und gibt NestedList zurueck ---- replaceAtomAll(_, _, [], []). replaceAtomAll(X, Y, [X|T1], [Y|T2]) :- replaceAtomAll(X, Y, T1, T2), ! . replaceAtomAll(X, Y, [H|T1], [H|T2]) :- \+ is_list(H), replaceAtomAll(X, Y, T1, T2), ! . replaceAtomAll(X, Y, [H1|T1], [H2|T2]) :- replaceAtomAll(X, Y, H1, H2), replaceAtomAll(X, Y, T1, T2) . ---- */ print_all([]). print_all([X|Rest]) :- write(X), nl, print_all(Rest). list_to_downcase([]). list_to_downcase([X|Rest]) :- write(X), downcase_atom(X, LowerX), write(' -> '), write(LowerX), nl, flatten(Rest, FlRest), list_to_downcase(FlRest) .