| :- dynamic member/2, induced_rule/2, cooccur/3. | |
| % --- Background co-occurrence facts (generated by XSLT from ontology.xml) --- | |
| cooccur('stack','stack_op',1). | |
| cooccur('dup','stack_op',3). | |
| cooccur('drop','stack_op',3). | |
| cooccur('swap','stack_op',3). | |
| cooccur('over','stack_op',2). | |
| cooccur('operations','stack_op',2). | |
| cooccur('dictionary','dict_op',2). | |
| cooccur('words','dict_op',3). | |
| cooccur('contains','dict_op',3). | |
| cooccur('holds','dict_op',0). | |
| cooccur('compiler','compiler_word',2). | |
| cooccur('compiles','compiler_word',2). | |
| cooccur('colon','compiler_word',2). | |
| cooccur('semicolon','compiler_word',3). | |
| cooccur('defined','compiler_word',1). | |
| cooccur('interpreter','interpreter_word',1). | |
| cooccur('interprets','interpreter_word',1). | |
| cooccur('pocketforth','engine_word',0). | |
| cooccur('engine','engine_word',2). | |
| cooccur('pocket','engine_word',1). | |
| cooccur('executes','engine_word',2). | |
| cooccur('inside','engine_word',1). | |
| cooccur('harness','engine_word',0). | |
| cooccur('transformer','meta_word',0). | |
| cooccur('xslt','meta_word',2). | |
| cooccur('asp','meta_word',3). | |
| cooccur('xml','meta_word',3). | |
| cooccur('code','meta_word',3). | |
| cooccur('generates','meta_word',2). | |
| cooccur('validates','meta_word',3). | |
| cooccur('architecture','meta_word',3). | |
| cooccur('constraints','meta_word',1). | |
| cooccur('learns','learning_word',5). | |
| cooccur('statistical','learning_word',3). | |
| cooccur('relationships','learning_word',5). | |
| cooccur('text','learning_word',1). | |
| cooccur('cooccurrence','learning_word',2). | |
| cooccur('pmi','learning_word',2). | |
| cooccur('embeddings','learning_word',6). | |
| cooccur('neural','learning_word',3). | |
| cooccur('network','learning_word',4). | |
| cooccur('capture','learning_word',2). | |
| cooccur('similarity','learning_word',1). | |
| % --- Concept hierarchy --- | |
| concept(forth_word). | |
| is_a(forth_word, root). | |
| concept(stack_op). is_a(stack_op, forth_word). | |
| concept(dict_op). is_a(dict_op, forth_word). | |
| concept(compiler_word). is_a(compiler_word, forth_word). | |
| concept(interpreter_word). is_a(interpreter_word, forth_word). | |
| concept(engine_word). is_a(engine_word, forth_word). | |
| concept(meta_word). is_a(meta_word, forth_word). | |
| concept(learning_word). is_a(learning_word, forth_word). | |
| % --- Seed members --- | |
| member('stack', stack_op). | |
| member('dup', stack_op). | |
| member('drop', stack_op). | |
| member('swap', stack_op). | |
| member('over', stack_op). | |
| member('operations', stack_op). | |
| member('dictionary', dict_op). | |
| member('words', dict_op). | |
| member('contains', dict_op). | |
| member('compiler', compiler_word). | |
| member('compiles', compiler_word). | |
| member('colon', compiler_word). | |
| member('semicolon', compiler_word). | |
| member('defined', compiler_word). | |
| member('interpreter', interpreter_word). | |
| member('interprets', interpreter_word). | |
| member('pocketforth', engine_word). | |
| member('engine', engine_word). | |
| member('pocket', engine_word). | |
| member('executes', engine_word). | |
| member('xslt', meta_word). | |
| member('asp', meta_word). | |
| member('xml', meta_word). | |
| member('generates', meta_word). | |
| member('validates', meta_word). | |
| member('learns', learning_word). | |
| member('statistical', learning_word). | |
| member('relationships', learning_word). | |
| member('embeddings', learning_word). | |
| member('neural', learning_word). | |
| member('network', learning_word). | |
| % --- ILP Engine (generated by XSLT from ontology.xml) --- | |
| candidate_score(Concept, Context, Precision, Recall, F1, PosCovered) :- | |
| findall(W, member(W, Concept), Pos), | |
| length(Pos, PosTotal), | |
| PosTotal > 0, | |
| findall(W, (member(W, Concept), cooccur(W, Context, _)), Covered), | |
| length(Covered, PosCovered), | |
| findall(W, cooccur(W, Context, _), AllWithContext), | |
| length(AllWithContext, AllTotal), | |
| (AllTotal > 0 -> Precision is PosCovered / AllTotal ; Precision = 0), | |
| Recall is PosCovered / PosTotal, | |
| (Precision + Recall > 0 -> F1 is 2*Precision*Recall/(Precision+Recall) ; F1 = 0). | |
| best_rule_for_concept(Concept, BestContext, BestF1) :- | |
| setof(Context, W^Cnt^cooccur(W, Context, Cnt), Contexts), | |
| findall((F1,Context), candidate_score(Concept, Context, _, _, F1, _), Scores), | |
| Scores \= [], | |
| max_member((BestF1, BestContext), Scores). | |
| induce_rules :- | |
| retractall(induced_rule(_,_)), | |
| forall(concept(C), | |
| ( best_rule_for_concept(C, Context, F1), | |
| F1 > 0.2, | |
| assertz(induced_rule(C, Context)), | |
| format("Induced: is_a(W, ~w) :- cooccur(W, '~w'). F1=~2f~n", [C, Context, F1]) | |
| ; format("No rule for ~w (insufficient evidence)~n", [C]) | |
| )). | |
| propose_new_members :- | |
| forall( | |
| ( cooccur(W, Context, Cnt), Cnt >= 1, | |
| induced_rule(Concept, Context), | |
| \+ member(W, Concept), | |
| \+ W = Concept ), | |
| format("Propose: ~w should be is_a(~w) because cooccurs with '~w' cnt=~w~n", | |
| [W, Concept, Context, Cnt])). | |
| generate_ontology_xml :- | |
| format("<ontology name=\"Induced-Next\">~n"), | |
| forall(concept(C), | |
| ( induced_rule(C, Ctx), | |
| format(" <concept id=\"~w\" is_a=\"forth_word\" induced_context=\"~w\">~n", [C, Ctx]), | |
| forall(member(W,C), format(" <member word=\"~w\"/>~n", [W])), | |
| format(" </concept>~n") | |
| )), | |
| format("</ontology>~n"). | |
| :- format("=== PocketLearn ILP Induction (XSLT-generated from PocketForthConcepts) ===~n"), | |
| induce_rules, | |
| format("~n=== Proposing new members ===~n"), | |
| propose_new_members. | |