I'm having trouble with a personal Prolog exercise. For context, the idea is to make a little digital logic tool which makes cell instances and pin connections. The hope is to let the program manage pin connection details, while the user can say, hey, connect these two instances together.
I don't how how to add a constraint which says that a pin connection shouldn't be made if the pin is already connected. My program goes into an infinite loop.
I also don't know if my approach is sane. Is there a better way to approach this problem in Prolog? Is Prolog just not cut out for my task? I am considering using assertz to create dynamic rules, but that seems to be more trouble, but maybe it's a smart way to go? I don't know.
What's going on:
connect(...) is the command to specify the what instances should be connected. They are being connected by instance name. And, connected(...) should be the result. So,
connected(...) :- connect(...) , other constraints, not(has_driver(...)). The trouble comes in because has_driver(...) looks at all the connected(...) items that already exist with bound variables. This is where a loop potentially happens. Surely I'm conceptually off here with the recursion. I need to make a stop case, but what would that possibly look like?
Strangely, the rule file seems to load without issue, but I get an infinite loop when I run the query: connected(SN, DN, SP, DP).
Here is my rule file so far....
type(pin_function, pf_bit). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Little cell library %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% FLOP type(cell, c_flop). cell_has_pin_func_src(c_flop, q , pf_bit). cell_has_pin_func_dst(c_flop, d , pf_bit). cell_has_pin_func_dst(c_flop, clk, pf_clk). cell_has_pin_func_dst(c_flop, rst, pf_rst). %%% NAND GATE type(cell, c_nand2). cell_has_pin_func_src(c_nand2, q, pf_bit). cell_has_pin_func_dst(c_nand2, a, pf_bit). cell_has_pin_func_dst(c_nand2, b, pf_bit). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Try to make a connection %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% instance(Name) :- instantiate(Cell, Name), type(cell, Cell). inst_is_type(Name, Type) :- instance(Name), instantiate(Cell, Name), type(Cell, Type). has_driver(DN, DP) :- connected( _, DN, _, DP). has_load(SN, SP) :- connected(SN, _, SP, _). connected(SN, DN, SP, DP) :- connect(SN, DN, Pin_Func), % Source, Dest, pin function instantiate(Src_C, SN), instantiate(Dst_C, DN), cell_has_pin_func_src(Src_C, SP, Pin_Func), cell_has_pin_func_dst(Dst_C, DP, Pin_Func). %not(has_driver(DN, DP)). % <<<<------Uncomment this line for trouble has_driver(DN, DP) :- connected( _, DN, _, DP). has_load(SN, SP) :- connected(SN, _, SP, _). %%%Try a little digital design instantiate(c_flop, ff1). instantiate(c_flop, ff2). connect(ff2, ff1, pf_bit). connect(ff1, ff2, pf_bit).
has_driverwants to prevent them from being accepted... in an infinite loop. I think the way forward would be to rewritehas_driverso it doesn't callconnected, then introduce a list of connections rather than just 2.has_driver(DN, DP)andhas_load(SN, SP)are in twice (not that removing the duplicates solves the infinite-loop problem). Its best to follow swi-prolog's load-time warning to keep predicates together, to spot such mistakes easier.