/* A converter for transforming the problem format of CP'05 into Prolog format */ /* by Neng-Fa Zhou, June 6, 2006, */ :-include('$BPDIR/Tools/xml.pl'). % Available at: http://www.probp.com/publib/xml.html main:- get_main_args(L), process_args(L,BaseName), xcsp2pl(BaseName). process_args([],InFile):-format("usage: convert FileName",[]),halt. process_args([BaseName|_],BaseName). xcsp2pl(File):- %File is a base name % writeln(user,converting(File)), atom_codes(File,MainString), append(MainString,".xml",InFileString), atom_codes(InFile,InFileString), append(MainString,".pl",OutFileString), atom_codes(OutFile,OutFileString), (exists(InFile)->true;format("File not found:~w~n",[InFile]),halt), readFile(InFile,Codes), xml_parse(Codes, Document),!, garbage_collect, tell(OutFile), process_xml(Document), told. % xml_pp(Document). process_xml(xml(Attrs,[Instance|_])):-true : process_instance(Instance). process_instance(element(_instance,Attrs,InstanceElms)):-true : format("comp_problem(Vs):-~n"), new_hashtable(VarsTab), process_instance_elms(InstanceElms,VarsTab,Preds), format("~ttrue.~n",[]). process_instance_elms([],VarsTab,Preds):-true : true. process_instance_elms([element(presentation,_Attrs,_)|Elms],VarsTab,Preds):-true : % ignor this elm process_instance_elms(Elms,VarsTab,Preds). process_instance_elms([element(domains,DomainsAttrs,DomElms)|Elms],VarsTab,Preds):-true : % ignor this elm process_dom_elms(DomElms), process_instance_elms(Elms,VarsTab,Preds). process_instance_elms([element(variables,VariabelsAttrs,VarElms)|Elms],VarsTab,Preds):-true : % ignor this elm process_var_elms(VarElms,Vars,VarsTab), format("~tVs=[~@],~n",[output_vars(Vars)]), process_instance_elms(Elms,VarsTab,Preds). process_instance_elms([element(relations,RelationsAttrs,RelElms)|Elms],VarsTab,Preds):-true : % ignor this elm process_rel_elms(RelElms), process_instance_elms(Elms,VarsTab,Preds). process_instance_elms([element(predicates,PredicatesAttrs,PredElms)|Elms],VarsTab,Preds):-true : % ignor this elm process_pred_elms(PredElms,Preds), process_instance_elms(Elms,VarsTab,Preds). process_instance_elms([element(constraints,ConstraintsAttrs,ConsElms)|Elms],VarsTab,Preds):-true : % ignor this elm process_cons_elms(ConsElms,VarsTab,Preds), process_instance_elms(Elms,VarsTab,Preds). process_instance_elms([Element|Elms],VarsTab,Preds):-true : throw(invalid_instance_element(Element)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_dom_elms([]):-true : true. process_dom_elms([element(_domain,Attrs,[pcdata(Dom)|_])|Elms]):-true : member(name=DName,Attrs),!, tokenize(Dom,Tokens), extract_dom_items(Tokens,Items), format("~tD~s=~w,~n",[DName,Items]), process_dom_elms(Elms). extract_dom_items([],Items):-true : Items=[]. extract_dom_items([X,'.','.',Y|Tokens],Items):-true : Items=[X..Y|ItemsR], extract_dom_items(Tokens,ItemsR). extract_dom_items([X|Tokens],Items):-true : Items=[X|ItemsR], extract_dom_items(Tokens,ItemsR). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_var_elms([],Vars,VarsTab):-true : Vars=[]. process_var_elms([element(_variable,Attrs,_)|Elms],Vars,VarsTab):-true : member(name=VNameCodes,Attrs), member(domain=DNameCodes,Attrs),!, name(VName,VNameCodes), name(DName,DNameCodes), hashtable_put(VarsTab,VName,DName), Vars=[VName|VarsR], format("~tV~w :: D~w,~n",[VName,DName]), process_var_elms(Elms,VarsR,VarsTab). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_rel_elms([]):-true : true. process_rel_elms([element(_relation,Attrs,[])|RelElms]):-true : member(name=NameCodes,Attrs),!, Tuples=[], NCodes="0", (member(semantics="supports",Attrs)->RelType=support_rel;RelType=conflict_rel), format("~t~w(Rel~s,~w,~s),~n",[RelType,NameCodes,Tuples,NCodes]), process_rel_elms(RelElms). process_rel_elms([element(_relation,Attrs,[pcdata(RelData)|_])|RelElms]):-true : tokenize(RelData,Tokens), extract_tuples(Tokens,Tuples), member(name=NameCodes,Attrs), member(nbTuples=NCodes,Attrs),!, (member(semantics="supports",Attrs)->RelType=support_rel;RelType=conflict_rel), format("~t~w(Rel~s,~w,~s),~n",[RelType,NameCodes,Tuples,NCodes]), process_rel_elms(RelElms). extract_tuples([],Tuples):-true : Tuples=[]. extract_tuples(Tokens,Tuples):-true : Tuples=[Tuple|Tuples1], extract_tuple(Tokens,Tokens1,Tuple), extract_tuples(Tokens1,Tuples1). extract_tuple([],TokensR,Tuple):-true : TokensR=[],Tuple=[]. extract_tuple(['|'|Tokens],TokensR,Tuple):-true : Tokens=TokensR,Tuple=[]. extract_tuple([Token|Tokens],TokensR,Tuple):-true : Tuple=[Token|TupleR], extract_tuple(Tokens,TokensR,TupleR). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_cons_elms([],VarsTab,Preds):-true : true. process_cons_elms([element(_constraint,Attrs,[])|ConsElms],VarsTab,Preds):-true ? member(reference="global:allDifferent",Attrs),!, member(scope=Scode,Attrs),!, tokenize(Scode,ActualArgs), % format("~tconstr_scope([~@]),~n",[output_vars(ActualArgs)]), format("~tcall_all_distinct([~@]),~n",[output_vars(ActualArgs)]), process_cons_elms(ConsElms,VarsTab,Preds). process_cons_elms([element(_constraint,Attrs,SumElms)|ConsElms],VarsTab,Preds):-true ? member(reference="global:weightedSum",Attrs),!, member(scope=Scode,Attrs),!, tokenize(Scode,ActualArgs), format("~tconstr_scope([~@]),~n",[output_vars(ActualArgs)]), process_sum_params(SumElms), process_cons_elms(ConsElms,VarsTab,Preds). process_cons_elms([element(_constraint,Attrs,[])|ConsElms],VarsTab,Preds):-true : % extension member(scope=Scode,Attrs), member(reference=PName,Attrs),!, tokenize(Scode,ActualArgs), % format("~tconstr_scope([~@]),~n",[output_vars(ActualArgs)]), retrieve_domains(ActualArgs,Domains,VarsTab), format("~textensional_constr(Rel~s,[~@],[~@]),~n",[PName,output_vars(ActualArgs),output_domains(Domains)]), process_cons_elms(ConsElms,VarsTab,Preds). process_cons_elms([element(_constraint,Attrs,[element(_,_,[pcdata(Params)|_])|_])|ConsElms],VarsTab,Preds):-true : member(scope=Scode,Attrs),!, tokenize(Scode,ScopeVars), format("~tconstr_scope([~@]),~n",[output_vars(ScopeVars)]), member(reference=PName,Attrs),!, member(pred(PName,FormalArgs,Body),Preds),!, % predicate, must exist tokenize(Params,ActualArgs), copy_term((FormalArgs,Body),(FormalArgsCp,BodyCp)), substitute_actual_for_formal(ActualArgs,FormalArgsCp), output_constrs(BodyCp), process_cons_elms(ConsElms,VarsTab,Preds). process_sum_params([element(_parameters,_Attrs,SumElms)|_]):-true : member(element(list,_,[pcdata(PCDCoeVarPairs)|_]),SumElms), member(element(op,_,[pcdata(PCDOP)|_]),SumElms), member(pcdata(PCDRHS),SumElms),!, tokenize(PCDCoeVarPairs,CoeVarPairs), tokenize(PCDOP,OPLst),OPLst=[OP|_], tokenize(PCDRHS,RHSLst),RHSLst=[RHS|_], format("~t",[]), output_coe_var_pairs(CoeVarPairs), output_op(OP), format("~w,~n",[RHS]). output_coe_var_pairs([Coe,Var]):-true : format("~w*V~w",[Coe,Var]). output_coe_var_pairs([Coe,Var|Rest]):-true : format("~w*V~w + ",[Coe,Var]), output_coe_var_pairs(Rest). output_op(eq):-true : format("#=",[]). output_op(neq):-true : format("#\\=",[]). output_op(gt):-true : format("#>",[]). output_op(ge):-true : format(">=",[]). output_op(lt):-true : format("#<",[]). output_op(le):-true : format("#=<",[]). substitute_actual_for_formal([],_):-true : true. substitute_actual_for_formal([ActualArg|ActualArgs],[V|Vs]):-integer(ActualArg) : V=ActualArg, substitute_actual_for_formal(ActualArgs,Vs). substitute_actual_for_formal([ActualArg|ActualArgs],[V|Vs]):-true : name(ActualArg,Codes), name(V,[0'V|Codes]), substitute_actual_for_formal(ActualArgs,Vs). output_vars([]):-true : true. output_vars([V|Vs]):-true : (integer(V)->format("~w",[V]);format("V~w",[V])), (Vs==[]->true; format(",",[]), output_vars(Vs)). output_domains([]):-true : true. output_domains([D|Ds]):-true : format("D~w",[D]), (Ds==[]->true; format(",",[]), output_domains(Ds)). output_constrs([]):-true : true. output_constrs([Constr|Constrs]):- format("~t~w,~n",[Constr]), output_constrs(Constrs). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_pred_elms([],Preds):-true : true. process_pred_elms([element(_predicate,Attrs,PredElms)|Elms],Preds):-true : member(name=PName,Attrs), member(element(parameters,_,[pcdata(Params)|_]),PredElms), member(element(expression,_,ExpElms),PredElms),!, % tokenize(Params,Tokens), process_params(Tokens,PredArgs,ArgsTab), % process_exp_elms(ExpElms,PredBody,ArgsTab), attach(pred(PName,PredArgs,PredBody),Preds), process_pred_elms(Elms,Preds). process_params([],PredArgs,ArgsTab):-true : PredArgs=[]. process_params([int,Arg|Tokens],PredArgs,ArgsTab):-true : PredArgs=[VArg|PredArgs1], attach(arg(Arg,VArg),ArgsTab), process_params(Tokens,PredArgs1,ArgsTab). process_exp_elms([],Constrs,_ArgsTab):-true : Constrs=[]. process_exp_elms([element(functional,_,[pcdata(Exp)|_])|Elms],Constrs,ArgsTab):-true : tokenize(Exp,Tokens), process_bool_exp(Tokens,[],Constr,ArgsTab), expand_and(Constr,Constrs,ConstrsR), process_exp_elms(Elms,ConstrsR,ArgsTab). expand_and((Constr1 #/\ Constr2),Constrs,ConstrsR):-true : expand_and(Constr1,Constrs,Constrs1), expand_and(Constr2,Constrs1,ConstrsR). expand_and(1,Constrs,ConstrsR):-true : Constrs=ConstrsR. expand_and(0,Constrs,ConstrsR):-true : Constrs=[fail|ConstrsR]. expand_and(Constr,Constrs,ConstrsR):-true : Constrs=[Constr|ConstrsR]. process_bool_exp([false|Tokens],TokensR,Constr,ArgsTab):-true : Constr=0,TokensR=Tokens. process_bool_exp([true|Tokens],TokensR,Constr,ArgsTab):-true : Constr=1,TokensR=Tokens. process_bool_exp([not,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_bool_exp(Tokens,Tokens1,Constr1,ArgsTab), Tokens1=[')'|TokensR], Constr=(#\ Constr1). process_bool_exp([and,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_bool_exp(Tokens,Tokens1,Constr1,ArgsTab), Tokens1=[','|Tokens2], process_bool_exp(Tokens2,Tokens3,Constr2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Constr1 #/\ Constr2). process_bool_exp([or,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_bool_exp(Tokens,Tokens1,Constr1,ArgsTab), Tokens1=[','|Tokens2], process_bool_exp(Tokens2,Tokens3,Constr2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Constr1 #\/ Constr2). process_bool_exp([xor,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_bool_exp(Tokens,Tokens1,Constr1,ArgsTab), Tokens1=[','|Tokens2], process_bool_exp(Tokens2,Tokens3,Constr2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Constr1 #\ Constr2). process_bool_exp([eq,'('|Tokens],TokensR,Constr,ArgsTab):-true : (process_bool_exp(Tokens,Tokens1,Constr1,ArgsTab)-> Tokens1=[','|Tokens2], process_bool_exp(Tokens2,Tokens3,Constr2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Constr1 #<=>Constr2) ; process_int_exp(Tokens,Tokens1,Exp1,ArgsTab),!, Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Exp1 #= Exp2) ). process_bool_exp([ne,'('|Tokens],TokensR,Constr,ArgsTab):-true : (process_bool_exp(Tokens,Tokens1,Constr1,ArgsTab)-> Tokens1=[','|Tokens2], process_bool_exp(Tokens2,Tokens3,Constr2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Constr1 #\= Constr2) ; process_int_exp(Tokens,Tokens1,Exp1,ArgsTab),!, Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Exp1 #\= Exp2) ). process_bool_exp([ge,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Exp1 #>= Exp2). process_bool_exp([gt,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Exp1 #> Exp2). process_bool_exp([le,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Exp1 #=< Exp2). process_bool_exp([lt,'('|Tokens],TokensR,Constr,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Constr=(Exp1 #< Exp2). process_int_exp([neg,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[')'|TokensR], Exp=(-Exp1). process_int_exp([abs,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[')'|TokensR], Exp=abs(Exp1). process_int_exp([add,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=(Exp1+Exp2). process_int_exp([sub,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=(Exp1-Exp2). process_int_exp([mul,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=(Exp1*Exp2). process_int_exp([div,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=(Exp1//Exp2). process_int_exp([mod,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=(Exp1 mod Exp2). process_int_exp([pow,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=(Exp1 ** Exp2). process_int_exp([min,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=min(Exp1,Exp2). process_int_exp([max,'('|Tokens],TokensR,Exp,ArgsTab):-true : process_int_exp(Tokens,Tokens1,Exp1,ArgsTab), Tokens1=[','|Tokens2], process_int_exp(Tokens2,Tokens3,Exp2,ArgsTab), Tokens3=[')'|TokensR], Exp=max(Exp1,Exp2). process_int_exp([Token|Tokens],TokensR,Exp,ArgsTab):-integer(Token) : Exp=Token, Tokens=TokensR. process_int_exp([Token|Tokens],TokensR,Exp,ArgsTab):-true : Tokens=TokensR, member(arg(Token,Exp),ArgsTab),!. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tokenize([],Tokens):-true : Tokens=[]. tokenize([Code|Codes],Tokens):-true ? is_space(Code),!, tokenize(Codes,Tokens). tokenize([Code|Codes],Tokens):-true ? is_delimeter(Code),!, char_code(Token,Code), Tokens=[Token|TokensR], tokenize(Codes,TokensR). tokenize([Code|Codes],Tokens):-true : extract_token(Codes,Name,CodesR), name(Token,[Code|Name]), Tokens=[Token|TokensR], tokenize(CodesR,TokensR). extract_token([],Name,CodesR):-true : Name=[],CodesR=[]. extract_token([Code|Codes],Name,CodesR):-true ? is_space(Code),!, Name=[], CodesR=Codes. extract_token(Codes,Name,CodesR):-Codes=[Code|_] ? is_delimeter(Code),!, Name=[], CodesR=Codes. extract_token([Code|Codes],Name,CodesR):-true : Name=[Code|NameR], extract_token(Codes,NameR,CodesR). :-mode is_space(+). is_space(0' ). is_space(9). % tab is_space(10). is_space(13). :-mode is_delimeter(+). is_delimeter(0'(). is_delimeter(0')). is_delimeter(0',). is_delimeter(0'.). is_delimeter(0'|). %%%% retrieve_domains([],Ds,VarsTab):-true : Ds=[]. retrieve_domains([V|Vs],Ds,VarsTab):-true : Ds=[D|Ds1], hashtable_get(VarsTab,V,D), retrieve_domains(Vs,Ds1,VarsTab).