logic-and-learning-lab/Popper

invoking popper from another python program

Closed this issue · 4 comments

it looks like this line in Settings will never get hit, because it's within the if kbpath == False: condition. for this reason, it doesn't seem currently possible to run Popper from another Python program (as in the README). would it be okay to move the line to outside the condition?

another related question about invoking from python: if I call learn_solution multiple times within the same run, is it possible that there will be interference between the calls, or should they be completely independent? I'm seeing some warnings suggesting that there might be interference

Just pushed a fix for the first issue.

It should work as follows:

from popper.util import Settings, print_prog_score
from popper.loop import learn_solution

kbpath='examples/trains4/'
exfile=kbpath+'exs.pl'
bkfile=kbpath+'bk.pl'
biasfile=kbpath+'bias.pl'
settings = Settings(cmd_line=False, ex_file=exfile, bk_file=bkfile, bias_file=biasfile)

prog, score, stats = learn_solution(settings)
if prog != None:
    print_prog_score(prog, score)

For the second question, there is a problem with Prolog/pyswip that prohibits us doing what you want to do.

The workaround is to spawn a new process for each call to Popper like so:

import multiprocessing
from multiprocessing import Process
from popper.util import Settings, print_prog_score
from popper.loop import learn_solution

def do_it__(settings, values):
    prog, score, stats = learn_solution(settings)
    values['prog'] = prog
    values['score'] = score

def do_it(settings):
    manager = multiprocessing.Manager()
    return_dict = manager.dict()
    p = Process(target=do_it__, args=(settings, return_dict))
    p.start()
    p.join()
    print_prog_score(return_dict['prog'], return_dict['score'])

def main():
    kbpath='examples/trains1/'
    exfile=kbpath+'exs.pl'
    bkfile=kbpath+'bk.pl'
    biasfile=kbpath+'bias.pl'

    settings = Settings(cmd_line=False, ex_file=exfile, bk_file=bkfile, bias_file=biasfile)
    do_it(settings)

    kbpath='examples/iggp-minimal-decay/'
    exfile=kbpath+'exs.pl'
    bkfile=kbpath+'bk.pl'
    biasfile=kbpath+'bias.pl'

    settings = Settings(cmd_line=False, ex_file=exfile, bk_file=bkfile, bias_file=biasfile)
    do_it(settings)

if __name__ == "__main__":
    main()

It is not elegant but works

that works, thanks!