out-paccs.pl 3.12 KB
% == No, Emacs this is -*-Prolog-*- code, not what you thought... =============

% == Code generation for PaCCS ================================================

cg_emit(fzn(preds(PS), vars(VS), constrs(CS), G), ST) :-
    cg_prefix(TEXT, PTXT),
    cg_preds(PS, ST, PTXT, VTXT1),
    cg_vars(decl, VS, ST, VTXT1, VTXT2),
    cg_vars(init, VS, ST, VTXT2, CTXT),
    %% cg_constrs(CTXT, GTXT, CS, ST),
    %% cg_goal(GTXT, STXT, G, VS, ST),
    %% cg_suffix(STXT, []),
    cg_suffix(CTXT, []),
    format("~s\n", [TEXT]).

% == DCGs for code generation =================================================

% -- predicates ---------------------------------------------------------------

cg_preds(_PS, _ST) --> [].

% -- variables ----------------------------------------------------------------

cg_vars(OP,  [V|Vs], ST) --> cg_var(OP, V, ST), cg_vars(OP, Vs, ST).
cg_vars(_OP, [], _) --> [].

cg_var(OP, var(N,int,I,A), ST) --> 
    cg_var(OP, var(N,int(1,999),I,A), ST). % FIXME

cg_var(decl, var(N,int(LB,UB),_I,_A), _ST) -->
    { format_to_codes(S, "  fd_int ~w = fd_new(~d, ~d);\n", [N, LB, UB]) },
    S.

cg_var(init, var(_,int(_,_),_,_), _) --> [].

% -- array of variables - - - - - - - - - - - - - - - - - - - - - - - - - - - -

cg_var(decl, var(N,array(_T,LB,UB),[],_), _ST) --> !,
    { SZ is UB-LB+1,
      format_to_codes(S, "  fd_int ~w[~d];\n", [N, SZ]) },
    S.

cg_var(init, var(N,array(T,ALB,AUB),[],_), _ST) --> !,
    { SZ is AUB-ALB+1, bound(lb, T, LB), bound(ub, T, UB) },
    { format_to_codes(S1, "  for (i=0; i<~d; ++i)\n", [SZ]) }, S1,
    { format_to_codes(S2, "    ~w[i] = fd_new(~d, ~d);\n", [N, LB, UB]) }, S2.

% -- array of constants - - - - - - - - - - - - - - - - - - - - - - - - - - - -

cg_var(decl, var(N,array(_T,LB,UB),lit(INIT,array(_)),_), _ST) --> 
    { nonvar(INIT), INIT=[_|_] }, !,
    { SZ is UB-LB+1,
      format_to_codes(S, "  int ~w[~d] = {\n", [N, SZ]) },
    S,
    cg_constant_list(INIT, "    "),
    " };\n".

cg_var(init, var(_N,array(_T,_LB,_UB),lit(INIT,array(_)),_), _ST) -->
    { nonvar(INIT), INIT=[_|_] }, !,
    [].


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

cg_constant_list([], _) --> [].
cg_constant_list([C|Cs], PFX) --> 
    PFX, cg_constant(C),
    cg_constant_list(Cs, ", ").

cg_constant(lit(N,int)) --> { format_to_codes(S, "~w", [N]) }, S.

% -- constraints --------------------------------------------------------------

cg_constrs([C|Cs], ST) --> cg_constr(C, ST), cg_constrs(Cs, ST).
cg_constrs([], _) --> [].

cg_constr(_C, _ST) --> [].	% FIXME: temporary

% -- goal ---------------------------------------------------------------------

cg_goal(satisfy, VS, ST) --> 
    "\n",
    "  if (fd_solve()) {\n",
    cg_var_print(VS, ST, "    "),
    "  }\n".

cg_var_print([], _, _) --> [].
cg_var_print([var(N,_,_,A)|Vs], ST, PFX) -->
    { member(output, A), ! },
    { format_to_codes(S, "~sfd_println(~s);\n", [PFX, N]) }, S,
    cg_var_print(Vs, ST, PFX).
cg_var_print([_|Vs], ST, PFX) --> cg_var_print(Vs, ST, PFX).


% -- prefix and suffix --------------------------------------------------------

cg_prefix -->
    "{\n",
    "  int i, j;\n".

cg_suffix -->
    "}\n".