/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 * 
 * $Id: convertwn20.pl,v 1.10 2007/01/10 19:40:08 mvanasse Exp $
 *
 * Description: converts WordNet's Prolog version into RDF/OWL.
 *
 *
 *  Author:  Mark F.J. van Assem (mark@cs.vu.nl)
 *
 * Adapted and extended for SWBP WG WordNet Conversion 
 *  from original script by Maarten Menken
 *   See http://thesauri.cs.vu.nl/
 *
 * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *     Unpacking
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Place in directory with subdirs 'src', 'frames', 'rdf', 'rdf/full' and 
 * 'rdf/basic'. The src dir should 
 * contain the WordNet Prolog source files (e.g. wn_s.pl). The 'rdf'
 * (sub)dirs will be used for output (converted files, e.g. 'wordnet-synset.rdf').
 * The 'frames' dir should contain the specially constructed 'sen.pl' file created
 * from the 'frames.vrb' file in the WN/UNIX distribution. It contains clauses of
 * the form 'sen(SentenceNr, String)'.
 * 
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *     Software Requirements
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * Programmed for SWI-Prolog 5.6.9 (stable release)
 *  http://www.swi-prolog.org/
 *
 * Programmed against WordNet Prolog Version 2.0.
 *  http://wordnet.princeton.edu/
 *
 *  
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *     To Do
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 *
 *  - better documentation
 *  - error/debug messages outputted to files instead of standard output
 *  - datatypes
 *  
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *     Main commands
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * Note that it may be necessary to set Prolog's default stack sizes higher in
 * order for the program to run (see Settings > Stack Sizes), or run Prolog in
 * high mem mode.
 *
 * - go.			Convert all of WordNet (not advisable for older PCs)		
 *				This creates different rdf files in the 'rdf' 
 * 				directory
 * - go_synsets
 * 				Only does synsets, wordsenses, words
 *
 * - go_relations		Does the rest
 *
 *				
 * - create_X_file		convert only the X clauses and output to file (see bottom of this file)
 *   e.g. create_synsets_file	convert only the s(...) clauses and output to file
 *
 * - create_X			convert only X-clauses and assert rdf triples
 *   e.g create_synsets		convert only s(...)-clauses and assert rdf triples
 * - ...
 *
 *  Recommended usage:
 *  - run 'go_synsets'
 *  - kill the current prolog process (to free up RAM)
 *  - run 'go_relations' (frames not implemented yet)
 *  
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *     Debugging
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 *
 * Error messages turned on by default when using the go... predicates.
 * Other messages are turned off.
 * Use 'debug(Cat)' to turn
 * them on. For which 'Cat' to use see the create_X predicates. E.g. for
 * create_pertainsto the categories 'per-types' and 'per-errors' are defined,
 * most follow this pattern (types: print for which sensetypes the relation
 * is asserted, errors: print errors such as combinations of sensetypes which
 * should not occur in the sourcefiles according to the documentation).
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  CVS change log: see bottom
 */

 
% load the SWI-Prolog SemWeb libraries 
 
:-
    use_module(library('semweb/rdf_db')).
%    use_module(library('semweb/rdfs')).


% Make all the WN predicates dynamic so they can be deleted after processing
%  for efficiency.
    
:- dynamic
   s/6, g/2, hyp/2, ent/2, sim/2, mm/2, ms/2, mp/2, der/4, cls/3,
   cs/2, vgp/4, at/2, ant/4, sa/4, ppl/4, per/4, fr/3.

%%%%%%%%%%%%%%%%%%%%% set the WN namespace %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% for testing with old code 
%rdf_db:ns(wn, 'http://wordnet.princeton.edu/wn20#').
%rdf_db:ns(wn20, 'http://wordnet.princeton.edu/wn20/').

% the namespaces
rdf_db:ns(wn20schema, 'http://www.w3.org/2006/03/wn/wn20/schema/').
rdf_db:ns(wn20instances, 'http://www.w3.org/2006/03/wn/wn20/instances/').

% is this repeat needed?
:- rdf_register_ns(wn20schema, 	'http://www.w3.org/2006/03/wn/wn20/schema/').
:- rdf_register_ns(wn20instances,'http://www.w3.org/2006/03/wn/wn20/instances/').


   
%%%%%%%%% set the directories/filenames of input and output files %%%%%%%%%%%%%%

src_dir(wn, 'src').
src_dir(fr, 'frames'). 	% all source files in above source dir except for the
		 	% frames file as it is created from the Unix dist, it is
			% not part of the src files in the normal WN Prolog dist

			
% Dir for files that belong to both the "full" and "basic" versions			
out_dir(wn, 'rdf').
% Dir for files that belong to the "full" version only
out_dir(wnfull, 'rdf/full').		
% Dir for files that belong to the "basic" version only
out_dir(wnbasic, 'rdf/basic').

% out_file/3 defines for each "kind" of output to which dir and which file it should be
% outputted.

% the "kind" associates source files and processing predicates


out_file(sl,  wnbasic,   'wordnet-senselabels.rdf').

out_file(ant, wnfull,  'wordnet-antonym.rdf').
out_file(der, wnfull,  'wordnet-derivationallyrelated.rdf').
out_file(ppl, wnfull,  'wordnet-participleof.rdf').
out_file(per, wnfull,  'wordnet-pertainsto.rdf').
out_file(sa,  wnfull,  'wordnet-seealso.rdf').
out_file(ws,  wnfull,  'wordnet-wordsensesandwords.rdf').


out_file(at,  wn, 'wordnet-attribute.rdf').
out_file(cs,  wn, 'wordnet-causes.rdf').
out_file(cls, wn, 'wordnet-classifiedby.rdf').
out_file(ent, wn, 'wordnet-entailment.rdf').
out_file(fr,  wn, 'wordnet-frame.rdf').
out_file(g,   wn, 'wordnet-glossary.rdf').
out_file(hyp, wn, 'wordnet-hyponym.rdf').
out_file(mm,  wn, 'wordnet-membermeronym.rdf').
out_file(mp,  wn, 'wordnet-partmeronym.rdf').
out_file(vgp, wn, 'wordnet-sameverbgroupas.rdf').
out_file(sim, wn, 'wordnet-similarity.rdf').
out_file(ms,  wn, 'wordnet-substancemeronym.rdf').
out_file(s,   wn, 'wordnet-synset.rdf').
	
%%%%%%%%%%%%%% construct the complete path to output file %%%%%%%%%%%%%%%%%%

% F is a code used to match to actual output file, see out_file/3.

out_file_path(F, OutFilePath) :-
	out_file(F, DirCode, File),
	out_dir(DirCode, Dir),
	concat_atom([Dir, '/', File], OutFilePath).



%%%%%%%%%%%%%%%%%%%%% synset types -> synset classnames %%%%%%%%%%%%%%%%%%%%%%%
synset_type(n, 'NounSynset').
synset_type(v, 'VerbSynset').
synset_type(a, 'AdjectiveSynset').
synset_type(s, 'AdjectiveSatelliteSynset').
synset_type(r, 'AdverbSynset').

%%%%%%%%%%%%%%%%%%%%% wordsense types -> wordsense classnames %%%%%%%%%%%%%%%%%

% the wordsense_type is determined by the synset type (means the synset
% contains only wordsenses of this type. 



wordsense_type(n,'NounWordSense').
wordsense_type(v,'VerbWordSense').
wordsense_type(a,'AdjectiveWordSense').
wordsense_type(s,'AdjectiveSatelliteWordSense').
wordsense_type(r,'AdverbWordSense').

%%%%%%% (word)sense types -> lexical representation used in URIs %%%%%%%%%%%%%%%%%

% the URIs for Synsets and WordSenses include the lexical type, so need a mapping
% to lowercase words without the addition of "Synset" or "WordSense".

lexical_type_uri(n,'noun').
lexical_type_uri(v,'verb').
lexical_type_uri(a,'adjective').
lexical_type_uri(s,'adjectivesatellite').
lexical_type_uri(r,'adverb').


%%%%%%%%%%%%%%%%%%%% class_type -> classified property %%%%%%%%%%%%%%%%%%%%%

class_type(t, classifiedByTopic).
class_type(u, classifiedByUsage).
class_type(r, classifiedByRegion).

%%%%%%%%%%% Predicate used to enable dynamic forming of local:ID URIs %%%%%%%%%%

% In order to put a variable after a namespace the use of rdf_global is required.

my_rdf_assert(S0,P0,O0) :-
	rdf_global_id(S0, S),
	rdf_global_id(P0, P),
	rdf_global_term(O0, O),
	rdf_assert(S,P,O).


%%%%%%%%%%%%%%%%%%%% Symbols in Words -> Symbols in word part in URI %%%%%%%%%%%%%%%%%%%%%

uri_map([ '\'' / '_', 
	   '/' / '_', 
	   '(' / '_', 
	   ')' / '_' ]).


% for each character in a word that is not allowed in a URI, replace it with
% character in the uri_map

% Also replaces the character if it is the last character in the word, e.g. resulting
% in 'bla_bla_'.

uri_word(Word, URIWord) :-
	
	% get the mapping of characters to an allowed character 
	uri_map(L),
	% check for each Char in the uri map if it is present, if so replace.
	map_char(L, Word, URIWord).

%%%%%%%%%%%%%%%%%%%% Symbols in Words -> Symbols in human-readable parts %%%%%%%%%%%%%%%%%%%%%

% all we do here is replace underscores with spaces.

label_map([ '_' / ' ' ]).
	
label_word(Word, LabelWord) :-
	label_map(L),
	map_char(L, Word, LabelWord).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% Helper predicate for uri_word and label_word.
% Replaces all occurences of one char (CharIn) with another (CharOut), and does
% so for each provided CharIn/CharOut pair
	
map_char([], OldWord, OldWord).

map_char([CharIn/CharOut | Tail], OldWord, NewWord) :-

		% check if CharIn is in the word (needed because concat_atom always succeeds)
		sub_atom(OldWord, _, _, _, CharIn),
		
		% replace it
		concat_atom(List, CharIn, OldWord),
		concat_atom(List, CharOut, TmpWord),
		map_char(Tail, TmpWord, NewWord),
		! 					% red cut, dont backtrack to deliver empty variable
		
		% if CharIn not present continue to check the next CharIn/CharOut pair		
		;  
		map_char(Tail, OldWord, NewWord).
	
%%%%%%%%%%%%%%%%%%%% collocation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% fail if word is not a collocation in WN, i.e. does not contain '-' or '_' 

collocation(Word) :-
	sub_atom(Word,_,_,_,'-')
	;
	sub_atom(Word,_,_,_,'_').

%%%%% Given a list of file names, load them from the src directory %%%%%%%%%%%%%

load_wordnet_prolog_files(File) :-
    atom(File),
    src_dir(wn, Dir),
    concat_atom([Dir, File], '/', Path),
    consult(Path).
  
load_wordnet_prolog_files([Head | Tail]) :-
	load_wordnet_prolog_files(Head),
	load_wordnet_prolog_files(Tail).
    

	
	
	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The following predicates are together responsible for converting s(_,_)	
% clauses to the appropriate rdf triples (Synsets, Words, WordSenses)
%
%  - assumes wn_s.pl is loaded
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Predicates for constructing instance URIs (they produce no side effects)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




%%%%%%%%%%%% Example: wn20instances:word-bank %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

construct_word_uri(Word, WordInstanceURI) :-
	
	% replace disallowed characters
	uri_word(Word, TheWord),
	concat_atom(['word-', TheWord], LocalId),
	
	
	% use rdf_global to be able to add a variable after a namespace 
	rdf_global_id(wn20instances:LocalId, WordInstanceURI).	


	
%%%%%%% Example: - wn20instances:wordsense-bank-noun-1 %%%%%%%%%%%%%%%%%%%%%%%%%

construct_wordsense_uri(s(_Id,_Wnum, Word, SenseType, SenseNr, _TC), WordSenseInstanceURI) :-

	% replace disallowed characters  
	uri_word(Word, URIWord),
	lexical_type_uri(SenseType, URISenseType),
	
	concat_atom(['wordsense-', URIWord, '-', URISenseType, '-', SenseNr], LocalId),

	% rdf_global makes possible to add variable after a namespace	
	rdf_global_id(wn20instances:LocalId, WordSenseInstanceURI).



%%%%%%%%% Example: wn20instances:synset-bank-noun-1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%

construct_synset_uri(s(Id,_Wnum, _Word, SenseType, _SenseNr, _TC), SynsetInstanceURI) :-


	% select first word(sense) of synset to use as part of the URI for the Synset instance

	% EDIT: removed SenseNr as constraining variable; sometimes the sensenr
	% does not correspond to the first word and this predicate fails...
	% Second edit: DO use the SenseNr that is given by the first WordSense of the synset,
	% just dont require it to be the SAME as the SenseNr provided in the predicate call.
	
 	s(Id, 1,FirstWord,_, SenseNr,_),		

	% replace disallowed characters  
	uri_word(FirstWord, URIWord),
	lexical_type_uri(SenseType, URISenseType), 
	
	concat_atom(['synset-', URIWord, '-', URISenseType, '-', SenseNr], LocalId),

	% rdf_global makes possible to add variable after a namespace	
	rdf_global_id(wn20instances:LocalId, SynsetInstanceURI).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% predicates that create triples
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% no checking of errors or doubles yet...

create_synsets :-
	
	% only select the first WordSense of the synset, that is all that is required
	% to construct the synsets URI, synsetId and rdfs:label properties
	s(Id, 1,Word,SenseType,SenseNr,TagCount),

	% create synset instance, with synsetId and rdfs:label
	create_synset(s(Id, 1,Word,SenseType,SenseNr,TagCount)),	
			
	% all done, move to next s(...)-es
	fail
      ;
	true.

% do the actual asserts.
% create_synset works for any s(...) provided to it.

create_synset(s(Id, Wnum,Word,SenseType,SenseNr,TagCount)) :-


		% create URI of the right subclass of Synset (NounSynset, ...)
		synset_type(SenseType,SynsetClass),

		construct_synset_uri(s(Id,Wnum, Word, SenseType, SenseNr, TagCount), SynsetInstanceURI),

		
		my_rdf_assert(SynsetInstanceURI, rdf:type, wn20schema:SynsetClass),
		my_rdf_assert(SynsetInstanceURI, wn20schema:'synsetId', literal(Id)),
		
		% now add an rdfs:label by choosing the first word
		s(Id,1,FirstWord,_,_,_),
		label_word(FirstWord, LabelWord),
		my_rdf_assert(SynsetInstanceURI, rdfs:label, literal(LabelWord)),
		
		% debug code
		debug(create-synset, 'Created synset with Id ~w', [Id]).
	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	
	
create_wordsensesandwords :-
	s(Id, _,_,_,_,_),

	% Collect all s(...) with same Id (i.e. the list of wordsenses that together form a synset)
	bagof(s(Id,A,B,C,D,E), s(Id,A,B,C,D,E), Synset),		

	process_synset(Synset),
	
	retractlist(Synset),
	% all done, move to next s(...)-es
	fail
      ;
	true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	


process_synset([]).

process_synset(s(Id,Wnum, Word, SenseType, SenseNr, TagCount)) :-	

	% create instances of the wordt and the wordsense
	create_word(Word, WordInstanceURI),						
	create_wordsense(s(Id, Wnum,Word,SenseType,SenseNr,TagCount), WordSenseInstanceURI),		

	construct_synset_uri(s(Id, Wnum,Word,SenseType,SenseNr,TagCount),    SynsetInstanceURI),

	% do the rdf asserts, at same time connect word to wordsense, wordsense to synset
	my_rdf_assert(WordSenseInstanceURI, wn20schema:word, WordInstanceURI ),
	my_rdf_assert(SynsetInstanceURI, wn20schema:containsWordSense, WordSenseInstanceURI),
	debug(ws-types, 'asserting triples for (Synset, WS, W): ~w, ~w, ~w',[SynsetInstanceURI, WordSenseInstanceURI, WordInstanceURI]).
	

process_synset( [ s(A,B,C,D,E,F) | Tail] ) :-
	process_synset(s(A,B,C,D,E,F)),
	process_synset(Tail).	
	

% helper predicate to delete a list of facts.

retractlist([]).
	
retractlist([H|T]) :-
	retract(H),
	retractlist(T).

	
	
	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
	
create_word(Word, WordInstanceURI) :-

		
		% A word is either of class Collocation or Word
		(
			collocation(Word)
			->
			WordClass = 'Collocation'
			;
			WordClass = 'Word'
		),

		construct_word_uri(Word, WordInstanceURI),
		label_word(Word, LabelWord),
		
		my_rdf_assert(WordInstanceURI, rdf:type, wn20schema:WordClass),
		my_rdf_assert(WordInstanceURI, wn20schema:lexicalForm, literal(LabelWord)).

		
% create all triples for a given wordsense. Return the URI of the new instance
		
create_wordsense(s(Id,Wnum, Word,SenseType,SenseNr,TagCount), WordSenseInstanceURI) :-		

		construct_wordsense_uri(s(Id,Wnum, Word,SenseType,SenseNr,TagCount), WordSenseInstanceURI),

		wordsense_type(SenseType, ClassName),
		label_word(Word, LabelWord),
		
		my_rdf_assert(WordSenseInstanceURI, rdf:type, wn20schema:ClassName),
		my_rdf_assert(WordSenseInstanceURI, wn20schema:tagCount, literal(TagCount)),
		my_rdf_assert(WordSenseInstanceURI, rdfs:label, literal(LabelWord)).
		


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	

create_senselabels :-

	s(Id, Wnum,Word,SenseType,SenseNr,TagCount),

	construct_synset_uri(s(Id, Wnum,Word,SenseType,SenseNr,TagCount),    SynsetInstanceURI),

	label_word(Word, LabelWord),
	
	rdf_assert(SynsetInstanceURI, wn20schema:senseLabel, literal(LabelWord)),
	% all done, move to next s(...)-es
	fail
      ;
	true.
	


	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
%	
% The following 'create_X' predicates each
%
%  - assume the correct wn_Y.pl files are loaded 
%  - convert all wordnet predicates of one type (e.g. hyp(_,_) to the
%    appropriate rdf triples using rdf_assert/3
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% each synset has a natural language label (definition or gloss)

create_glossaries :-
        g(SynsetId, Gloss),
	s(SynsetId,A,B,C,D,E),
	construct_synset_uri(s(SynsetId,A,B,C,D,E), SynsetURI),

        rdf_assert(SynsetURI, wn20schema:gloss, literal(Gloss)),

	% done with this g(...), do next
        fail
      ;
        true.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between synsets

create_hypernyms :-
        hyp(Hypo, Hyper),
	s(Hypo,A1,B1,C1,D1,E1),
	s(Hyper,A2,B2,C2,D2,E2),

	construct_synset_uri(s(Hypo,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(Hyper,A2,B2,C2,D2,E2), Object),

        rdf_assert(Subject, wn20schema:hyponymOf, Object),
	
	% done with this hyp(...), do next
        fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between Verb synsets

create_entailments :-
        ent(VerbSynsetId1, VerbSynsetId2),
	s(VerbSynsetId1,A1,B1,C1,D1,E1),
	s(VerbSynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(VerbSynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(VerbSynsetId2,A2,B2,C2,D2,E2), Object),

	rdf_assert(Subject, wn20schema:entails, Object),

	% done with this ent(...), do next
        fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
% symmetric relation between synsets

% no need to check for the inverses because it seems they are all not there 
% in source file (at least not for a LOT of them).

create_similarities :-
        sim(SynsetId1, SynsetId2),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),
	
	% just to be sure we check if the inverse was not already asserted,
	% but we wont check for 'erroneous' missing inverses
	\+rdf(Object, wn20schema:similarTo, Subject),
	rdf_assert(Subject, wn20schema:similarTo, Object),
	% done with this sim(...), do next
        fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between synsets

create_membermeronyms :-
        mm(SynsetId1, SynsetId2),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),

	rdf_assert(Subject, wn20schema:memberMeronymOf, Object),
        fail
      ;
        true.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between synsets

create_substancemeronyms :-
        ms(SynsetId1, SynsetId2),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),

	rdf_assert(Subject, wn20schema:substanceMeronymOf, Object),

	% done with this ms(...), do next
        fail
      ;
        true.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between synsets


create_partmeronyms :-
        mp(SynsetId1, SynsetId2),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),

	rdf_assert(Subject, wn20schema:partMeronymOf, Object),

	% done with this ms(...), do next
        fail
      ;
        true.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
% symmetric relation between wordsenses

% File contains the inverses, predicate only asserts a triple if the
% inverse is present. Else it outputs error statement.

create_derivationallyrelated :-
	der(SynsetId1, Wnum1, SynsetId2, Wnum2),
	s(SynsetId1,Wnum1,B1,C1,D1,E1),
	s(SynsetId2,Wnum2,B2,C2,D2,E2),
	
	(	%IF no inverse in the source;
			
	  	\+der(SynsetId2, Wnum2, SynsetId1, Wnum1)
	      	
		->

		%THEN do nothing i.e. assume this ant(..) is erroneous		
		%        output some debug code
		debug(der-errors,'Error: inverse statement not present for der(~w, ~w, ~w, ~w)', [SynsetId1, Wnum1, SynsetId2, Wnum2])

		%ELSE
		;	
	
		construct_wordsense_uri(s(SynsetId1,Wnum1,B1,C1,D1,E1), Subject),
		construct_wordsense_uri(s(SynsetId2,Wnum2,B2,C2,D2,E2), Object),
	
		% first check whether not already processed the inverse, then assert new triple
		\+rdf(Object, wn20schema:derivationallyRelated, Subject),
		rdf_assert(Subject, wn20schema:derivationallyRelated, Object)
	),
	% done with this der(...), do next
	fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between synsets converted into three separate
% rdf properties


create_classifiedby :-
	cls(SynsetId1, SynsetId2, Type),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	class_type(Type, PropertyName),
	rdf_db:ns(wn20schema, NS),
	concat_atom([NS, PropertyName], TheProperty),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),
	
	rdf_assert(Subject, TheProperty, Object),

	
	% done with this cls(...), do next
	fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
% non-symmetric relationship between synsets

create_causes :-	
	cs(SynsetId1, SynsetId2),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),

	rdf_assert(Subject, wn20schema:causes, Object),
	
	% done with this cs(...), do next
	fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% symmetric relation between synsets 

% seems that the Wnums are not important as they are all 0, so we implement
% this as a relation between synsets instead of wordsenses.

% File contains the inverses, predicate only asserts a triple if the
% inverse is present. Else it outputs error statement.

create_verbgroups :-
	vgp(SynsetId1, _, SynsetId2, _),
	s(SynsetId1,A1,B1,C1,D1,E1),
	s(SynsetId2,A2,B2,C2,D2,E2),

	construct_synset_uri(s(SynsetId1,A1,B1,C1,D1,E1), Subject),
	construct_synset_uri(s(SynsetId2,A2,B2,C2,D2,E2), Object),

	% first check whether not already processed the inverse, then assert new triple
	\+rdf(Object, wn20schema:sameVerbGroupAs, Subject),
	rdf_assert(Subject, wn20schema:sameVerbGroupAs, Object),
	
	% done with this vgp(...), do next
	fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relationship between Noun and Adjective(Satellite) synsets

% According to documentation the inverse relationship is also in the source
% so have to check for the direction. 
% If there is no inverse then output error.
% It is not a problem that the inverses are there because they result in the
% same triples in this code.

create_attributes :-
	at(SynsetId1, SynsetId2),

	s(SynsetId1,A1,B1,SenseType1,D1,E1),
	s(SynsetId2,A2,B2,SenseType2,D2,E2),

	(
	
		%IF no inverse
		 
		\+at(SynsetId2, SynsetId1)
	
		%THEN output error
		 ->		
		
		 debug(at-errors, 'No inverse for at(~w, ~w) found, skipping...', [SynsetId1,SynsetId2])
		   
		 ; %ELSE add the appropriate RDF triples
		
		( 
	
		% concatenate the sensetypes into PairType to be able to check 
		% which case we are dealing with in one statement	
		concat_atom([SenseType1,SenseType2], PairType),
		
		% Noun-Adjective
		PairType == 'na',
		construct_synset_uri(s(SynsetId1,A1,B1,SenseType1,D1,E1), Subject),
		construct_synset_uri(s(SynsetId2,A2,B2,SenseType2,D2,E2), Object),
		rdf_assert(Subject, wn20schema:attribute, Object)	

		;
		
		% same for Noun-AdjectiveSatellite
		PairType == 'ns',
		construct_synset_uri(s(SynsetId1,A1,B1,SenseType1,D1,E1), Subject),
		construct_synset_uri(s(SynsetId2,A2,B2,SenseType2,D2,E2), Object),
		rdf_assert(Subject, wn20schema:attribute, Object)
	      
		
		% skip the PairTypes 'an' and 'sn', because these are inverses 
		% that previous code already handled.
		

		;
		
		% In every other case PairType is not one of the above, output an error message.
		% Check using 'member' is required because of use of "fail" later on to process all at(...)

		\+(member(PairType, ['na','ns','an','sn'])),
		debug(at-errors, 'Error, the Synsets ~w and ~w found in an at(...) do not have valid SenseTypes, respectively ~w and ~w' , [SynsetId1, SynsetId2, SenseType1, SenseType2])
		)
	),
	
	% done with this at(...), do next
	fail
      ;
        true.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% symmetric relation between WordSenses.

% according to documentation the symmetric relationship might also be in the
% source file, i.e. contains both ant(A,B) and ant(B,A) which both result in 
% the same output triple.
% Predicate checks if the symmetric relationship is also present 
% (for WN 2.0 this is not the case for some ant(...)). 
% If not,
% it does NOT assert wn20schema:antonymOf. It then also outputs 
% error message using 'debug/2'. To see them assert 'debug(ant-errors)' before running.


create_antonyms :-	
	ant(SynsetId1, Wnum1, SynsetId2, Wnum2),

	s(SynsetId1,Wnum1,B1,C1,D1,E1),
	s(SynsetId2,Wnum2,B2,C2,D2,E2),

	(	%IF no inverse in the source;
			
	  	\+ant(SynsetId2, Wnum2, SynsetId1, Wnum1)
	      	
		->

		%THEN do nothing i.e. assume this ant(..) is erroneous		
		%        output some debug code
	        concat_atom(['Error, no symmetric ant for WordSenses (SynsetId, Wnum): ', SynsetId1, ', wnum=', Wnum1, ', ', SynsetId2, ', wnum2=', Wnum2, ' (triple not added)\n'], ErrorMsg),
		debug(ant-errors,ErrorMsg, [])

		%ELSE
		;
		
		construct_wordsense_uri(s(SynsetId1,Wnum1,B1,C1,D1,E1), Subject),
		construct_wordsense_uri(s(SynsetId2,Wnum2,B2,C2,D2,E2), Object),

		% first check whether not already processed the inverse, then assert new triple
		\+rdf(Object, wn20schema:antonymOf, Subject),
		rdf_assert(Subject, wn20schema:antonymOf, Object)
		
	),
	
	% done with this ant(...), do next
	
	fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% non-symmetric relation between WordSenses, only verbs and adjectives
% Not known if only FROM Verbs TO adjectives or that any combination is allowed.

% When running this predicate it turns out that sa(...) is only between verbs in 
% this WN version (2.0). To see this assert 'debug(sa-types)' before running.

create_seealso :-
	sa(SynsetId1, Wnum1, SynsetId2, Wnum2),
	s(SynsetId1,Wnum1,B1,SenseType1,D1,E1),
	s(SynsetId2,Wnum2,B2,SenseType2,D2,E2),

	construct_wordsense_uri(s(SynsetId1,Wnum1,B1,SenseType1,D1,E1), Subject),
	construct_wordsense_uri(s(SynsetId2,Wnum2,B2,SenseType2,D2,E2), Object),

	% concatenate the sensetypes into PairType to be able to check 
	% which case we are dealing with in one statement	
	concat_atom([SenseType1,SenseType2], PairType),
	(

		member(PairType, ['vv','va', 'vs', 'aa','av', 'as', 'sv', 'sa']),
		rdf_assert(Subject, wn20schema:seeAlso, Object),
		
		% no inverse property yet...

		% debug code
		debug(sa-types, PairType, [])					
             ;
	       	% in every other case PairType is not one of the above
		% (check using 'member' is required because of use of "fail" later on to process all at(...)
	        \+(member(PairType, ['vv','va', 'vs', 'aa','av', 'as', 'sv', 'sa'])),

		% debug code
	      	concat_atom(['Error. Ids: ', SynsetId1, SenseType1, ' ', SynsetId2, SenseType2, '\n'], ErrorMsg),
		debug(sa-errors, ErrorMsg, [])
	),
	
	% done with this sa(...), do next
	fail
      ;
        true.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
% Non-symmetric relation between WordSenses: adjective(satellite) -> verb

create_participles :-
	ppl(SynsetId1, Wnum1, SynsetId2, Wnum2),
	s(SynsetId1,Wnum1,B1,SenseType1,D1,E1),
	s(SynsetId2,Wnum2,B2,SenseType2,D2,E2),

	construct_wordsense_uri(s(SynsetId1,Wnum1,B1,SenseType1,D1,E1), Subject),
	construct_wordsense_uri(s(SynsetId2,Wnum2,B2,SenseType2,D2,E2), Object),

	% concatenate the sensetypes into PairType to be able to check 
	% which case we are dealing with in one statement	
	concat_atom([SenseType1,SenseType2], PairType),
	(

		member(PairType, ['av', 'sv']),
		rdf_assert(Subject, wn20schema:participleOf, Object),

		% debug code
		debug(ppl-types, PairType, [])				
	     ;
	       	% in every other case PairType is not one of the above
		% (check using 'member' is required because of use of "fail" later on to process all at(...)
		\+(member(PairType, ['av', 'sv'])),
		
		% debug code
	      	concat_atom(['Error. Ids: ', SynsetId1, SenseType1, ' ', SynsetId2, SenseType2, '\n'], ErrorMsg),
		debug(ppl-errors, ErrorMsg, [])					
	),
	
	% done with this ppl(...), do next
	fail
      ;
        true.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% Non-symmetric relation between WordSenses, converted into two properties:
%  wn20schema:adjectivePertainsTo, wn20schema:adverbPertainsTo

create_pertainsto :-
	per(SynsetId1, Wnum1, SynsetId2, Wnum2),
	s(SynsetId1,Wnum1,B1,SenseType1,D1,E1),
	s(SynsetId2,Wnum2,B2,SenseType2,D2,E2),

	construct_wordsense_uri(s(SynsetId1,Wnum1,B1,SenseType1,D1,E1), Subject),
	construct_wordsense_uri(s(SynsetId2,Wnum2,B2,SenseType2,D2,E2), Object),

	% concatenate the sensetypes into PairType to be able to check 
	% which case we are dealing with in one statement	
	concat_atom([SenseType1,SenseType2], PairType),
	(

		member(PairType, ['an', 'aa', 'as', 'sn','sa', 'ss']),
		rdf_assert(Subject, wn20schema:adjectivePertainsTo, Object),

		
		% debug code
		debug(per-types, PairType, [])				
	     ;
		member(PairType, ['ra', 'rs']),
		rdf_assert(Subject, wn20schema:adverbPertainsTo, Object),

		% debug code
		debug(per-types, PairType, [])				

	     ;	     
	        % in every other case PairType is not one of the above
		% (check using 'member' is required because of use of "fail" later on to process all at(...)
		\+(member(PairType, ['an', 'aa', 'as', 'sn','sa', 'ss','ra', 'rs'])),
		
		% debug code
	      	concat_atom(['Error. Ids: ', SynsetId1, SenseType1, ' ', SynsetId2, SenseType2, '\n'], ErrorMsg),
		debug(per-errors, ErrorMsg, [])					
	),
	
	% done with this ppl(...), do next
	fail
      ;
        true.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

% Relation between VerbWordSenses and a string.
% Uses the fr(...) from the original WordNet Prolog distribution, as well as an
% added sen(...) because the actual sentences are NOT in the Prolog dist.

create_frames :-
	
	% a frame associates a WordSense (identified with synset Id and Wnum)
	% with a sentence nr
	fr(Id, SenNr, Wnum),
	% sen associates a sentence nr with a string
	sen(SenNr, String),	
	s(Id,Wnum, Word, ST, SNr, TC),

	(
	% case 1: WordSenseNr = 0, the frame sentence should be attached to all WordSenses in the Synset

	Wnum == 0,
	
	create_wordsense_uris(s(Id,Wnum, Word, ST, SNr, TC), WSUriList),
	attach_frame_to_wordsenses(WSUriList, String)		
	
	; %OR
	
	% case 2: WordSenseNr \== 0, the frame sentence should only be attached to the WordSense
	% identified by the Wnum

	
	Wnum \== 0,
	
	construct_wordsense_uri(s(Id,Wnum, Word, ST, SNr, TC), URI),
	rdf_assert(URI, wn20schema:frame, literal(String))
		
	),
	
	% done with this fr(...), do next
	fail
      ;
        true.


% given a synset ID, construct a list of URIs for its WordSenses	
	
create_wordsense_uris(s(Id,_,_,_,_,_), URIList):-	

	bagof(s(Id,A,B,C,D,E), s(Id,A,B,C,D,E), Synset),	%get all s... that belong to the synset	
	maplist(construct_wordsense_uri, Synset, URIList).	% apply construct_wordsense uri to each s(...) 

attach_frame_to_wordsenses([], _String).
	
attach_frame_to_wordsenses([H|T], String) :-
	rdf_assert(H, wn20schema:frame, literal(String)),
	attach_frame_to_wordsenses(T, String).

	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
%
%  The following predicates are for loading the appropriate files and 
%   subsequently calling the right create_X predicate; they form the 
%    "main program loop"
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		
%
%  Create_wordnet_file:
%   - load the list of SrcFiles
%   - open the appropriate outputfile using OutFileCode
%   - call Predicate (which should create the RDF statements and assert them
%                     with rdf_assert)
%   - save all the triples to OutFile
%   - add the xml:lang attribute to OutFile RDF tag with value "en-US"
%   - retract all triples again (for efficiency)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%		

create_wordnet_file(SrcFiles, OutFileCode, Predicate) :-
	load_wordnet_prolog_files(SrcFiles),
	out_file_path(OutFileCode, OutFile),
	call(Predicate),
	debug(create-wordnet-file, 'Now going to save triples to file ~w',[OutFile]), 

	% add lang attribute to whole doc, add namespaces to circumvent Prolog bug
	rdf_save(OutFile,[document_language('en-US'), namespaces([wn20instances, wn20schema])]),

	debug(create-wordnet-file, 'Saved triples to file, now going to retract all RDF statements',[]), 
	rdf_retractall(_,_,_).	
	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	
%
%  Convenience predicates, each creates a separate RDF file based usually 
%   on one WN clause
%   e.g. create_hypernyms_file processes all hyp(...,...).
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	

create_synsets_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file('wn_s.pl', s, create_synsets).


create_sense_labels_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file('wn_s.pl', sl, create_senselabels).

create_wordsensesandwords_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file('wn_s.pl', ws, create_wordsensesandwords).

	
create_glossaries_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_g.pl'], g, create_glossaries).
	
create_hypernyms_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl', 'wn_hyp.pl'], hyp, create_hypernyms).	

create_entailments_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_ent.pl'], ent, create_entailments).
	
create_similarities_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl', 'wn_sim.pl' ], sim, create_similarities).

create_membermeronyms_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl', 'wn_mm.pl'], mm, create_membermeronyms).

create_substancemeronyms_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_ms.pl'], ms, create_substancemeronyms).

create_partmeronyms_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_mp.pl'], mp, create_partmeronyms).

create_derivationallyrelated_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_der.pl'], der, create_derivationallyrelated).

create_classifiedby_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_cls.pl'], cls, create_classifiedby).

create_causes_file :-	
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_cs.pl'], cs, create_causes).

create_verbgroups_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_vgp.pl'], vgp, create_verbgroups).

create_attributes_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_at.pl'], at, create_attributes).

create_antonyms_file :-	
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_ant.pl'], ant, create_antonyms).

create_seealso_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_sa.pl'], sa, create_seealso).

create_participles_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_ppl.pl'], ppl, create_participles).

create_pertainsto_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	
	create_wordnet_file(['wn_s.pl','wn_per.pl'], per, create_pertainsto).

%%%%% This predicate is different from the previous ones:
%%%%% Hack needed to load the sen.pl file as it is not in the normal source
%%%%% directory as is the case with all other files.
%%%%% See create_frames for why this file is needed and intentionally kept separate.
	
create_frames_file :-
	% turn on debug statements on file creation level so user sees
	% when processing is done and save to file commences.
	debug(create-wordnet-file),	

	% hack to load sen.pl file from frames dir	
	src_dir(fr, FrDir),	
	concat_atom([FrDir, 'sen.pl'], '/', Path),
	consult(Path),
	
	% normal part
	create_wordnet_file(['wn_s.pl', 'wn_fr.pl'], fr, create_frames).

	
	
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	


% Note that computers with limited capacity cannot handle 'go.'.  
% Better to:
%
%  - run 'go_synsets'
%  - kill the current prolog process (to free up RAM again)
%  - run 'go_relations'

% Especially create_wordsensesandwords_file is demanding.

go :-
	debug_error_all,
	
	create_synsets_file,
	create_sense_labels_file,
	create_wordsensesandwords_file,
	
	create_glossaries_file,
	create_hypernyms_file,
	create_entailments_file,
	create_similarities_file,
	create_membermeronyms_file,
	create_substancemeronyms_file,
	create_partmeronyms_file,
	create_derivationallyrelated_file,
	create_classifiedby_file,
	create_causes_file,
	create_verbgroups_file,
	create_attributes_file,
	create_antonyms_file,
	create_seealso_file,
	create_participles_file,
	create_pertainsto_file,
	create_frames_file.

	
go_synsets :-
	debug_error_all,	

	create_synsets_file,
	create_sense_labels_file,
	create_wordsensesandwords_file.
	
go_relations :-
	debug_error_all,

	create_glossaries_file,
	create_hypernyms_file,
	create_entailments_file,
	create_similarities_file,
	create_membermeronyms_file,
	create_substancemeronyms_file,
	create_partmeronyms_file,
	create_derivationallyrelated_file,
	create_classifiedby_file,
	create_causes_file,
	create_verbgroups_file,
	create_attributes_file,
	create_antonyms_file,
	create_seealso_file,
	create_participles_file,
	create_pertainsto_file,
	create_frames_file.

% turn on error debug statements for all predicates that have error debug messages	
	
debug_error_all :-		
	debug(der-errors),
	debug(at-errors),
	debug(ant-errors),
	debug(sa-errors),
	debug(ppl-errors),
	debug(per-errors).


% fin!

abode_test :-
	[src/wn_s],
	rdf_retractall(_,_,_),
	% Collect all s(...) with same Id (i.e. the list of wordsenses that together form a synset)
	%bagof(s(103141215,B,C,D,E,F), B^C^D^E^F^s(103141215,B,C,D,E,F), Synset),		
	bagof(s(103141215,B,C,D,E,F), s(103141215,B,C,D,E,F), Synset),		

	write(Synset), !,
	process_synset(Synset).


/******************************************************************************

 $Log: convertwn20.pl,v $
 Revision 1.10  2007/01/10 19:40:08  mvanasse
 updated version that fixes problem with missing senses

 Revision 1.9  2006/05/24 13:13:35  mvanasse
 deleted double file name and directory for the senselabels. Reorganised the file list alphabetically

 Revision 1.8  2006/05/19 14:52:27  mvanasse
 - improved comments/documentation
 - fixed error in prop name: synsetContainsWordSense -> containsWordSense

 Revision 1.7  2006/05/17 13:12:20  mvanasse
 wn20schema:synsetContainsWordSense -> wn20schema:containsWordSense

 Revision 1.6  2006/04/25 15:22:07  mvanasse
 changed to new URI patterns; minor improvements in comments and structure

 Revision 1.5  2006/04/23 19:18:52  mvanasse
 *** empty log message ***

 Revision 1.4  2006/04/23 18:51:17  mvanasse
 added file for senselabels

 Revision 1.3  2006/04/09 18:00:12  mvanasse
 - removed creation of inverse properties (e.g. hypernymOf)
 - improved code for replacing illegal chars in URIs
 - improved checking for missing inverse statements and outputting error msg
 - more flexible routing of output to files/directories
 - implemented frame sentence generation
 - fixed bug that caused inverse wn:attribute's to be asserted

 Revision 1.2  2006/04/06 14:56:10  mvanasse
 fixed two errors in the old program:
 - antonym inverses are removed
 - language tag now en-US instead of en

 Revision 1.1  2006/04/06 13:33:15  mvanasse
 Copy of Prolog conversion program + sources belonging to the first draft (before Editor's Draft 2 February 2006). No Basic/Full version, produces the inverse properties also and old URI formatting; some bugs.

 - Added Princeton WN/UNIX distribution
 - Added dir 'frames' with frames.vrb file from the UNIX distribution
 - Created new 'sen.pl' file based on 'frames.vrb'


*******************************************************************************/