;;; -*- Mode: LISP; Syntax: Common-lisp; Package: LOOM; Base: 10. -*-

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                             ;
;  Copyright (c) 1988, 1995, 1999 by the University of Southern California    ;
;  All rights reserved.                                                       ;
;                                                                             ;
;  Permission to use, copy, modify, and distribute this software and its      ;
;  documentation in source and binary forms for non-commercial purposes       ;
;  and without fee is hereby granted, provided that this notice               ;
;  be reproduced in any copy or modification thereof, and that                ;
;  any documentation, advertising materials, and other materials related      ;
;  to such distribution and use acknowledge that the software was             ;
;  developed by the University of Southern California, Information            ;
;  Sciences Institute.  The name of the University may not be used to         ;
;  endorse or promote products derived from this software without             ;
;  specific prior written permission.                                         ;
;                                                                             ;
;  THE UNIVERSITY OF SOUTHERN CALIFORNIA MAKES NO REPRESENTATIONS ABOUT THE   ;
;  SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  THIS SOFTWARE IS PROVIDED   ;
;  "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,          ;
;  WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND          ;
;  FITNESS FOR A PARTICULAR PURPOSE.                                          ;
;                                                                             ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; TIME-QUERY.LISP (ABOX)

(in-package "LOOM")
  ;;
;;;;;; Generation functions for :becomes, :ceases, :detects & :undetects
  ;;

(defun generate-plausible-transitions (instance conceptOrRelation agentTime)
  ;; Returns all plausible times when "instance" could have had a change
  ;;   in "conceptOrRelation".  These times will need to be filtered to
  ;;   find actual transitions due to derived information;
  ;; Tricky:  Concept TEMPORAL-INCOHERENT must be handled as a special
  ;;   case since it is determined at a low level in the data structure;
  (declare (inline generate-typed-world-transitions))
  (cond ((eq conceptOrRelation (loom-constant TEMPORAL-INCOHERENT))
         (generate-temporal-incoherent-transitions instance agentTime))
        ((implied-computed-features conceptOrRelation)
         ;; Use this because we don't know how to derive more specific
         ;;   bounds for computed feature depend-ons; TAR 10/5/93
         (generate-all-world-transitions instance agentTime))
        (t
         (generate-typed-world-transitions instance
				      (temporal-depend-ons conceptOrRelation)
				      agentTime
                                      nil))) )

(defun generate-plausible-world-role-transitions (instance relation agentTime)
  (declare (inline generate-plausible-transitions))
  (generate-plausible-transitions instance relation agentTime))

(defun generate-becomes-concept (instance concept agentTime)
  ;; Generate all possible times!
  (declare (inline generate-plausible-transitions))
  (generate-plausible-transitions instance concept agentTime) )

(defun generate-ceases-concept (instance concept agentTime)
  ;; Generate all possible times!
  (declare (inline generate-plausible-transitions))
  (generate-plausible-transitions instance concept agentTime) )

(defun generate-becomes-relation (instance relation agentTime)
  ;; Generate all possible times!
  (declare (inline generate-plausible-transitions))
  (generate-plausible-transitions instance relation agentTime) )

(defun generate-ceases-relation (instance relation agentTime)
  ;; Generate all possible times!
  (declare (inline generate-plausible-transitions))
  (generate-plausible-transitions instance relation agentTime) )


  ;;
;;;;;; Methods specialized on TIME-MAP for temporal queries.
  ;;

;; GET-SLOT-VALUE, GET-SLOT-VALUES, HAS-INSTANCE-P and FIND-TYPE&RESIDUE-FEATURES


(defmethod has-instance-p ((concept UNARY-CONCEPT) (instance TIME-MAP))
  ;; Situation: *query-agent-time* and *query-world-time* must both be bound.
  ;; If "concept" is temporal, then we need to do a time map lookup to see
  ;;    if "instance" belongs to "concept".
  ;;    Otherwise, we need to pass the function on to the regular
  ;;      (non-temporal) version.
  (if (temporal-p concept)
      (or (has-direct-slot-value instance
				 :type concept) ;tar 4/22/93 
	  (has-bc-instance-p concept (real-instance instance)
			     nil nil))	;tar 1/8/93  
      (has-instance-p concept
		      (get-agent-time-offset-instance 
			(real-instance instance)))) )

(defmethod get-slot-value ((instance TIME-MAP) relation)
  ;; Situation: *query-agent-time* and *query-world-time* must both be bound.
  ;; We need to find the appropriate object for the slot (relation) and
  ;;    test to make sure it is temporal.  If it isn't, then we need
  ;;    to pass the function on to the regular (non-time map code)
  (if (temporal-p relation)
    (if (role-is-single-valued-p relation)	; tar 4/26/93
      (first (direct-slot-value instance relation))
      (direct-slot-value instance relation))	; tar 4/22/93
    (get-slot-value (get-agent-time-offset-instance 
                     (real-instance instance))
                    relation)) )
  
(defmethod get-slot-values ((instance TIME-MAP) relation)
  ;; Situation: *query-agent-time* and *query-world-time* must both be bound.
  ;; We need to find the appropriate object for the slot (relation) and
  ;;    test to make sure it is temporal.  If it isn't, then we need
  ;;    to pass the function on to the regular (non-time map code)
  (if (temporal-p relation)
    (direct-slot-value instance relation)	; tar 4/22/93
    (get-slot-values (get-agent-time-offset-instance 
                      (real-instance instance))
                     relation)) )

(defmethod find-type&residue-features ((self TIME-MAP))
  ;; Return two values for "self":
  ;;    (1) the unification of the asserted list of conjuncts, including
  ;;  the non-temporal ones;
  ;;    (2) any non-temporal residue features (temporal instances don't
  ;;   have attached features);
  (multiple-value-bind (atemporalType atemporalResidue)
      (find-type&residue-features (get-agent-time-offset-instance
				   (real-instance self)))
    (values
     (compute-unified-type
      (most-specific-conjuncts
       (most-specific-concepts
	(cons atemporalType
	      (mapcar #'find-concept (direct-slot-value self :type)))))
      (intrinsic-concept (real-instance self)))
     atemporalResidue) ))

(defmethod get-cached-types ((self TIME-MAP))
  ;; Return the cached types for "self", including the non-temporal ones;
  (let ((atemporalTypes
         (get-cached-types (get-agent-time-offset-instance
                            (real-instance self)))))
    (append (mapcar #'find-concept (direct-slot-value self :type))
            atemporalTypes) ))

