% This is provides the Reach(able) vars in a Graph, when starting % for any in a Set of variables. The return vars are in the same % order as provided in the libary top_sort/2 predicate. % graph_variables_reach_ord( Set, Graph, Reach ) :- graph_variables_reach( Set, Graph, [], ReachSetOrd ), top_sort( Graph, TopOrder ), ord_set_narrows( TopOrder, ReachSetOrd, Reach ). ord_set_narrows( [], [], [] ). ord_set_narrows( [H|T], Set, Reach ) :- ( ord_del_element( Set, H, Red ) -> Reach = [H|TReach], ( Red == [] -> RemL = []; RemL = T ) ; Red = Set, Reach = TReach, RemL = [] ), ord_set_narrows( RemL, Red, TReach ). % graph_variables_reach( Vars, Graph, Acc, Reach ) :- % Reach are all the variables that are reachable from % some variable in Vars, according to the edges in Graph. % Intermediate results are held in the set Acc. % Currently Graph donot include no-edged vertices, % thus one has to protect reachable/3. % graph_variables_reach( [V|Vs], Graph, Acc, Reach ) :- ( reachable( V, Graph, VReach ) -> true ; VReach = [V] ), % append( VReach, Acc, NewAcc ), % merge_set( VReach, Acc, NewAcc ), % swi ? ord_union( VReach, Acc, NewAcc ), graph_variables_reach( Vs, Graph, NewAcc, Reach ). graph_variables_reach( [], _Graph, Acccumulated, Sorted ) :- list_to_ord_set( Acccumulated, Sorted ). % graph_add_constraint_many_to_one( Vars, Constr, DepVar, Graph, NewGraph ) :- graph_add_constraint_many_to_one( [], _Constr, _DepVar, Graph, Graph ). graph_add_constraint_many_to_one( [V|Vs], Constr, DepVar, Graph, NewGraph ) :- graph_add_constraint( V, Constr, DepVar, Graph, NxGraph ), graph_add_constraint_many_to_one( Vs, Constr, DepVar, NxGraph, NewGraph ). % graph_add_constraint( Var, _Constr, DepVar, Graph, NewGraph ) :- % an edge from DepVar to Var is added from Graph to NewGraph, % provisio that there is n't a path from Var to DepVar. % Constr is not used, But if both = and # would be later % supported, then one maybe able to weight the edges. % graph_add_constraint( Var, Constr, DepVar, Graph, NewGraph ) :- ( reachable(Var,Graph,VarReachesThese) -> true ; VarReachesThese = [] ), ( memberchk(DepVar,VarReachesThese) -> print_message( error, graph_cycle_while_adding(ind_var(Var),constr(Constr),dep_var(DepVar))) ; true ), add_edges( Graph, [DepVar-Var], NewGraph ).