Files
secondo/ParallelTransform/Transform.pl
2026-01-23 17:03:45 +08:00

299 lines
8.6 KiB
Prolog

/*
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 <Relation>
2. Wenn bereits gefundene <Relation> und noch feed vorhanden dann wieder hinter feed
3. Wenn keine <Relation> gefunden und kein feed dann ist letztes ELement eine <Relation>
*/
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)
.