
    niE                         S SK JrJr  S SKrS SKJs  Jr  S SK	J
r
  S SKJr   " S S\R                  R                  5      rg)    )ListTupleN)Fact)ModelInterfaceOptionsc                      ^  \ rS rSrSrSS\\   S\S\4U 4S jjjrS\	S\	S	\\
   4S
 jrSS\	S\	S	\\R                  \R                  \\
   4   4S jjrSrU =r$ )LogicIntegratedClassifier
   z
Class to integrate a PyTorch model with PyReason. The output of the model is returned to the
user in the form of PyReason facts. The user can then add these facts to the logic program and reason using them.
class_names
identifierinterface_optionsc                 Z   > [         [        U ]  5         Xl        X l        X0l        X@l        g)a#  
:param model: PyTorch model to be integrated.
:param class_names: List of class names for the model output.
:param identifier: Identifier for the model, used as the constant in the facts.
:param interface_options: Options for the model interface, including threshold and snapping behavior.
N)superr   __init__modelr
   r   r   )selfr   r
   r   r   	__class__s        m/home/james-whalen/.local/lib/python3.13/site-packages/pyreason/scripts/learning/classification/classifier.pyr   "LogicIntegratedClassifier.__init__   s)     	'79
&$!2    t1t2returnc                     / nU R                    H?  n[        U SU R                   S3U R                   SU S3XS9nUR                  U5        MA     U$ )z
Return PyReason facts to create nodes for each class. Each class node will have bounds `[1,1]` with the
 predicate corresponding to the model name.
:param t1: Start time for the facts
:param t2: End time for the facts
:return: List of PyReason facts
()--factname
start_timeend_time)r
   r   r   append)r   r   r   factscfacts         r   get_class_facts)LogicIntegratedClassifier.get_class_facts   s_     !!A1#Qt/q14??:K1QCu8UbdrDLL " r   c           	      X   U R                  U5      n[        R                  " USS9R                  5       nU R                  n[
        R                  " UR                  UR                  UR                  S9nXW:  nUR                  b  [
        R                  " UR                  UR                  UR                  S9n	UR                  (       a  U	O)[
        R                  " SUR                  UR                  S9n
UR                  (       a  U	O)[
        R                  " SUR                  UR                  S9nORUR                  (       a  UO[
        R                  " U5      n
UR                  (       a  UO[
        R                  " U5      n[
        R                  " X[
        R                  " U5      5      n[
        R                  " X[
        R                  " U5      5      n/ n[!        [#        U R$                  5      5       H:  nX   R'                  5       nX   R'                  5       nUR)                  UU/5        M<     / n[+        U R$                  U5       HQ  u  nnUu  nnU SU R,                   SUS S	US S
3n[/        UU R,                   SU S3X#S9nUR)                  U5        MS     XEU4$ )z
Forward pass of the model
:param x: Input tensor
:param t1: Start time for the facts
:param t2: End time for the facts
:return: Output tensor
   )dim)dtypedeviceg        g      ?r   z) : [z.3fz, ]r   r   r   )r   Fsoftmaxsqueezer   torchtensor	thresholdr+   r,   
snap_valueset_lower_boundset_upper_bound
zeros_like	ones_likewhererangelenr
   itemr"   zipr   r   )r   xr   r   outputprobabilitiesoptsr3   	conditionr4   	lower_val	upper_vallower_boundsupper_boundsbounds_listilowerupperr#   
class_nameboundsfact_strr%   s                          r   forward!LogicIntegratedClassifier.forward*   s<    A 		&a088:%% LL}7J7JS`SgSgh	!-	??&doo]=P=PYfYmYmnJ&*&:&:
SXeXkXkTaThThAjI&*&:&:
SXeXkXkTaThThAjI *.)=)=5CSCSTaCbI)-)=)=5??S`CaI {{99I9I-9XY{{99WX s4++,-A O((*E O((*Eu~. . "%d&6&6"DJ!LE5$Qt&7uU3Kr%PSTUVH$//):!J<u'MZ\jDLL	 #E
 e++r   )r
   r   r   r   )
classifierN)r   r   )__name__
__module____qualname____firstlineno____doc__r   strr   r   intr   r&   r   r1   TensorrN   __static_attributes____classcell__)r   s   @r   r   r   
   s    349 3# 3i~ 3 3# 3 4: 0,S 0,# 0,eELL%,,X\]aXb<b6c 0, 0,r   r   )typingr   r   torch.nnr1   torch.nn.functionalnn
functionalr.   pyreason.scripts.facts.factr   /pyreason.scripts.learning.utils.model_interfacer   Moduler    r   r   <module>rd      s-        , QP, P,r   