<commit_before>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  
%  This file is part of Logtalk <http://logtalk.org/>
%  Copyright 1998-2016 <NAME> <<EMAIL>>
%  
%  Licensed under the Apache License, Version 2.0 (the "License");
%  you may not use this file except in compliance with the License.
%  You may obtain a copy of the License at
%  
%      http://www.apache.org/licenses/LICENSE-2.0
%  
%  Unless required by applicable law or agreed to in writing, software
%  distributed under the License is distributed on an "AS IS" BASIS,
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%  See the License for the specific language governing permissions and
%  limitations under the License.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


:- object(library_dependency_diagram(Format),
	imports(library_diagram(Format))).

	:- info([
		version is 2.0,
		author is '<NAME>',
		date is 2016/02/24,
		comment is 'Predicates for generating library dependency diagrams. A dependency exists when an entity in one library makes a reference to an entity in another library.',
		parnames is ['Format']
	]).

	:- uses(list, [
		member/2, memberchk/2
	]).

	% first, output the library node
	output_library(Library, Directory, Options) :-
		^^add_link_options(Directory, Options, LinkingOptions),
		(	memberchk(directory_paths(true), Options) ->
			memberchk(omit_path_prefixes(Prefixes), Options),
			(	member(Prefix, Prefixes),
				atom_concat(Prefix, Relative, Directory) ->
				^^output_node(Directory, Library, library, [Relative], library, LinkingOptions)
			;	^^output_node(Directory, Library, library, [Directory], library, LinkingOptions)
			)
		;	^^output_node(Directory, Library, library, [], library, LinkingOptions)
		),
		^^remember_included_library(Library, Directory),
		fail.
	% second, output edges for all libraries that this library refers to
	output_library(Library, Directory, Options) :-
		depends_library(Library, Directory, OtherLibrary, OtherDirectory, Kind, Options),
		% ensure that this dependency is not already recorded
		\+ ^^edge(Directory, OtherDirectory, _, _, _),
			(	Kind == module ->
				^^remember_referenced_prolog_library(OtherLibrary, OtherDirectory),
				^^save_edge(Directory, OtherDirectory, [depends], depends_on_library, [tooltip(depends)| Options])
			;	^^remember_referenced_logtalk_library(OtherLibrary, OtherDirectory),
				^^save_edge(Directory, OtherDirectory, [depends], depends_on_library, [tooltip(depends)| Options])
			),
		fail.
	output_library(_, _, _).

	depends_library(Library, Directory, OtherLibrary, OtherDirectory, Kind, _) :-
		(	object_property(Object, file(Basename, Directory)),
			depends_object(Object, Kind, Other)
		;	protocol_property(Protocol, file(Basename, Directory)),
			depends_protocol(Protocol, Kind, Other)
		;	category_property(Category, file(Basename, Directory)),
			depends_category(Category, Kind, Other)
		;	modules_diagram_support::module_property(Module, file(Basename, Directory)),
			depends_module(Module, Kind, Other)
		),
		entity_basename_directory(Kind, Other, OtherBasename, OtherDirectory),
		(	OtherBasename \== Basename ->
			true
		;	OtherDirectory \== Directory
		),
		atom_concat(OtherDirectory, OtherBasename, OtherPath),
		(	Kind == module ->
			modules_diagram_support::module_property(OtherLibrary, file(OtherPath))
		;	logtalk::loaded_file_property(OtherPath, library(OtherLibrary))
		),
		OtherLibrary \== Library.

	% sometimes a library is a wrapper for its sub-libraries without source files
	% on its own; use the relative paths to check for sub-libraries
	depends_library(Library, Directory, OtherLibrary, OtherDirectory, object, Options) :-
		logtalk_library_path(OtherLibrary, _),
		OtherLibrary \== Library,
		logtalk::expand_library_path(OtherLibrary, OtherDirectory),
		atom_concat(Directory, Relative, OtherDirectory),
		Relative \== '',
		% we have a sub-library
		output_library(OtherLibrary, OtherDirectory, Options).

	depends_object(Object, object, Other) :-
		object_property(Object, calls(Other::_,_)), nonvar(Other).
	depends_object(Object, module, Other) :-
		object_property(Object, calls(':'(Other,_),_)), nonvar(Other).
	depends_object(Object, object, Other) :-
		extends_object(Object, Other).
	depends_object(Object, object, Other) :-
		instantiates_class(Object, Other).
	depends_object(Object, object, Other) :-
		specializes_class(Object, Other).
	depends_object(Object, protocol, Other) :-
		implements_protocol(Object, Other).
	depends_object(Object, category, Other) :-
		imports_category(Object, Other).
	depends_object(Object, category, Other) :-
		complements_object(Other, Object).

	depends_protocol(Protocol, object, Other) :-
		extends_protocol(Protocol, Other).

	depends_category(Category, object, Other) :-
		category_property(Category, calls(Other::_,_)), nonvar(Other).
	depends_category(Category, module, Other) :-
		category_property(Category, calls(':'(Other,_),_)), nonvar(Other).
	depends_category(Category, category, Other) :-
		extends_category(Category, Other).
	depends_category(Category, protocol, Other) :-
		implements_protocol(Category, Other).

	depends_module(Module, object, Other) :-
		modules_diagram_support::module_property(Module, calls(Other::_,_)), nonvar(Other).
	depends_module(Module, module, Other) :-
		modules_diagram_support::module_property(Module, calls(':'(Other,_),_)), nonvar(Other).

	entity_basename_directory(object, Entity, Basename, Directory) :-
		object_property(Entity, file(Basename, Directory)).
	entity_basename_directory(protocol, Entity, Basename, Directory) :-
		protocol_property(Entity, file(Basename, Directory)).
	entity_basename_directory(category, Entity, Basename, Directory) :-
		category_property(Entity, file(Basename, Directory)).
	entity_basename_directory(module, Entity, Basename, Directory) :-
		modules_diagram_support::module_property(Entity, file(Basename, Directory)).

	% by default, diagram layout is top to bottom:
	default_option(layout(top_to_bottom)).
	% by default, diagram title is empty:
	default_option(title('')).
	% by default, print current date:
	default_option(date(true)).
	% by default, don't generate cluster, file, and entity URLs:
	default_option(url_prefixes('', '')).
	% by default, don't omit any path prefixes when printing paths:
	default_option(omit_path_prefixes([])).
	% by default, don't print directory paths:
	default_option(directory_paths(true)).
	% by default, print relation labels:
	default_option(relation_labels(true)).
	% by default, don't print node type captions
	default_option(node_type_captions(false)).
	% by default, write diagram to the current directory:
	default_option(output_directory('./')).
	% by default, don't exclude any library sub-directories:
	default_option(exclude_libraries([])).

	diagram_name_suffix('_library_dependency_diagram').

:- end_object.



:- object(library_dependency_diagram,
	extends(library_dependency_diagram(dot))).

	:- info([
		version is 2.0,
		author is '<NAME>',
		date is 2014/01/14,
		comment is 'Predicates for generating library dependency diagrams in DOT format.'
	]).

:- end_object.<commit_msg>Fix rendering bug in the new library dependency diagrams where sub-libraries would not have their own cluster<commit_after>%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  
%  This file is part of Logtalk <http://logtalk.org/>
%  Copyright 1998-2016 <NAME> <<EMAIL>>
%  
%  Licensed under the Apache License, Version 2.0 (the "License");
%  you may not use this file except in compliance with the License.
%  You may obtain a copy of the License at
%  
%      http://www.apache.org/licenses/LICENSE-2.0
%  
%  Unless required by applicable law or agreed to in writing, software
%  distributed under the License is distributed on an "AS IS" BASIS,
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%  See the License for the specific language governing permissions and
%  limitations under the License.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


:- object(library_dependency_diagram(Format),
	imports(library_diagram(Format))).

	:- info([
		version is 2.0,
		author is '<NAME>',
		date is 2016/02/24,
		comment is 'Predicates for generating library dependency diagrams. A dependency exists when an entity in one library makes a reference to an entity in another library.',
		parnames is ['Format']
	]).

	:- uses(list, [
		member/2, memberchk/2
	]).

	% first, output the library node
	output_library(Library, Directory, Options) :-
		^^add_link_options(Directory, Options, LinkingOptions),
		(	memberchk(directory_paths(true), Options) ->
			memberchk(omit_path_prefixes(Prefixes), Options),
			(	member(Prefix, Prefixes),
				atom_concat(Prefix, Relative, Directory) ->
				^^output_node(Directory, Library, library, [Relative], library, LinkingOptions)
			;	^^output_node(Directory, Library, library, [Directory], library, LinkingOptions)
			)
		;	^^output_node(Directory, Library, library, [], library, LinkingOptions)
		),
		^^remember_included_library(Library, Directory),
		fail.
	% second, output edges for all libraries that this library refers to
	output_library(Library, Directory, Options) :-
		depends_library(Library, Directory, OtherLibrary, OtherDirectory, Kind, Options),
		% ensure that this dependency is not already recorded
		\+ ^^edge(Directory, OtherDirectory, _, _, _),
			(	Kind == module ->
				^^remember_referenced_prolog_library(OtherLibrary, OtherDirectory),
				^^save_edge(Directory, OtherDirectory, [depends], depends_on_library, [tooltip(depends)| Options])
			;	^^remember_referenced_logtalk_library(OtherLibrary, OtherDirectory),
				^^save_edge(Directory, OtherDirectory, [depends], depends_on_library, [tooltip(depends)| Options])
			),
		fail.
	output_library(_, _, _).

	depends_library(Library, Directory, OtherLibrary, OtherDirectory, Kind, _) :-
		(	object_property(Object, file(Basename, Directory)),
			depends_object(Object, Kind, Other)
		;	protocol_property(Protocol, file(Basename, Directory)),
			depends_protocol(Protocol, Kind, Other)
		;	category_property(Category, file(Basename, Directory)),
			depends_category(Category, Kind, Other)
		;	modules_diagram_support::module_property(Module, file(Basename, Directory)),
			depends_module(Module, Kind, Other)
		),
		entity_basename_directory(Kind, Other, OtherBasename, OtherDirectory),
		(	OtherBasename \== Basename ->
			true
		;	OtherDirectory \== Directory
		),
		atom_concat(OtherDirectory, OtherBasename, OtherPath),
		(	Kind == module ->
			modules_diagram_support::module_property(OtherLibrary, file(OtherPath))
		;	logtalk::loaded_file_property(OtherPath, library(OtherLibrary))
		),
		OtherLibrary \== Library.

	% sometimes a library is a wrapper for its sub-libraries without source files
	% on its own; use the relative paths to check for sub-libraries
	depends_library(Library, Directory, OtherLibrary, OtherDirectory, object, Options) :-
		logtalk_library_path(OtherLibrary, _),
		OtherLibrary \== Library,
		logtalk::expand_library_path(OtherLibrary, OtherDirectory),
		atom_concat(Directory, Relative, OtherDirectory),
		Relative \== ''.

	depends_object(Object, object, Other) :-
		object_property(Object, calls(Other::_,_)), nonvar(Other).
	depends_object(Object, module, Other) :-
		object_property(Object, calls(':'(Other,_),_)), nonvar(Other).
	depends_object(Object, object, Other) :-
		extends_object(Object, Other).
	depends_object(Object, object, Other) :-
		instantiates_class(Object, Other).
	depends_object(Object, object, Other) :-
		specializes_class(Object, Other).
	depends_object(Object, protocol, Other) :-
		implements_protocol(Object, Other).
	depends_object(Object, category, Other) :-
		imports_category(Object, Other).
	depends_object(Object, category, Other) :-
		complements_object(Other, Object).

	depends_protocol(Protocol, object, Other) :-
		extends_protocol(Protocol, Other).

	depends_category(Category, object, Other) :-
		category_property(Category, calls(Other::_,_)), nonvar(Other).
	depends_category(Category, module, Other) :-
		category_property(Category, calls(':'(Other,_),_)), nonvar(Other).
	depends_category(Category, category, Other) :-
		extends_category(Category, Other).
	depends_category(Category, protocol, Other) :-
		implements_protocol(Category, Other).

	depends_module(Module, object, Other) :-
		modules_diagram_support::module_property(Module, calls(Other::_,_)), nonvar(Other).
	depends_module(Module, module, Other) :-
		modules_diagram_support::module_property(Module, calls(':'(Other,_),_)), nonvar(Other).

	entity_basename_directory(object, Entity, Basename, Directory) :-
		object_property(Entity, file(Basename, Directory)).
	entity_basename_directory(protocol, Entity, Basename, Directory) :-
		protocol_property(Entity, file(Basename, Directory)).
	entity_basename_directory(category, Entity, Basename, Directory) :-
		category_property(Entity, file(Basename, Directory)).
	entity_basename_directory(module, Entity, Basename, Directory) :-
		modules_diagram_support::module_property(Entity, file(Basename, Directory)).

	% by default, diagram layout is top to bottom:
	default_option(layout(top_to_bottom)).
	% by default, diagram title is empty:
	default_option(title('')).
	% by default, print current date:
	default_option(date(true)).
	% by default, don't generate cluster, file, and entity URLs:
	default_option(url_prefixes('', '')).
	% by default, don't omit any path prefixes when printing paths:
	default_option(omit_path_prefixes([])).
	% by default, don't print directory paths:
	default_option(directory_paths(true)).
	% by default, print relation labels:
	default_option(relation_labels(true)).
	% by default, don't print node type captions
	default_option(node_type_captions(false)).
	% by default, write diagram to the current directory:
	default_option(output_directory('./')).
	% by default, don't exclude any library sub-directories:
	default_option(exclude_libraries([])).

	diagram_name_suffix('_library_dependency_diagram').

:- end_object.



:- object(library_dependency_diagram,
	extends(library_dependency_diagram(dot))).

	:- info([
		version is 2.0,
		author is '<NAME>',
		date is 2016/02/29,
		comment is 'Predicates for generating library dependency diagrams in DOT format.'
	]).

:- end_object.
{'fraction_non_alphanumeric': 0.1379645710316082, 'fraction_numerical': 0.004723862452240361, 'mean_word_length': 5.911185789726356, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1780686', 'n_tokens_mistral': 4586, 'n_tokens_neox': 4176, 'n_words': 1076}