(***********************************************************************)
(*                                                                     *)
(*                                 GALAX                               *)
(*                            XML Query Engine                         *)
(*                                                                     *)
(*  Copyright 2000, Lucent Technologies.                               *)
(*  Distributed only by permission.                                    *)
(*                                                                     *)
(***********************************************************************)

(* $Id: datamodel.mli,v 1.34 2002/10/06 03:41:27 simeon Exp $ *)

(**************************************)
(* *This* is the XML Query Data Model *)
(**************************************)

open Simple
open Decimal

(*******************************************)
(* Caml types used in the module interface *)
(*******************************************)

(* Generic Caml type for sequences (AKA ordered forests) *)

type 'a _oforest
      (* [t] in the XML Query Data Model
	 is represented as t _oforest in Caml *)

(* Generic Caml type for optional values *)

type 'a _option
      (* t|null in the XML Query Data Model
	 is represented as t _option in Caml *)

(* Caml types for XML names *)

type _QNameElem = Sym.relem_symbol   (* This is an element QName - e.g., used in element construction *)
type _QNameAttr = Sym.rattr_symbol   (* This is an attribute QName - e.g., used in attribute construction *)

(* Note:
     There is also below a _QName type that represents QName *values*
     as instances of the data model, and as defined in XML Schema
   - Jerome
 *)

(*************)
(* XML Nodes *)
(*************)

(* Nodes in the data model *)

type _DocNode          (* Document node *)
type _ElemNode         (* Element node *)
type _AttrNode         (* Attribute node *)
type _TextNode         (* Text node *)
type _NSNode           (* Namespace node *)
type _PINode           (* Process instruction node *)
type _CommentNode      (* Comment node *)

(* Generic node type *)

type _Node

type _NodeKind =
  | DocNodeKind
  | ElemNodeKind
  | AttrNodeKind
  | TextNodeKind
  | NSNodeKind
  | PINodeKind
  | CommentNodeKind

(*****************)
(* XML Instances *)
(*****************)

(* Note:
     At this point, the data model can deal with heterogeneous
     sequences of nodes and values. An _Instance is either a node or a
     value. An _InstanceForest is a sequence of nodes and values. Most
     of the evaluation functions in Galax are working on
     _InstanceForests.
   - Jerome
*)

(* Instances of the data model *)

type _Instance =
  | InstanceNode of _Node
  | InstanceValue of _DataValue

type _InstanceForest =
    _Instance _oforest

(*************************************)
(* Caml specific operations on nodes *)
(*************************************)

(* Note:
     The following functions are not part of the data model but are
     useful to manipulate the Caml representation of nodes.
   - Jerome
 *)

(* Casts from specific node types to a generic node *)

val buildDocNode     : _DocNode     -> _Node
val buildElemNode    : _ElemNode    -> _Node
val buildAttrNode    : _AttrNode    -> _Node
val buildTextNode    : _TextNode    -> _Node
val buildNSNode      : _NSNode      -> _Node
val buildPINode      : _PINode      -> _Node
val buildCommentNode : _CommentNode -> _Node

(* Casts from generic node to a specific node type *)

val getDocNode     : _Node -> _DocNode
val getElemNode    : _Node -> _ElemNode
val getAttrNode    : _Node -> _AttrNode
val getTextNode    : _Node -> _TextNode
val getNSNode      : _Node -> _NSNode
val getPINode      : _Node -> _PINode
val getCommentNode : _Node -> _CommentNode

(* Selects nodes based on their specific type *)

val selectDocNodes     : _Node _oforest -> _DocNode _oforest
val selectElemNodes    : _Node _oforest -> _ElemNode _oforest
val selectAttrNodes    : _Node _oforest -> _AttrNode _oforest
val selectTextNodes    : _Node _oforest -> _TextNode _oforest
val selectNSNodes      : _Node _oforest -> _NSNode _oforest
val selectPINodes      : _Node _oforest -> _PINode _oforest
val selectCommentNodes : _Node _oforest -> _CommentNode _oforest

(* Tests for a node specific type *)

val isDocNode     : _Node -> bool
val isElemNode    : _Node -> bool
val isAttrNode    : _Node -> bool
val isTextNode    : _Node -> bool
val isNSNode      : _Node -> bool
val isPINode      : _Node -> bool
val isCommentNode : _Node -> bool

(* Returns the kindness of a node *)

val getNodeKind : _Node -> _NodeKind

(***********************)
(* Operations on nodes *)
(***********************)

(* Generic operations on nodes *)

(* Type operations *)

val nodeType        : _Node -> _Def_T list
val nodeAddType     : _Node -> _Def_T -> unit
val nodeChangeType  : _Node -> _Def_T list -> unit

(* Parent operations *)

val nodeParent      : _Node -> _Node _oforest

(* String value *)

val nodeStringValue : _Node -> _string

(* Deep copy *)

val nodeDeepCopy    : _Node -> _Node

(* Document Node operations *)

val docNode         : _anyURI -> _Node _oforest -> _DocNode
val docNodeId       : Nodeid.nodeid -> _anyURI -> _Node _oforest -> _DocNode
 
val docUri          : _DocNode -> _anyURI
val docChildren     : _DocNode -> _Node _oforest
val docRootElement  : _DocNode -> _ElemNode

(* Elements Node operations *)

val elemNode :
    _QNameElem -> _NSNode _oforest ->
      _AttrNode _oforest -> _Node _oforest -> _Def_T list -> _ElemNode

val elemNodeId :
    Nodeid.nodeid ->
      _QNameElem -> _NSNode _oforest ->
	_AttrNode _oforest -> _Node _oforest -> _Def_T list -> _ElemNode

val elemNodeWithValue :
    _QNameElem -> _NSNode _oforest ->
      _AttrNode _oforest -> _Node _oforest -> _Def_T list -> _DataValue _oforest -> _ElemNode

val elemNodeWithValueId :
    Nodeid.nodeid ->
      _QNameElem -> _NSNode _oforest ->
	_AttrNode _oforest -> _Node _oforest -> _Def_T list -> _DataValue _oforest -> _ElemNode

val elemNode' :
    _QNameElem -> _NSNode _oforest ->
      _Node _oforest -> _Def_T list -> _ElemNode

val elemNodeWithValue' :
    _QNameElem -> _NSNode _oforest ->
      _Node _oforest -> _Def_T list -> _DataValue _oforest -> _ElemNode

val elemNodeChangeValue : _ElemNode -> _DataValue _oforest -> unit

val elemName       : _ElemNode -> _QNameElem
val elemNamespaces : _ElemNode -> _NSNode _oforest
val elemAttributes : _ElemNode -> _AttrNode _oforest
val elemChildren   : _ElemNode -> _Node _oforest
val elemValue      : _ElemNode -> _DataValue _oforest

(* Attributes Node operations *)

val attrBuildContent : _Node _oforest -> _text

(* Note:
     This is a special function that takes an arbitrary sequence of
     nodes and builds a text node suitable for the content of an
     attribute.
 - Jerome
 *)

val attrNode :
    _QNameAttr -> _text -> _AttrNode
val attrNodeId :
    Nodeid.nodeid -> _QNameAttr -> _text -> _AttrNode

val attrNodeWithValue :
    _QNameAttr -> _text -> _DataValue _oforest -> _AttrNode
val attrNodeWithValueId :
    Nodeid.nodeid -> _QNameAttr -> _text -> _DataValue _oforest -> _AttrNode

val attrChangeValue : _AttrNode -> _DataValue _oforest -> unit

val attrName    : _AttrNode -> _QNameAttr
val attrContent : _AttrNode -> _text
val attrValue   : _AttrNode -> _DataValue _oforest

(* Text Node operations *)

val textNode      : _text -> _TextNode
val textNodeId    : Nodeid.nodeid -> _text -> _TextNode

val textContent   : _TextNode -> _text

(* Namespace Node operations *)

val nsNode      : _ncName -> _anyURI -> _NSNode
val nsNodeId    : Nodeid.nodeid -> _ncName -> _anyURI -> _NSNode

val nsPrefix 	: _NSNode -> _ncName
val nsUri    	: _NSNode -> _anyURI

(* Processing instructions Node operations *)

val piNode      : _string -> _string -> _PINode
val piNodeId    : Nodeid.nodeid -> _string -> _string -> _PINode

val piTarget 	: _PINode -> _string
val piValue  	: _PINode -> _string

(* Comments Node operations *)

val commentNode      : _string -> _CommentNode
val commentNodeId    : Nodeid.nodeid -> _string -> _CommentNode

val commentValue     : _CommentNode -> _string

(*******************************)
(* Operations on node identity *)
(*******************************)

(* Note:
     These are not supported yet.
   - Jerome
 *)

(* Node equality *)

val nodeEqual : _Node -> _Node -> bool

(* Document order *)

val nodePrecedes : _Node -> _Node -> bool
val nodeFollows  : _Node -> _Node -> bool

(***************************)
(* Operations on sequences *)
(***************************)

(* Note:
     Below are all the traditional operations on lists.

     Curently, sequences are implemented as lists. A cursor interface
     on sequences would be useful for enabling other (possibly more
     efficient) implementations of sequences in the future.

   - Jerome
 *)

(* Sequence constructors *)

val oforestEmpty       : 'a _oforest
val oforestBuildSingle : 'a -> 'a _oforest
val oforestCons        : 'a -> 'a _oforest -> 'a _oforest
val oforestAppend      : 'a _oforest -> 'a _oforest -> 'a _oforest

(* Sequence accessors *)

val oforestIsEmpty     : 'a _oforest -> bool
val oforestIsSingle    : 'a _oforest -> bool
val oforestIsOptional  : 'a _oforest -> bool
val oforestGetSingle   : 'a _oforest -> 'a
val oforestHead        : 'a _oforest -> 'a
val oforestTail        : 'a _oforest -> 'a _oforest
val oforestLength      : 'a _oforest -> int
val oforestNth         : 'a _oforest -> int -> 'a

(* Sequence iterators *)

val oforestMap       : ('a -> 'b) -> 'a _oforest -> 'b _oforest
val oforestIter      : ('a -> unit) -> 'a _oforest -> unit
val oforestFilter    : ('a -> bool) -> 'a _oforest -> 'a _oforest
val oforestFold_left : ('a -> 'b -> 'a) -> 'a -> 'b _oforest -> 'a
val oforestConcat    : 'a _oforest list -> 'a _oforest
val oforestConcatMap : ('a -> 'b _oforest) -> 'a _oforest -> 'b _oforest

(* Casts from sequences to lists and back *)

val list_of_oforest : 'a _oforest -> 'a list
val oforest_of_list : 'a list -> 'a _oforest

(*****************************************)
(* Caml specific operations on instances *)
(*****************************************)

(* Note:
     The following functions are not part of the data model but are
     useful to manipulate the Caml representation of instances.
   - Jerome
 *)

(* Casts from nodes to instances *)

val buildAttrForest     : _AttrNode _oforest -> _InstanceForest
val buildNSForest       : _NSNode _oforest   -> _InstanceForest
val buildTextForest     : _TextNode _oforest -> _InstanceForest

val buildNodeInstance        : _Node               -> _Instance
val buildNodeInstanceForest  : _Node _oforest      -> _InstanceForest

val buildValueInstance       : _DataValue          -> _Instance
val buildValueInstanceForest : _DataValue _oforest -> _InstanceForest

(* Casts from instances to nodes and values *)

val getNodeInstance  : _Instance -> _Node
val getValueInstance : _Instance -> _DataValue

(* Tests whether an instance is a node or a value *)

val isNodeInstance  : _Instance -> bool
val isValueInstance : _Instance -> bool

(* Filters nodes and values in an instance forest *)

val filterInstanceForest  : _InstanceForest -> (_Node _oforest * _DataValue _oforest)

(***************************)
(* Operations on instances *)
(***************************)

(* Note:
     Most of these operations are used directly by the evalution
     engine. It is open which of these operations should be separated
     as part of the built-in functions and operators implementation.
   - Jerome
 *)

(* Comparison operations *)

val instance_eq   : _Instance -> _Instance -> bool
val instance_neq  : _Instance -> _Instance -> bool

val instance_lteq : _Instance -> _Instance -> bool
val instance_lt   : _Instance -> _Instance -> bool
val instance_gteq : _Instance -> _Instance -> bool
val instance_gt   : _Instance -> _Instance -> bool

val instance_forest_eq  : _InstanceForest -> _InstanceForest -> bool
val instance_forest_neq : _InstanceForest -> _InstanceForest -> bool

val instance_compare : _Instance -> _Instance -> int
(** [instance_compare i1 i2] returns 0 if the two values are equal, a
    positive integer if the first value is greater and a negative
    integer if the first value is smaller.

    Comparison between values uses the corresponding standard order.

    Comparison between two nodes uses document order.

    This function raises an error if the two values are not of the
    same kind or if one is a node and the other is not.

    This function is used for the evaluation of sort by expressions.
*)

(* Some useful instance constructors *)

val _true  : _Instance
val _false : _Instance

val _int   : _int -> _Instance
val _integer : _integer -> _Instance
val _decimal : _decimal -> _Instance
val _float : _float -> _Instance
val _double  : _double -> _Instance

val boolval : bool -> _Instance

(* Some useful instance destructors *)

val extract_optional_instance : _InstanceForest -> _Instance option

val extract_string_instance : _InstanceForest -> string

(*****************************)
(* XPath specific operations *)
(*****************************)

(* Note:
     These functions are not part of the data model , but are useful
     for XPath. These are currently defined only in the XPath 1.0
     specification.
   - Jerome
 *)

(* XPath axis accessors *)

val ancestor_axis           : _Node -> _Node _oforest
val ancestor_or_self_axis   : _Node -> _Node _oforest
val attribute_axis          : _Node -> _Node _oforest
val child_axis              : _Node -> _Node _oforest
val descendant_axis         : _Node -> _Node _oforest
val descendant_or_self_axis : _Node -> _Node _oforest
val namespace_axis          : _Node -> _Node _oforest
val parent_axis             : _Node -> _Node _oforest
val self_axis               : _Node -> _Node _oforest

(* Computes the princinpal node kind of a given axis *)

val principal_node_kind : Xquery_ast.axis -> _NodeKind


(*********************************)
(* Evaluation related operations *)
(*********************************)

(* Note:
     The status of the following functions is not clear. They are
     currently used internally by the evaluation engine.
   - Jerome
 *)

val get_val_name : _Instance -> Sym.resolved_unit_symbol
    (* get 'type symbol' of a node *)
val getNodeName  : _Node -> Namespace.rqname option
    (* Returns the 'name' of a node *)
val getNodeQName : _Node -> string
    (* Returns the 'qname' of a node *)
val getNodeSym   : _Node -> Sym.resolved_unit_symbol option
    (* Returns the 'symbol' of a node *)


(****************************)
(* Serialization operations *)
(****************************)

(* Note:
     These serialization operations are part of the Datamodel
     interface. This is because, they are more effectively implemented
     by looking at the internal representation of data model nodes and
     values.
   - Jerome
 *)

val xml_header : string
    (* XML header *)

val serialize_in_result        : string -> _InstanceForest -> string
val fserialize_in_result       : Format.formatter -> string -> _InstanceForest -> unit

val serialize_instance_forest  : string -> _InstanceForest -> string
val fserialize_instance_forest : Format.formatter -> string -> _InstanceForest -> unit

val fserialize_result : Format.formatter -> _InstanceForest -> unit 

(*********************)
(* Update operations *)
(*********************)

(* Note:
     These functions are not part of the official XPath/XQuery data
     model. They are used as a low-level interface to the update
     language.
   - Jerome
 *)

val delete_node_with_children  : _InstanceForest -> unit
val delete_node_paste_children : _InstanceForest -> unit

