:- module(miniWordNet,[compConcepts/2, compISA/0, graphMWN/2, outputMWN/2, axiomsWN/1, cutDownMWN/0, checkConsBK/0, addTopMWN/0, sizeMWN/1, clearMWN/0]). /* ======================================================================== Load Modules ======================================================================== */ :- use_module(library(lists),[member/2,append/3,select/3]). :- use_module(semlib(options),[option/2]). :- use_module(semlib(errors),[error/2,warning/2]). :- use_module(semlib(drs2fol),[symbol/4,timex/2]). % :- use_module(knowledge(nationality),[nationality/2]). /* ======================================================================== Load WordNet ======================================================================== */ % :- [candc(working/wordnet/wordnet)]. %:- [working/wordnet/vanilla_train_s]. %:- [working/wordnet/vanilla_train_l]. %:- [working/wordnet/vanilla_train_xxxl]. %:- [working/wordnet/vanilla_test_xl]. %:- [working/wordnet/human_test]. %:- [working/wordnet/elliesimple]. %:- [working/wordnet/ellie_train]. %:- [working/wordnet/combined]. /* ======================================================================== Declare Dynamic Predicates ======================================================================== */ :- dynamic concept/2, % concept(Concept, ConceptId) isa/2, % isa(ConceptId1, ConceptId2) isnota/2, % isnota(ConceptId1, ConceptId2) word/5. % word(Word,Cat,Sense,Freq,ConceptId), /* ======================================================================== Minimum Frequence for words under consideration ======================================================================== */ minFreq(0). /* ======================================================================== Clear Background Knowledge ======================================================================== */ clearMWN:- retractall(word(_,_,_,_,_)), retractall(isa(_,_)), retractall(isnota(_,_)), retractall(concept(_,_)). /* ======================================================================== Compute Concepts for one DRS ======================================================================== */ compConcepts(DRS,DRS):- findSymDrs(DRS,[]-_,[]-Concepts), selectConcepts(Concepts), !. compConcepts(DRS,DRS). /* ======================================================================== Get all symbols from a DRS ======================================================================== */ findSymDrs(smerge(A,B),X1-X3,R1-R2):- !, findSymDrs(A,X1-X2,R1-R3), findSymDrs(B,X2-X3,R3-R2). findSymDrs(merge(A,B),X1-X3,R1-R2):- !, findSymDrs(A,X1-X2,R1-R3), findSymDrs(B,X2-X3,R3-R2). findSymDrs(alfa(_,A,B),X1-X3,R1-R2):- !, findSymDrs(A,X1-X2,R1-R3), findSymDrs(B,X2-X3,R3-R2). findSymDrs(drs([_:Y1|Dom],Conds),X1-X3,R1-R2):- select(Y2,X1,X2), Y1==Y2, !, findSymDrs(drs(Dom,Conds),X2-X3,R1-R2). findSymDrs(drs([_|Dom],Conds),X1-X2,R1-R2):- findSymDrs(drs(Dom,Conds),X1-X2,R1-R2). findSymDrs(drs([],Conds),X1-X2,R1-R2):- !, findSymConds(Conds,X1-X2,R1-R2). /* ======================================================================== Get all symbols from a DRS-Condition ======================================================================== */ findSymConds([],X-X,R-R). findSymConds([_:imp(B1,B2)|L],X1-X3,R1-R4):- !, findSymDrs(B1,X1-X2,R1-R2), findSymDrs(B2,X2-_,R2-R3), findSymConds(L,X1-X3,R3-R4). findSymConds([_:or(B1,B2)|L],X1-X2,R1-R4):- !, findSymDrs(B1,X1-_,R1-R2), findSymDrs(B2,X1-_,R2-R3), findSymConds(L,X1-X2,R3-R4). findSymConds([_:duplex(_,B1,_,B2)|L],X1-X3,R1-R4):- !, findSymDrs(B1,X1-X2,R1-R2), findSymDrs(B2,X2-_,R2-R3), findSymConds(L,X1-X3,R3-R4). findSymConds([_:not(B)|L],X1-X2,R1-R3):- !, findSymDrs(B,X1-_,R1-R2), findSymConds(L,X1-X2,R2-R3). findSymConds([_:pos(B)|L],X1-X2,R1-R3):- !, findSymDrs(B,X1-_,R1-R2), findSymConds(L,X1-X2,R2-R3). findSymConds([_:nec(B)|L],X1-X2,R1-R3):- !, findSymDrs(B,X1-_,R1-R2), findSymConds(L,X1-X2,R2-R3). findSymConds([_:prop(_,B)|L],X1-X2,R1-R3):- !, findSymDrs(B,X1-_,R1-R2), findSymConds(L,X1-X2,R2-R3). findSymConds(L1,X1-X2,R1-R2):- select(_:pred(Y1,Sym,n,Sense),L1,L2), !, ( stoplist(Sym,n), !, findSymConds(L2,X1-X2,R1-R2) ; member(Y0,X1), Y1==Y0, !, warning('symbol ~p not selected for MWN',[Sym]), findSymConds(L2,X1-X2,R1-R2) ; findSymConds(L2,[Y1|X1]-X2,[s(Sym,n,Sense)|R1]-R2) ). findSymConds(L1,X1-X2,R1-R2):- select(_:pred(Y,Sym,v,Sense),L1,L2), !, ( stoplist(Sym,v), !, findSymConds(L2,X1-X2,R1-R2) ; findSymConds(L2,[Y|X1]-X2,[s(Sym,v,Sense),s(event,n,1)|R1]-R2) ). findSymConds(L1,X1-X2,R1-R2):- select(_:pred(Y,Sym,a,Sense),L1,L2), !, ( stoplist(Sym,a), !, findSymConds(L2,X1-X2,R1-R2) ; findSymConds(L2,[Y|X1]-X2,[s(Sym,a,Sense)|R1]-R2) ). findSymConds(L1,X1-X2,R1-R2):- select(_:pred(Y,Sym,r,Sense),L1,L2), !, ( stoplist(Sym,r), !, findSymConds(L2,X1-X2,R1-R2) ; findSymConds(L2,[Y|X1]-X2,[s(Sym,r,Sense)|R1]-R2) ). findSymConds([_:card(_,N,_)|L],X1-X2,R1-[s(Sym,cardinal,1),s(numeral,n,1)|R2]):- option('--plural',false), integer(N), N > 0, !, symbol(c,number,N,Sym), findSymConds(L,X1-X2,R1-R2). findSymConds([_:timex(Y1,T)|L],X1-X2,R1-[s(Sym,timex,1),s(time,n,5)|R2]):- \+ (member(Y0,X1), Y1==Y0), !, timex(T,Sym), findSymConds(L,[Y1|X1]-X2,R1-R2). findSymConds([_:named(Y1,Sym,Cat,Sense)|L],X1-X2,R1-[s(Sym,Cat,Sense)|R2]):- % \+ (member(Y0,X1), Y0==Y1), !, findSymConds(L,[Y1|X1]-X2,R1-R2). findSymConds([_|L],X1-X2,R1-R2):- findSymConds(L,X1-X2,R1-R2). /* ======================================================================== Select relevant nouns and verbs as concepts ======================================================================== */ selectConcepts([]). selectConcepts([s(_,ttl,_)|L]):- !, % ignore titles selectConcepts(L). selectConcepts([s(X,Cat,0)|L]):- !, % WSD (most frequent sense) selectConcepts([s(X,Cat,1)|L]). %selectConcepts([c(X,Syms,Cat,0)|L]):- !, % WSD (most frequent sense) % selectConcepts([c(X,Syms,Cat,1)|L]). selectConcepts([s(X,Cat,Sense)|L]):- word(X,Cat,Sense,_,ID), !, % if word (token) is already retract(word(X,Cat,Sense,N1,ID)), % in the database N2 is N1 + 1, % then increase frequency assert(word(X,Cat,Sense,N2,ID)), selectConcepts(L). selectConcepts([s(Sym1,Cat,Sense1)|L]):- concept(Concept,ID), % if word is not in the database member(s(Sym2,Cat,Sense2),Concept), % but a synonym is, then syn(Cat,Sym1,Sense1,Sym2,Sense2), !, % extend list of synonyms assert(word(Sym1,Cat,Sense1,1,ID)), retract(concept(Concept,ID)), assert(concept([s(Sym1,Cat,Sense1)|Concept],ID)), selectConcepts(L). selectConcepts([s(X,Cat,Sense)|L]):- !, getConceptId(ID), % else add word assert(word(X,Cat,Sense,1,ID)), % and its concept to database assert(concept([s(X,Cat,Sense)],ID)), selectConcepts(L). %selectConcepts([c(X,_,Cat,Sense)|L]):- % word(X,Cat,Sense,_,ID), !, % if name is already % retract(word(X,Cat,Sense,N1,ID)), % in the database % N2 is N1 + 1, % then increase frequency % assert(word(X,Cat,Sense,N2,ID)), % selectConcepts(L). %selectConcepts([c(X,Symbols,Cat,Sense)|L]):- !, % getConceptId(ID), % assert(word(X,Cat,Sense,1,ID)), % findall(s(Sym,Cat,Sense),member(Sym,Symbols),Syn), % assert(concept([s(X,Cat,Sense)|Syn],ID)), % selectConcepts(L). selectConcepts([_|L]):- selectConcepts(L). /* ======================================================================== Synonyms ======================================================================== */ syn(n,Sym1,Sense1,Sym2,Sense2):- synn(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (nouns) syn(n,Sym1,Sense1,Sym2,Sense2):- synn(Sym2,Sense2,Sym1,Sense1), !. %%% WordNet (nouns) syn(v,Sym1,Sense1,Sym2,Sense2):- synv(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (verbs) syn(v,Sym1,Sense1,Sym2,Sense2):- synv(Sym2,Sense2,Sym1,Sense1), !. %%% WordNet (verbs) syn(a,Sym1,Sense1,Sym2,Sense2):- syna(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (adjectives) syn(a,Sym1,Sense1,Sym2,Sense2):- syna(Sym2,Sense2,Sym1,Sense1), !. %%% WordNet (adjectives) syn(r,Sym1,Sense1,Sym2,Sense2):- synr(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (adverbs) syn(r,Sym1,Sense1,Sym2,Sense2):- synr(Sym2,Sense2,Sym1,Sense1), !. %%% WordNet (adverbs) syn(per,Sym1,Sense1,Sym2,Sense2):- synp(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (names) syn(loc,Sym1,Sense1,Sym2,Sense2):- synp(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (names) syn(org,Sym1,Sense1,Sym2,Sense2):- synp(Sym1,Sense1,Sym2,Sense2), !. %%% WordNet (names) /* ======================================================================== Calculate WordNet ISA Relations (first select all relevant concepts) ======================================================================== */ compISA:- minFreq(Min), setof(s(X,Cat,Sense,ID),N^(word(X,Cat,Sense,N,ID),N>Min),L), !, compISA(L), compISNOTA(L). compISA. /* ======================================================================== Calculate WordNet ISA Relations ======================================================================== */ compISA([]). compISA([s(_,_,_,ID)|L]):- isa(ID,_), !, % already calculated superconcept compISA(L). /* ------------------------------------------------------------------------ Time and Numeric Expressions ------------------------------------------------------------------------ */ compISA([s(_,timex,1,ID1)|L]):- !, % timex addConcept(time,n,5,ID2), assert(isa(ID1,ID2)), compISA([s(time,n,5,ID2)|L]). compISA([s(_,cardinal,1,ID1)|L]):- !, % cardinal addConcept(numeral,n,1,ID2), assert(isa(ID1,ID2)), compISA([s(numeral,n,1,ID2)|L]). /* ------------------------------------------------------------------------ Locations ------------------------------------------------------------------------ */ %compISA([s(Sym1,loc,Sense1,ID1)|L]):- % location in WordNet % isap(Sym1,Sense1,Sym2,Sense2), !, % addConcept(Sym2,n,Sense2,ID2), % assert(isa(ID1,ID2)), % compISA([s(Sym2,n,Sense2,ID2)|L]). compISA([s(_,loc,_,ID1)|L]):- % location not in WordNet addConcept(location,n,1,ID2), !, assert(isa(ID1,ID2)), compISA([s(location,n,1,ID2)|L]). /* ------------------------------------------------------------------------ Organisations ------------------------------------------------------------------------ */ %compISA([s(Sym1,org,Sense1,ID1)|L]):- % organisation in WordNet % isap(Sym1,Sense1,Sym2,Sense2), !, % addConcept(Sym2,n,Sense2,ID2), % assert(isa(ID1,ID2)), % compISA([s(Sym2,n,Sense2,ID2)|L]). compISA([s(_,org,_,ID1)|L]):- % organisation not in WordNet addConcept(organisation,n,1,ID2), !, assert(isa(ID1,ID2)), compISA([s(organisation,n,1,ID2)|L]). /* ------------------------------------------------------------------------ Persons ------------------------------------------------------------------------ */ %compISA([s(Sym1,per,Sense1,ID1)|L]):- % person in WordNet % isap(Sym1,Sense1,Sym2,Sense2), !, % addConcept(Sym2,n,Sense2,ID2), % assert(isa(ID1,ID2)), % compISA([s(Sym2,n,Sense2,ID2)|L]). compISA([s(_,per,_,ID1)|L]):- % person not in WordNet addConcept(somebody,n,1,ID2), !, assert(isa(ID1,ID2)), compISA([s(somebody,n,1,ID2)|L]). /* ------------------------------------------------------------------------ Nouns ------------------------------------------------------------------------ */ % take all isa relations % compISA([s(Sym1,n,Sense1,ID1)|L1]):- % nouns in WordNet % option('--x',true), findall(s(Sym2,n,Sense2,ID2),( isan(Sym1,Sense1,Sym2,Sense2), addConcept(Sym2,n,Sense2,ID2), assert(isa(ID1,ID2)) ), New), New = [_|_], !, append(New,L1,L2), compISA(L2). % take only first isa relation % %compISA([s(Sym1,n,Sense1,ID1)|L]):- % nouns in WordNet % option('--x',false), % isan(Sym1,Sense1,Sym2,Sense2), !, % addConcept(Sym2,n,Sense2,ID2), % assert(isa(ID1,ID2)), % compISA([s(Sym2,n,Sense2,ID2)|L]). /* ------------------------------------------------------------------------ Verbs ------------------------------------------------------------------------ */ compISA([s(Sym1,v,Sense1,ID1)|L]):- % verbs in WordNet (+ ISA) isav(Sym1,Sense1,Sym2,Sense2), !, addConcept(Sym2,v,Sense2,ID2), assert(isa(ID1,ID2)), compISA([s(Sym2,v,Sense2,ID2)|L]). compISA([s(Sym,v,Sense,_)|L]):- % verbs in WordNet (- ISA) synv(Sym,Sense,_,_), !, compISA(L). compISA([s(Sym,v,Sense,_)|L]):- % verbs in WordNet (- ISA) isav(_,_,Sym,Sense), !, compISA(L). /* ------------------------------------------------------------------------ All Other Cases ------------------------------------------------------------------------ */ compISA([s(Sym1,nam,Sense1,ID1)|L]):- % named entity in WordNet isap(Sym1,Sense1,Sym2,Sense2), !, addConcept(Sym2,n,Sense2,ID2), assert(isa(ID1,ID2)), compISA([s(Sym2,n,Sense2,ID2)|L]). compISA([s(Sym,Cat,Sense,ID)|L]):- % outside WordNet word(Sym,Cat,Sense,F,ID), minFreq(Min), F > Min, !, warning('unclassified token: ~p~p~p',[Cat,Sense,Sym]), compISA(L). compISA([_|L]):- compISA(L). /*======================================================================== compISNOTA ========================================================================*/ compISNOTA([]). compISNOTA([s(Sym1,a,Sense1,ID1)|L]):- isnotaa(Sym1,Sense1,Sym2,Sense2), member(s(Sym2,a,Sense2,ID2),L), !, assert(isnota(ID1,ID2)), compISNOTA(L). compISNOTA([_|L]):- compISNOTA(L). /*======================================================================== Get a new concept Id ========================================================================*/ getConceptId(I3):- concept(_,I1), \+ ( concept(_,I2), I2 > I1 ), !, I3 is I1 + 1. getConceptId(1). /*======================================================================== Calculate First-Order Axioms ========================================================================*/ axiomsWN(Axioms):- option('--modal',false), !, findall(isa(A,B),(isa(A,B),\+A=B,\+B=0),ISA), findall(isnota(A,B),isnota(A,B),ISNOTA), % co-hyponyms % findall(isnota(A,B),(isa(A,C), concept([s(_,T,_)|_],A), % isa(B,C), concept([s(_,T,_)|_],B), % A',File2],' ',Command), shell(Command,0), !. createGraph(_,_):- error('failed to execute the dot program',[]). /*------------------------------------------------------------------------ Print Nodes ------------------------------------------------------------------------*/ printNodes([],Stream):- !, nl(Stream). printNodes([I|L],Stream):- concept(X,I), !, format(Stream,' ~p [label="',[I]), printNode(X,Stream), printNodes(L,Stream). printNodes([_|L],Stream):- printNodes(L,Stream). /*------------------------------------------------------------------------ Print Single Node ------------------------------------------------------------------------*/ printNode([s(Sym,Cat,Sense)],Stream):- frequency(Sym,Cat,Sense,F), !, format(Stream,'~p-~p-~p (F=~p)"];~n',[Sym,Cat,Sense,F]). printNode([s(Sym,Cat,Sense)|L],Stream):- frequency(Sym,Cat,Sense,F), !, format(Stream,'~p-~p-~p (F=~p)\\n',[Sym,Cat,Sense,F]), printNode(L,Stream). /*------------------------------------------------------------------------ Word Frequency ------------------------------------------------------------------------*/ frequency(X,C,S,F):- word(X,C,S,F,_), !. frequency(_,_,_,0). /*------------------------------------------------------------------------ Print Relations ------------------------------------------------------------------------*/ printIsa(Stream):- isa(I,J), format(Stream,' ~p -> ~p;~n',[J,I]), fail. printIsa(Stream):- format(Stream,'~n}~n',[]). /*======================================================================== Add Concept ========================================================================*/ addConcept(Sym,Cat,Sense,ID):- concept(Concept,ID), member(s(Sym,Cat,Sense),Concept), !. addConcept(Sym1,Cat,Sense1,ID):- concept(Concept,ID), member(s(Sym2,Cat,Sense2),Concept), syn(Cat,Sym1,Sense1,Sym2,Sense2), retract(concept(Concepts,ID)), assert(concept([s(Sym1,Cat,Sense1)|Concepts],ID)), !. addConcept(Sym,Cat,Sense,ID):- getConceptId(ID), assert(concept([s(Sym,Cat,Sense)],ID)). /*======================================================================== Check for inconsistencies ========================================================================*/ checkConsBK:- isa(A,B), isa(A,C), \+ C=B, !, format('inconsistent node ~p has two parents ~p and ~p~n',[A,B,C]). checkConsBK. /*======================================================================== Cut down redundant nodes ========================================================================*/ cutDownMWN:-!, findall(I,concept(_,I),C), cutDown(C). cutDown([]). cutDown([A|L]):- isa(A,B), %%% remove "hanging" nodes that are not \+ isa(_,A), %%% terminal symbols \+ word(_,_,_,_,A), !, retract(isa(A,B)), retract(concept(_,A)), cutDown(L). cutDown([B|L]):- isa(A,B), isa(B,C), %%% two other nodes, but not for nodes that have an instance \+ word(_,_,_,_,B), \+ (isa(D,B), \+ D=A), !, retract(isa(A,B)), retract(isa(B,C)), retract(concept(_,B)), assert(isa(A,C)), cutDown(L). cutDown([_|L]):- cutDown(L). /*======================================================================== Add Top Concept (if there is not one yet) ========================================================================*/ addTopMWN:- concept(E,B), member(s(event,n,1),E), %%% place all verbs under concept(V,A), member(s(_,v,_),V), %%% the event-1 concept \+ isa(A,_), !, assert(isa(A,B)), addTopMWN. addTopMWN:- concept(_,B), \+ isa(B,_), %%% if there are at least two concept(_,C), \+ B=C, \+ isa(C,_), !, %%% different nodes B and C without parent assert(concept([s('_top',n,0)],0)), %%% then introduce a common top node assert(isa(B,0)), assert(isa(C,0)), addTopMWN1. addTopMWN. addTopMWN1:- %%% second part of introducing top node concept([s('_top',n,0)],I), %%% introduce top for all other nodes concept(_,B), \+ B=I, %%% without parents \+ isa(B,_), !, assert(isa(B,I)), addTopMWN1. addTopMWN1. /* ======================================================================== Size WordNet (number of disjoint concepts) ======================================================================== */ sizeMWN(Size):- findall(X,isa(X,_),L), length(L,Size). /* ======================================================================== Symbol Stop List ======================================================================== */ stoplist(')',_). stoplist('(',_). stoplist('"',_). stoplist('%',_). stoplist('$',_). stoplist('=',_). stoplist('*',_). stoplist('/',_). stoplist('#',_). stoplist('+',_). stoplist('\\',_). stoplist('>',_). stoplist('<',_). stoplist('\240',_). stoplist(quantity,n). stoplist(more,n). /*======================================================================== Output MWN (prolog) ========================================================================*/ outputMWN(Dir,File):- atomic_list_concat([Dir,'/',File,'.mwn'],Name), open(Name,write,Stream), printTerminals(Stream), close(Stream). /*======================================================================== Output terminal symbols ========================================================================*/ printTerminals(Stream):- format(Stream,'%~n% word(+Word, +Cat, +Sense, +Frequency, +ConceptID).~n%~n',[]), word(X,C,S,N,I), \+ I = 0, format(Stream,'~q.~n',[word(X,C,S,N,I)]), fail. printTerminals(Stream):- format(Stream,'%~n% concept(+SynSet, +ConceptID).~n%~n',[]), concept(I,J), format(Stream,'~q.~n',[concept(I,J)]), fail. printTerminals(Stream):- format(Stream,'%~n% isa(+SubConceptID, +SuperConceptID).~n%~n',[]), isa(I,J), format(Stream,'~p.~n',[isa(I,J)]), fail. printTerminals(Stream):- format(Stream,'%~n% isnota(+ConceptID, +ConceptID).~n%~n',[]), isnota(I,J), format(Stream,'~p.~n',[isnota(I,J)]), fail. printTerminals(_). /*======================================================================== Adjacent Indexes ========================================================================*/ adjacent([I],[J]):- !, J is I + 1. adjacent(Is,Js):- member(I,Is), member(J,Js), J is I + 1, !. /*------------------------------------------------------------------------ ALL BELOW IS NOT USED CURRENTLY --- SUBJECT TO REVISION! Unknown word is a nationality unknownWord(Sym,_,Freq1):- nationality(Sym,_), minFreq(Min), word(inhabitant,n,Freq2,Id), Freq2 > Min, getConceptId(NewId), assert(word(Sym,p,Freq1,NewId)), assert(concept([Sym],NewId)), assert(isa(NewId,Id)), !. ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ Unknown word is known as a compound (e.g. website -> web site) unknownWord(Sym1,n,Freq1):- minFreq(Min), name(Sym1,Codes1), append(Prefix,Postfix,Codes1), append(Prefix,[95|Postfix],Codes2), name(Sym2,Codes2), word(Sym2,Cat,Freq2,Id), Freq2 > Min, \+ Id=0, assert(word(Sym1,Cat,Freq1,Id)), retract(concept(Concepts,Id)), assert(concept([Sym1|Concepts],Id)), !, true. % format('Added word ~p similar to ~p~n',[Sym1,Sym2]). ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ Unknown compound word is known as a non compound (e.g. web site -> website) unknownWord(Sym1,n,Freq1):- minFreq(Min), name(Sym1,Codes1), append(Prefix,[95|Postfix],Codes1), append(Prefix,Postfix,Codes2), name(Sym2,Codes2), word(Sym2,Cat,Freq2,Id), Freq2 > Min, assert(word(Sym1,Cat,Freq1,Id)), retract(concept(Concepts,Id)), assert(concept([Sym1|Concepts],Id)), !, true. % format('Added word ~p similar to ~p~n',[Sym1,Sym2]). ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ Unknown compound word is hyponym of existing word E.g. winter_sport ISA sport unknownWord(Sym1,n,Freq1):- minFreq(Min), name(Sym1,Codes1), append(_,[95|Codes2],Codes1), name(Sym2,Codes2), word(Sym2,Cat,Freq2,Id), Freq2 > Min, getConceptId(NewId), assert(word(Sym1,Cat,Freq1,NewId)), assert(concept([Sym1],NewId)), assert(isa(NewId,Id)), !, true. % format('Hyponym word ~p of ~p~n',[Sym1,Sym2]). ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ Unknown hyphenated word is hyponym of existing word E.g. Asian-American ISA American unknownWord(Sym1,Cat,Freq1):- member(Cat,[n,p]), minFreq(Min), name(Sym1,Codes1), append(_,[45|Codes2],Codes1), name(Sym2,Codes2), word(Sym2,Cat,Freq2,Id), Freq2 > Min, getConceptId(NewId), assert(word(Sym1,Cat,Freq1,NewId)), assert(concept([Sym1],NewId)), assert(isa(NewId,Id)), !, true. % format('Hyponym word ~p of ~p~n',[Sym1,Sym2]). ------------------------------------------------------------------------*/