
% Print meta-syntax representation output by mapper.

% -------------------------------------------------------------

% $Id: print.pl,v 2.4 1994/05/05 16:21:25 dbc Exp dbc $

% $Log: print.pl,v $
% Revision 2.4  1994/05/05  16:21:25  dbc
% Add support for printing variable mapping descriptors.
% Add support for printing function argument mapping descriptors.
%
% Revision 2.3  1994/04/26  15:50:15  dbc
% Properly support application of `size' to expressions.
% Support new form of `idxRef' node, with size field.
% Print linear representations of subscripts, embedding expressions, and
% index abbreviations.
% Delete code for printing obsolete cases of expressions (`equal', `map',
% `diff', `add1', ...).
%
% Revision 2.2  1994/04/15  13:43:13  dbc
% Support revision 2.2 of type-checker.
%
% Revision 2.1  1994/04/11  16:56:46  dbc
% Support elemental and array function reference nodes.
% Support `forall' and `arrall' nodes.
%
% Revision 1.1  1994/04/11  10:41:26  dbc
% Initial revision
%

% -------------------------------------------------------------

printMet(DHs, Syms) :-
    nl,
    printProgram(DHs, [], Syms, 8).

printProgram(DHs, SHs, Syms, Indent) :-
    printDeclarationHandles(DHs, Syms, Indent),
    printExpressionHandles(SHs, Syms, Indent, nolins).

printDeclarationHandles([], _, _).
printDeclarationHandles([DH | DHs], Syms, Indent) :-
    printDeclarationHandle(DH, Syms, Indent),
    printDeclarationHandles(DHs, Syms, Indent).

printDeclarationHandle(DH, Syms, Indent) :-
    printSHandle(DH),
    symLookUp(DH, D, Syms),
    printDeclaration(D, Syms, Indent).

printDeclaration(variable(Atr), Syms, Indent) :-
    printTerm(variable, Indent), nl,
    indent(Indent1, Indent),
    varAtr(Atr),
      %IHs := Atr -> indices,
      EHs     := Atr -> abbrevs,
      MapDesc := Atr -> mapDesc,
      %M      := Atr -> mapping,
      % Binding := Atr -> binding,
      Shape   := Atr -> shape,
    printShape(Shape, EHs, Syms, Indent1),
    printMapDesc(MapDesc, Syms, Indent1).
    %printMapping(M, Syms, Indent1).
printDeclaration(function(Atr), _, Indent) :-
    printTerm(function, Indent), nl,
    indent(Indent1, Indent),
    funAtr(Atr),
      Syms1 := Atr -> syms,
      DHs   := Atr -> declarations, SHs  := Atr -> statements,
      AHs   := Atr -> dummies,      RH   := Atr -> result,
      % Class := Atr -> class,
      AShps := Atr -> dumShps,      RShp := Atr -> resShp,
      AMaps := Atr -> dumMaps,      RMap := Atr -> resMap,
      DumAlnGrps := Atr -> dumAlnGrps, ResAlnGrp := Atr -> resAlnGrp,
    printProgram(DHs, SHs, Syms1, Indent1),
    printDums(AHs, AShps, AMaps, 1, Indent1),
    printDum(RH, RShp, RMap, result, Indent1),
    printTerm(DumAlnGrps, Indent1), nl,
    printTerm(ResAlnGrp, Indent1), nl.
printDeclaration(expression(E, Atr), Syms, Indent) :-
    printTerm(abbrev, Indent), nl,
    indent(Indent1, Indent),
    printExpression(E, Atr, Syms, Indent1).

printDums([], [], [], _, _).
printDums([AH | AHs], [AShp | AShps], [AMap | AMaps], N, Indent) :-
    printDum(AH, AShp, AMap, arg(N), Indent),
    N1 is N + 1,
    printDums(AHs, AShps, AMaps, N1, Indent).

printDum(H, Shp, Map, Name, Indent) :-
    printTerm(Name, Indent),
    printString(" "),
    printSHandle(H),
    printString(" "),
    print(Shp),
    printString(" "),
    print(Map),
    nl.
    

printShape(Shape, EHs, Syms, Indent) :-
    printExpressionHandles(Shape, Syms, Indent, nolins),
    printIndexAbbrevs(EHs, Syms, Indent).

printIndexAbbrevs([], _, _).
printIndexAbbrevs([EH | EHs], Syms, Indent) :-
    printIndexAbbrev(EH, Syms, Indent),
    printIndexAbbrevs(EHs, Syms, Indent).

printIndexAbbrev(EH, Syms, Indent) :-
    printTerm(abbrev, Indent), nl,
    indent(Indent1, Indent),
    printExpressionHandle(EH, Syms, Indent1, nolins).
    %printExpressionHandle(EH, Syms, Indent1, lins).

printRange(SizeH, Syms, Indent) :-
    printExpressionHandle(SizeH, Syms, Indent, nolins).


printMapDesc(align(Template, IdxMapDescs, EmbedDescs), Syms, Indent) :-
    printTerm(align, Indent), printString(" "), print(Template), nl,
    indent(Indent1, Indent),
    indent(Indent2, Indent1),
    (IdxMapDescs = [], !,
      true
    |true,
      printTerm(mappings, Indent1), nl,
      printIdxMapDescs(IdxMapDescs, Syms, Indent2)),
    (EmbedDescs = [], !,
      true
    |true,
      printTerm(embeddings, Indent1), nl,
      printEmbedDescs(EmbedDescs, Syms, Indent2)).
printMapDesc(distribute, _, Indent) :-
    printTerm(distribute, Indent), nl.
printMapDesc(def, _, _).

printIdxMapDescs([], _, _).
printIdxMapDescs([IdxMapDesc | IdxMapDescs], Syms, Indent) :-
    printIdxMapDesc(IdxMapDesc, Syms, Indent),
    printIdxMapDescs(IdxMapDescs, Syms, Indent).

printIdxMapDesc(map(MH, CH) :: D, Syms, Indent) :-
    printTerm(map, Indent), printString(" "), print(D), nl,
    indent(Indent1, Indent),
    printExpressionHandle(MH, Syms, Indent1, nolins),
    printExpressionHandle(CH, Syms, Indent1, nolins).
printIdxMapDesc(id :: D, _, Indent) :-
    printTerm(id, Indent), printString(" "), print(D), nl.
printIdxMapDesc(col, _, Indent) :-
    printTerm(col, Indent), nl.

printEmbedDescs([], _, _).
printEmbedDescs([EmbedDesc | EmbedDescs], Syms, Indent) :-
    printEmbedDesc(EmbedDesc, Syms, Indent),
    printEmbedDescs(EmbedDescs, Syms, Indent).

printEmbedDesc(emb(EH) :: D, Syms, Indent) :-
    printTerm(emb, Indent), printString(" "), print(D), nl,
    indent(Indent1, Indent),
    printExpressionHandle(EH, Syms, Indent1, nolins).
printEmbedDesc(rep :: D, _, Indent) :-
    printTerm(rep, Indent), printString(" "), print(D), nl.


printMapping(align(V, Embs), Syms, Indent) :-
    printTerm(align, Indent), printString(" "), print(V), nl,
    indent(Indent1, Indent),
    printEmbeddings(Embs, Syms, Indent1).
printMapping(distribute, _, Indent) :-
    printTerm(distribute, Indent), nl.
printMapping(def, _, _).


printExpressionHandles([], _, _, _).
printExpressionHandles([EH | EHs], Syms, Indent, Opts) :-
    printExpressionHandle(EH, Syms, Indent, Opts),
    printExpressionHandles(EHs, Syms, Indent, Opts).

printExpressionHandle(EH, Syms, Indent, Opts) :-
    printSHandle(EH),
    symLookUp(EH, expression(E, Atr), Syms),
    printExpression(E, Atr, Syms, Indent),
    (Opts = lins, !,
      expAtr(Atr),
	LinSet := Atr -> linSet,
      indent(Indent1, Indent),
      printLinSet(LinSet, Syms, Indent1)
    |true,
      true).

printExpression(literal(L), _, _, Indent) :-
    printTerm(literal(L), Indent), nl.
printExpression(varRef(VH), _, _, Indent) :-
    printTerm(varRef, Indent), printString(" "), printSHandle(VH), nl.
printExpression(idxRef(SizeH, IH), _, Syms, Indent) :-
    printTerm(idxRef, Indent), printString(" "), printIHandle(IH), nl,
    indent(Indent1, Indent),
    printExpressionHandle(SizeH, Syms, Indent1, nolins).
printExpression(funRef(FH, Tag, EHs), Atr, Syms, Indent) :-
    expAtr(Atr),
      Tests := Atr -> assertions,
    printTerm(funRef, Indent), printString(" "),
    (Tag = user, !, printSHandle(FH) | print(Tag)), nl,
    indent(Indent1, Indent),
    printExpressionHandles(EHs, Syms, Indent1, nolins),
    printTests(Tests, Syms, Indent1).
printExpression(subscript(EH, EHs), _, Syms, Indent) :-
    printTerm(subscript, Indent), nl,
    indent(Indent1, Indent),
    printExpressionHandle(EH, Syms, Indent1, nolins),
    printExpressionHandles(EHs, Syms, Indent1, lins).
printExpression(forall(_, Shape, AHs, EHs), _, Syms, Indent) :-
    printTerm(forall, Indent), nl,
    indent(Indent1, Indent),
    printShape(Shape, AHs, Syms, Indent1),
    printExpressionHandles(EHs, Syms, Indent1, nolins).
printExpression(arrall(_, Shape, EH), _, Syms, Indent) :-
    printTerm(arrall, Indent), nl,
    indent(Indent1, Indent),
    printShape(Shape, [], Syms, Indent1),
    printExpressionHandle(EH, Syms, Indent1, nolins).
printExpression(size(N, EH), _, Syms, Indent) :-
    printTerm(size, Indent), printString(" "),
    print(N), printString(" "), nl,
    indent(Indent1, Indent),
    printExpressionHandle(EH, Syms, Indent1, nolins).
printExpression(any, _, _, Indent) :-
    printTerm(any, Indent), nl.
printExpression(E, _, _, Indent) :-  % debug
    printTerm(E, Indent), nl.


printTests([], _, _) :- !.  % (cut so stops here if `Tests' uninstantiated).
printTests(EHs, Syms, Indent) :-
    printTerm(assert, Indent), nl,
    indent(Indent1, Indent),
    printExpressionHandles(EHs, Syms, Indent1, nolins).
   
printLinSet([], _, _) :- !.  % (cut so stops here if `LinSet' uninstantiated).
printLinSet(LinSet, Syms, Indent) :-
    printTerm(linear, Indent), nl,
    indent(Indent1, Indent),
    printLins(LinSet, Syms, Indent1).

printLins([], _, _).
printLins([Lin | Lins], Syms, Indent) :-
    printLin(Lin, Syms, Indent),
    printLins(Lins, Syms, Indent).

printLin(map(SizeH, MH, CH, IH), Syms, Indent) :-
    printTerm(map, Indent), nl,
    indent(Indent1, Indent),
    printExpressionHandles([SizeH, MH, CH], Syms, Indent1, nolins),
    printTerm(idx, Indent1), printString(" "), printIHandle(IH), nl.

printEmbeddings([], _, _).
printEmbeddings([Emb | Embs], Syms, Indent) :-
    printEmbedding(Emb, Syms, Indent),
    printEmbeddings(Embs, Syms, Indent).


printEmbedding(rep,   _, Indent) :- !, printTerm(replicated, Indent), nl.
printEmbedding(EH, Syms, Indent) :-
    printExpressionHandle(EH, Syms, Indent, lins).


printSHandles([]).
printSHandles([AH | AHs]) :-
    printSHandle(AH),
    printString(" "),
    printSHandles(AHs).

printSHandle(handle(I, J)) :- print(s(I, J)).


printIHandles([]).
printIHandles([IH | IHs]) :-
    printIHandle(IH),
    printString(" "),
    printIHandles(IHs).

printIHandle(handle(I, J)) :- print(i(I, J)).


printTerm(Term, Indent) :-
    current_output(Op),
    line_position(Op, P),
    S is Indent - P,
    tab(S),
    print(Term).

indent(Indent1, Indent) :- Indent1 is Indent + 2.

