########################################################################
#
# File Name:            InferenceEngine.py
#
# Documentation:        http://docs.4suite.org/4Rdf/Inference/InferenceEngine.py.html
#
"""

WWW: http://4suite.org/4RDF         e-mail: support@4suite.org

Copyright (c) 1999 Fourthought Inc, USA.   All Rights Reserved.
See  http://4suite.org/COPYRIGHT  for license and copyright information
"""
import sys
from Ft.Rdf import Model, Statement
from Ft.Rdf.Drivers import Memory

import Common

class InferenceEngine:
    CHAINING = 2
    READY = 1
    STOPPED = 3
    outStream = sys.stdout
    def __init__(self, core, rules = None):
        self.core = core
        mem = Memory.DbAdapter('workspace')
        mem.begin()
        self.workspace = Model.Model(mem)
        self.rules = []
        if rules:
            self.rules = rules
        self.state = InferenceEngine.READY
        return

    def execute(self,items,extParams = None, context=None):
        if extParams == None:
            extParams = {}
        if context == None:
            context = Common.Context(external_params = extParams)
        
        self.state = InferenceEngine.CHAINING
        context.fireRules = 1
        res = []
        for item in items:
            rt = item.execute(self,context)
            if rt is not None:
                res.append(rt)
        self.state = InferenceEngine.READY
        context.fireRules = 0
        return res

    def fire(self,context):
        self.state = InferenceEngine.CHAINING
        for rule in self.rules:
            rule.fire(self,context)
        self.state = InferenceEngine.READY
        return
        

    def complete(self, subject, predicate, object):
        results = self.core.complete(subject, predicate, object)
        results.extend(self.workspace.complete(subject, predicate, object))
        return results

    def contains(self, statement):
        return (self.workspace.contains(statement) or
                self.core.contains(statement))

    def narrowRules(self, predicateId, args):
        #An optimization opportunity, but for now, just return them all
        return self.rules

