solve_ins(InFile):- write(user,'solving ... '),writeln(user,InFile), atom_codes(InFile,InFileCodes), append(InFileCodes,"_out",OutFileCodes), atom_codes(OutFile,OutFileCodes), solve(InFile,OutFile). solve(InFile,OutFile):- open(InFile,read,Sread), set_input(Sread), read_atoms(As), close(Sread), open(OutFile,write,Swrite), set_output(Swrite), solve(As), close(Swrite). read_atoms(InFile,As):- open(InFile,read,Sread), set_input(Sread), read_atoms(As), close(Sread). read_atoms(As):- read(A), read_atoms_aux(A,As). % Note that a list is read if . is not followed by a space. read_atoms_aux(end_of_file,As):-!, As=[]. read_atoms_aux(As0,As):-As0=[_|_],!, append_facts(As0,As,AsR), read(NextA), read_atoms_aux(NextA,AsR). read_atoms_aux(A,[A|As]):- read(NextA), read_atoms_aux(NextA,As). append_facts([],As,AsR):-!,As=AsR. append_facts([F|Fs],As,AsR):-!, append_facts(F,As,As1), append_facts(Fs,As1,AsR). append_facts(F,[F|As],As). assert_facts([]). assert_facts([A|As]):- assertz(A), assert_facts(As). % get_largest_atom(As,A): A is the largest unifying atom in As (using @> in comparison) get_largest_atom([A0|As],A):- A ?= A0,!, get_largest_atom(As,A0,A). get_largest_atom([_|As],A):- get_largest_atom(As,A). get_largest_atom([],A,A). get_largest_atom([A1|As],A0,A):- A ?= A1, A1 @> A0,!, get_largest_atom(As,A1,A). get_largest_atom([_|As],A0,A):- get_largest_atom(As,A0,A). % map atoms to and from integers using an association list map(X,Y,Map):-var(Map),!, map_build(X,Y,Map). map(X,Y,Map):- map_get(X,Y,Map). map([],_,[],[]). map([A|As],I,[I|Bs],[(A,I)|Map]):- I1 is I+1, map(As,I1,Bs,Map). map_build([],[],[]). map_build([A|As],[B|Bs],[(A,B)|Map]):- map_build(As,Bs,Map). map_get([],[],_):-!. map_get([A|As],[B|Bs],Map):-!, map_get(A,B,Map), map_get(As,Bs,Map). map_get(A,B,Map):- member((A,B),Map),!. % close a incomplete list closetail(L):-var(L),!,L=[]. closetail([_|L]):-closetail(L). %% A naive implementation. A faster implementation should extract %% global serialized(Starts,Durations) constraints post_disjunctive_tasks([]). post_disjunctive_tasks([disj_tasks(S1,D1,S2,D2)|Disjs]):- (S1+D1 #=< S2) #\/ (S2+D2 #=< S1), post_disjunctive_tasks(Disjs). %% A naive implementation. A faster implementation should extract %% global all_distinct(Vs) constraints post_neqs([]). post_neqs([X #\= Y|Neqs]):- X #\= Y, post_neqs(Neqs). a3_new(A,N1,N2,N3):- var(A),integer(N1),integer(N2),integer(N3),N1>0,N2>0,N3>0,!, functor(A,'$array',N1), foreach(I in 1..N1,[SubA],(arg(I,A,SubA),a2_new(SubA,N2,N3))). a3_new(A,N1,N2,N3):- throw(illegal_argument(a3_new(A,N1,N2,N3))). a3_get(A,I,J,K,Aijk):- % allows functional notations I1 is I, J1 is J, K1 is K, arg(I1,A,Ai), arg(J1,Ai,Aij), arg(K1,Aij,Aijk). %% 2-dimensional array a2_new(A,N1,N2):- var(A),integer(N1),integer(N2),N1>0,N2>0,!, functor(A,'$array',N1), foreach(I in 1..N1,[SubA],(arg(I,A,SubA),functor(SubA,'$array',N2))). a2_new(A,N1,N2):- throw(illegal_argument(a2_new(A,N1,N2))). a2_get(A,I,J,Aij):- % allows functional notations I1 is I, J1 is J, arg(I1,A,Ai), arg(J1,Ai,Aij). %%% foreach (simple iterators for Prolog) foreach(Iterators,Goal):- foreach(Iterators,true,[],Goal,[]). foreach(Iterators,LVars,Goal):- foreach(Iterators,true,LVars,Goal,[]). foreach((I,Is),IsRest,LVars,Goal,Map):-!, (IsRest==true->IsRest1=Is;IsRest1=(Is,IsRest)), foreach(I,IsRest1,LVars,Goal,Map). foreach(Var in L..U,IsRest,LVars,Goal,Map):-!, replace_local_var(L,L1,Map), replace_local_var(U,U1,Map), L2 is L1, U2 is U1, foreach_range(Var,L2,U2,IsRest,LVars,Goal,Map). foreach(Var in Lst,IsRest,LVars,Goal,Map):-Lst=[_|_],!, foreach_list(Var,Lst,IsRest,LVars,Goal,Map). foreach(true,true,LVars,Goal,Map):-!, replace_local_var(Goal,Goal1,LVars,Map,_), call(Goal1). foreach(true,Is,LVars,Goal,Map):- foreach(Is,true,LVars,Goal,Map). foreach_range(_Var,L,U,_IsRest,_LVars,_Goal,_Map):-L>U,!. foreach_range(Var,L,U,IsRest,LVars,Goal,Map):- foreach(IsRest,true,LVars,Goal,[(Var,L)|Map]), L1 is L+1, foreach_range(Var,L1,U,IsRest,LVars,Goal,Map). foreach_list(_Var,[],_IsRest,_LVars,_Goal,_Map). foreach_list(Var,[E|Es],IsRest,LVars,Goal,Map):- replace_local_var(E,E1,Map), foreach(IsRest,true,LVars,Goal,[(Var,E1)|Map]), foreach_list(Var,Es,IsRest,LVars,Goal,Map). replace_local_var(Term,Term1,Map):- replace_local_var(Term,Term1,[],Map,_). replace_local_var(Term,NTerm,LVars,Map,NMap):-var(Term),!, (lookup_map(Term,NTerm,Map)->NMap=Map; membchk(Term,LVars)->NMap=[(Term,NTerm)|Map]; NTerm=Term,NMap=Map). replace_local_var(Term,NTerm,_LVars,Map,NMap):- atomic(Term),!,NTerm=Term,NMap=Map. replace_local_var([E|Es],[E1|Es1],LVars,Map,NMap):-!, replace_local_var(E,E1,LVars,Map,Map1), replace_local_var(Es,Es1,LVars,Map1,NMap). replace_local_var(Term,NTerm,_LVars,Map,NMap):- is_array(Term),!, NTerm=Term,NMap=Map. replace_local_var(Term,NTerm,_LVars,Map,NMap):- is_hashtable(Term),!, NTerm=Term,NMap=Map. replace_local_var(Term,NTerm,LVars,Map,NMap):- functor(Term,F,N), functor(NTerm,F,N), replace_local_var(Term,NTerm,LVars,Map,NMap,1,N). replace_local_var(_Term,_NTerm,_LVars,Map,NMap,I,N):-I>N,!,NMap=Map. replace_local_var(Term,NTerm,LVars,Map,NMap,I,N):- arg(I,Term,A), arg(I,NTerm,NA), replace_local_var(A,NA,LVars,Map,Map1), I1 is I+1, replace_local_var(Term,NTerm,LVars,Map1,NMap,I1,N). lookup_map(Term,NTerm,[(Term1,NTerm1)|_]):- Term==Term1,!, NTerm=NTerm1. lookup_map(Term,NTerm,[_|Map]):- lookup_map(Term,NTerm,Map).