I just tried that, works like a charm, eh voila a left recursive rule,
or even worse a double recursive rule. It profits from the fact
that SWI-Prolog tabling always terminates for Datalog:
?- learn(X).
X = (anc(_A, _B):-parent(_, _B), parent(_A, _)) ;
X = (anc(_A, _B):-anc(_C, _B), anc(_A, _C);parent(_A, _B))
Etc..
But I guess my invention generator is a little bit too random.
It does not use some higher order templates, it freely
invents disjunctions and conjunctions as rule body from
a freely invented list of variables, also freely invents the head.
But its relatively fast. The tabling is controlled via
abolish_all_tables/0 and untable/1 like here:
validate((H :- B)) :-
functor(H, anc, 2),
abolish_all_tables,
untable(anc/2),
retractall(anc(_,_)),
assertz((H :- B)),
table(anc/2),
forall(panc(X,Y), anc(X,Y)),
forall(nanc(X,Y), \+ anc(X,Y)).
The rest is generate and test:
% learn(+Rule)
learn(Rule) :-
repeat,
invent(Rule),
validate(Rule).
The invent/1 predicate is written like a fuzz tester.