1/*****************************************************************************
    2 * This file is part of the Prolog Development Tool (PDT)
    3 * 
    4 * Author: Andreas Becker, Ilshat Aliev
    5 * WWW: http://sewiki.iai.uni-bonn.de/research/pdt/start
    6 * Mail: pdt@lists.iai.uni-bonn.de
    7 * Copyright (C): 2013, CS Dept. III, University of Bonn
    8 * 
    9 * All rights reserved. This program is  made available under the terms
   10 * of the Eclipse Public License v1.0 which accompanies this distribution,
   11 * and is available at http://www.eclipse.org/legal/epl-v10.html
   12 * 
   13 ****************************************************************************/
   14
   15:- module(util_for_graphML, [
   16	predicate_in_file/4,
   17	file_of_predicate/4,
   18	main_module_of_file/2,
   19	first_line_of_predicate_in_file/5,
   20	exported_predicate/3,
   21	exported_predicate/2,
   22	locally_dead_predicate/3,
   23	call_term_position/7
   24]).   25
   26:- use_module(library(lists)).   27:- use_module(pdt_prolog_library(utils4modules_visibility)).   28:- use_module(pdt_common_pl('callgraph/pdt_call_graph')).   29:- use_module(pdt_prolog_library(compatibility), [
   30	pdt_source_file/2
   31]).   32
   33predicate_in_file(File, Module, Name, Arity) :-
   34	pdt_source_file(Module:Head, File),
   35	functor(Head, Name, Arity),
   36	\+ find_blacklist(Name, Arity, Module).
   37
   38find_blacklist('$load_context_module',2,_).
   39find_blacklist('$load_context_module',3,_).
   40find_blacklist('$mode',2,_).
   41find_blacklist('$pldoc',4,_).
   42
   43
   44file_of_predicate(Module, Name, Arity, File) :-
   45	functor(Head, Name, Arity),
   46	(	predicate_property(Module:Head, multifile)
   47	->	defined_in_files(Module, Name, Arity, Locations),
   48		member(File-_, Locations)
   49	;	(	predicate_property(Module:Head, file(File))
   50		->	true
   51		;	module_property(Module, file(File))
   52		)
   53	).
   54
   55main_module_of_file(File, Module) :-
   56	module_property(Module, File),
   57	\+ atom_concat(plunit_, _, Module),
   58	!.
   59
   60main_module_of_file(_File, user).
   61
   62first_line_of_predicate_in_file(Module, Name, Arity, File, Line) :-
   63	functor(Head, Name, Arity),
   64	(	predicate_property(Module:Head, multifile)
   65	->	defined_in_files(Module, Name, Arity, Locations),
   66		member(File-LineAndRefs, Locations),
   67		findall(L, member(location(L, _), LineAndRefs), Ls),
   68		min_list(Ls, Line)
   69	;	(	predicate_property(Module:Head, line_count(Line))
   70		->	true
   71		;	Line = 1
   72		)
   73	).
   74		
   75
   76exported_predicate(Module, Name, Arity) :-
   77	functor(Head, Name, Arity),
   78	exported_predicate(Module, Head).
   79
   80exported_predicate(Module, Head) :-
   81	(	Module == user
   82	;	predicate_property(Module:Head, exported)
   83	),
   84	!.
   85
   86locally_dead_predicate(Module, Name, Arity) :-
   87	locally_dead_predicate(Module, Name, Arity, [Module:Name/Arity]).
   88
   89locally_dead_predicate(Module, Name, Arity, _Visited):-
   90	uncalled_local_predicate(Module, Name, Arity).
   91locally_dead_predicate(Module, Name, Arity, Visited):-
   92	\+ exported_predicate(Module, Name, Arity),
   93	forall((
   94		calls(Module, Name, Arity, CallerModule, CallerName, CallerArity, _NumberOfCalls),
   95		\+ member(CallerModule:CallerName/CallerArity, Visited)
   96	),(
   97		locally_dead_predicate(CallerModule, CallerName, CallerArity, [CallerModule:CallerName/CallerArity | Visited])
   98	)).
   99			
  100uncalled_local_predicate(Module, Name, Arity):-
  101	uncalled_predicate(Module, Name, Arity),
  102	\+ exported_predicate(Module, Name, Arity).
  103
  104uncalled_predicate(Module, Name, Arity):-
  105	declared_in_module(Module, Name, Arity, _),
  106	\+ calls(Module, Name, Arity, _, _, _, _).
  107
  108assert_location(_, _, clause_term_position(_Ref, TermPosition), _) :-
  109	asserta(location(TermPosition)).
  110
  111:- dynamic(location/1).  112
  113call_term_position(SourceModule, SourceFunctor, SourceArity, TargetModule, TargetFunctor, TargetArity, Position) :-
  114	retractall(location(_)),
  115	functor(Target, TargetFunctor, TargetArity),
  116	pdt_walk_code([trace_reference(TargetModule:Target), predicates([SourceModule:SourceFunctor/SourceArity]), on_trace(util_for_graphML:assert_location)]),
  117	location(TermPosition),
  118	!,
  119	(	TermPosition = term_position(Start, End, _, _, _)
  120	;	TermPosition = Start-End
  121	),
  122	format(atom(Position), '~w-~w', [Start, End])