:- 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("~n"), forall(concept(C), ( induced_rule(C, Ctx), format(" ~n", [C, Ctx]), forall(member(W,C), format(" ~n", [W])), format(" ~n") )), format("~n"). :- format("=== PocketLearn ILP Induction (XSLT-generated from PocketForthConcepts) ===~n"), induce_rules, format("~n=== Proposing new members ===~n"), propose_new_members.