Search code examples
pythonprologsegmentation-faultrosswi-prolog

Segmentation Fault While Querying the KB using pyswip with ROS


I built a ROS Package to run this script called planner_node.py to interface with Prolog Knowledge Base(KB):

#! /bin/env python3

from pyswip import Prolog
import rospy
from std_msgs.msg import String

class planner:

    def __init__(self, scene_file="src/mmi/scenes/test.pl"):

        self.scene_file = scene_file
        self.data = None
        self.prolog = Prolog()
        self.prolog.consult(self.scene_file)
        self.init_ros()

    def init_ros(self):

        rospy.init_node("planner_node")
        self.rate = rospy.Rate(10)
       
        self.what_next = rospy.Publisher("what_next_topic", String, queue_size=10)
        self.check_sat = rospy.Publisher("check_sat_topic", String, queue_size=10)
        rospy.Subscriber('check_sat_topic', String, self.proceed_next_action)
       

    def get_plan_status(self):
        plan_done = list(self.prolog.query("plan_done(A)."))[0]['A']
        if plan_done == 'true':
            result = True
        else:
            result = False
        return result

    def proceed_next_action(self, data):
        self.get_next_action()
    
    # publishes on what_next_topic
    def get_next_action(self):
        if self.get_plan_status():
            self.what_next.publish(self.curr_action_id)
            return
           
        ####### get the next action
        next_actions = list(self.prolog.query("pending_actions(Action_List)."))
        act = next_actions[0]
        act_list = act['Action_List']
        self.curr_action_id = act_list[0]

        self.prolog = self.apply_action(self.prolog, self.curr_action_id)

        self.data = self.curr_action_id
       
    def list_to_string(self, list1):
        if list1 == []:
            return "[]"
        result = "["
        for elt in list1:
            result += str(elt)
            result += ","

        return result[:-1] + "]"

    def apply_action(self, prolog, curr_action_id):
        """
        updates the data in the prolog file self.file_path
        """

        print("applying "+str(curr_action_id)+"  ... ")
       
        ############
        all_applied_acts = list(prolog.query("all_applied_actions(A)."))[0]['A']
        all_applied_actions = "all_applied_actions("+self.list_to_string(all_applied_acts)+")"
        prolog.retract(all_applied_actions)

        all_applied_acts.insert(0,curr_action_id)
        all_applied_actions = "all_applied_actions("+self.list_to_string(all_applied_acts)+")"
        prolog.assertz(all_applied_actions)
        ############
        pending = list(prolog.query("pending_actions(A)."))[0]['A']
        pending_actions = "pending_actions("+self.list_to_string(pending)+")"
        prolog.retract(pending_actions)

        pending.remove(curr_action_id)
        pending_actions = "pending_actions("+self.list_to_string(pending)+")"
        prolog.assertz(pending_actions)
        ############
        if pending == []:
            prolog.assertz('plan_done(true)')
            prolog.retract('plan_done(false)')
        ############

        return prolog

## Main
if __name__ == '__main__':

    planner1 = planner()
    planner1.get_next_action()   

    while not rospy.is_shutdown():
        planner1.what_next.publish(planner1.data)
        planner1.check_sat.publish("yes")

Here is the Knowledge Base test.pl:

:- dynamic(all_applied_actions/1).
:- dynamic(pending_actions/1).
:- dynamic(plan_done/1).

% % % % % % % % % % % % % % % %

all_applied_actions([]).
pending_actions([2,3,4,6,7,8,10,11,12,14]).

plan_done(false).

% % % % % % % % % % % % % % % %

I get this Error: Segmentation fault (core dumped) while running this rosnode. It is probably caused by the prolog queries but I do not know where is the issue nor how to fix it.

Can you please tell me how to resolve this segmentation fault please?


Solution

  • I resolved the issue by using rosprolog instead of pyswip.

    Here is an example

    #!/usr/bin/env python
    
    import roslib; roslib.load_manifest('rosprolog')
    
    import rospy
    from rosprolog_client import PrologException, Prolog
    
    if __name__ == '__main__':
        rospy.init_node('example_query_prolog_kb')
        prolog = Prolog()
        query = prolog.query("perishable(X), location(X,Y,_)")
        for solution in query.solutions():
            print 'Foenter code hereund solution. Product: %s, Location: %s' % (solution['X'], solution['Y'])
        query.finish()