(***********************************************************************)
(*                                                                     *)
(*                                 GALAX                               *)
(*                              XQuery Engine                          *)
(*                                                                     *)
(*  Copyright 2001-2003, Lucent Technologies.                          *)
(*  Distributed only by permission.                                    *)
(*                                                                     *)
(***********************************************************************)

(* $Id: datamodel.mli,v 1.55 2003/06/27 00:05:07 simeon Exp $ *)

(* Module: Datamodel
   Description:
     This module implements the XQuery 1.0 and XPath 2.0 data model.
*)

open Datatypes
   (** Contains the definition for all XML Schema data types and for
       atomic values *)


(*****************)
(* Prerequisites *)
(*****************)

(* Caml types for XML names *)

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

type _ncName   = Namespace.ncname

(* Note:
     Note that there is also a type _QName in the Datatypes module, used
     to represent QName *values* as instances of the data model.
   - Jerome
 *)

(*************)
(* Sequences *)
(*************)

type 'a _Sequence
      (** A sequence of type t -- or 't*' -- in the XML Query Data
	  Model is represented as t _Sequence in Caml *)

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

(* There are 7 kinds of nodes *)

type _DocumentNode     			  (* Document node *)
type _ElementNode      			  (* Element node *)
type _AttributeNode    			  (* Attribute node *)
type _TextNode         			  (* Text node *)
type _NamespaceNode    			  (* Namespace node *)
type _ProcessingInstructionNode           (* Process instruction node *)
type _CommentNode      			  (* Comment node *)

(* _Node stands for all kinds of nodes *)

type _Node =
  | DocumentNode              of _DocumentNode
  | ElementNode               of _ElementNode
  | AttributeNode             of _AttributeNode
  | TextNode                  of _TextNode
  | NamespaceNode             of _NamespaceNode
  | ProcessingInstructionNode of _ProcessingInstructionNode
  | CommentNode               of _CommentNode

(* Node kinds *)

type _NodeKind =
  | DocumentNodeKind
  | ElementNodeKind
  | AttributeNodeKind
  | TextNodeKind
  | NamespaceNodeKind
  | ProcessingInstructionNodeKind
  | CommentNodeKind


(**************)
(* XML Values *)
(**************)

(* Note:
     Caml type names below are based on the terminology adopted by the
     XML Query and XSLT working groups, and used in the XQuery 1.0 and
     XPath 2.0 data model.

     The data model deals with values [type _Value]. Values are
     sequences of items [type _Item _Sequence]. An item [type _Item]
     can be either a node [type _Node] or an atomic value ([type
     _AtomicValue], defined in the Datatypes module).

     Most of the evaluation functions in Galax are working on the
     [_Value] type.

   - Jerome
*)

(* Items *)

type _Item =
  | Node of _Node
  | AtomicValue of _AtomicValue

(* Values *)

type _Value =
  _Item _Sequence
  

(**********)
(* Tuples *)
(**********)

(* Note:
     2002/11/20 Values are extended with a notion of tuple, for
     internal use.
   - Jerome *)

type _Tuple


(*******************)
(* Extended values *)
(*******************)

type _Extended_Value

val create_tuple 	     : (Xquery_ast.rname * _Value) list -> _Tuple
val access_tuple 	     : Xquery_ast.rname -> _Tuple -> _Value

val _Extended_Value_of_Tuples         : _Tuple _Sequence -> _Extended_Value
val _Tuples_of_Extended_Value         : _Extended_Value  -> _Tuple _Sequence

val _Extended_Value_of_Value          : _Value           -> _Extended_Value
val _Value_of_Extended_Value          : _Extended_Value  -> _Value

exception Not_A_Tuple of _Extended_Value
exception Not_A_Value of _Extended_Value

val _Concat_Extended_Value_Sequence   : _Extended_Value _Sequence -> _Extended_Value

(*************************************)
(* 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 buildDocumentNode   	     : _DocumentNode              -> _Node
val buildElementNode 		     : _ElementNode               -> _Node
val buildAttributeNode  	     : _AttributeNode             -> _Node
val buildTextNode    		     : _TextNode                  -> _Node
val buildNamespaceNode  	     : _NamespaceNode             -> _Node
val buildProcessingInstructionNode   : _ProcessingInstructionNode -> _Node
val buildCommentNode 	             : _CommentNode               -> _Node

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

val getDocumentNode     	     : _Node -> _DocumentNode
val getElementNode 		     : _Node -> _ElementNode
val getAttributeNode    	     : _Node -> _AttributeNode
val getTextNode    		     : _Node -> _TextNode
val getNamespaceNode    	     : _Node -> _NamespaceNode
val getProcessingInstructionNode     : _Node -> _ProcessingInstructionNode
val getCommentNode 		     : _Node -> _CommentNode

(* Selects nodes based on their specific type *)

val selectDocumentNodes   	     : _Node _Sequence -> _DocumentNode              _Sequence
val selectElementNodes 	  	     : _Node _Sequence -> _ElementNode               _Sequence
val selectAttributeNodes  	     : _Node _Sequence -> _AttributeNode             _Sequence
val selectTextNodes    	  	     : _Node _Sequence -> _TextNode                  _Sequence
val selectNamespaceNodes  	     : _Node _Sequence -> _NamespaceNode             _Sequence
val selectProcessingInstructionNodes : _Node _Sequence -> _ProcessingInstructionNode _Sequence
val selectCommentNodes 	             : _Node _Sequence -> _CommentNode               _Sequence

(* Tests for a node specific node kind *)

val isDocumentNode     		: _Node -> bool
val isElementNode      		: _Node -> bool
val isAttributeNode    		: _Node -> bool
val isTextNode         		: _Node -> bool
val isNamespaceNode    		: _Node -> bool
val isProcessingInstructionNode : _Node -> bool
val isCommentNode      		: _Node -> bool

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

(* Generic operations on nodes *)

(* Returns the kind of a node *)

val nodeKind                 : _Node -> _NodeKind

(* Type operations *)

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

(* base_uri *)
val base_uri        : _Node -> xs_anyURI option

(* typed_value always returns a squence of atomic values, wrapped up as items *)
val typed_value     : _Node -> _Item _Sequence

(* Parent operations *)

val nodeParent      : _Node -> _Node _Sequence

(* String value *)

val nodeStringValue : _Node -> xs_string

(* Deep copy *)

val nodeDeepCopy    : _Node -> _Node

(* Document Node operations *)

val docNode         : xs_anyURI -> _Node _Sequence -> Glx_pxp.encoding option -> _DocumentNode
val docNodeId       : Nodeid.nodeid -> xs_anyURI -> _Node _Sequence -> Glx_pxp.encoding option -> _DocumentNode
 
val docUri          : _DocumentNode -> xs_anyURI
val docChildren     : _DocumentNode -> _Node _Sequence
val docRootElement  : _DocumentNode -> _ElementNode

(* Elements Node operations *)

val elemNode :
    _ElemName -> _NamespaceNode _Sequence ->
      _AttributeNode _Sequence -> _Node _Sequence -> _Def_T list -> _ElementNode

val elemNodeId :
    Nodeid.nodeid ->
      _ElemName -> _NamespaceNode _Sequence ->
	_AttributeNode _Sequence -> _Node _Sequence -> _Def_T list -> _ElementNode

val elemNodeWithValue :
    _ElemName -> _NamespaceNode _Sequence ->
      _AttributeNode _Sequence -> _Node _Sequence -> _Def_T list -> _AtomicValue _Sequence -> _ElementNode

val elemNodeWithValueId :
    Nodeid.nodeid ->
      _ElemName -> _NamespaceNode _Sequence ->
	_AttributeNode _Sequence -> _Node _Sequence -> _Def_T list -> _AtomicValue _Sequence -> _ElementNode

val elemNode' :
    _ElemName -> _NamespaceNode _Sequence ->
      _Node _Sequence -> _Def_T list -> _ElementNode

val elemNodeWithValue' :
    _ElemName -> _NamespaceNode _Sequence ->
      _Node _Sequence -> _Def_T list -> _AtomicValue _Sequence -> _ElementNode

val elemNodeChangeValue : _ElementNode -> _AtomicValue _Sequence -> unit

val elemUri        : _ElementNode -> xs_anyURI option
val elemLang       : _ElementNode -> xs_string option
val elemName       : _ElementNode -> _ElemName
val elemNamespaces : _ElementNode -> _NamespaceNode _Sequence
val elemAttributes : _ElementNode -> _AttributeNode _Sequence
val elemChildren   : _ElementNode -> _Node _Sequence
val elemHasElementContent : _ElementNode -> bool
val elemValue      : _ElementNode -> _AtomicValue _Sequence

val elemGetId      : _ElementNode -> Nodeid.nodeid option

(* Attributes Node operations *)

val attrBuildContent : _Node _Sequence -> xdt_untyped

(* 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 :
    _AttrName -> xdt_untyped -> _AttributeNode
val attrNodeId :
    Nodeid.nodeid -> _AttrName -> xdt_untyped -> _AttributeNode

val attrNodeWithValue :
    _AttrName -> xdt_untyped -> _AtomicValue _Sequence -> _AttributeNode
val attrNodeWithValueId :
    Nodeid.nodeid -> _AttrName -> xdt_untyped -> _AtomicValue _Sequence -> _AttributeNode

val attrChangeValue : _AttributeNode -> _AtomicValue _Sequence -> unit

val attrName    : _AttributeNode -> _AttrName
val attrContent : _AttributeNode -> xdt_untyped
val attrValue   : _AttributeNode -> _AtomicValue _Sequence

(* Text Node operations *)

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

val textContent   : _TextNode -> xdt_untyped

(* Namespace Node operations *)

val nsNode      : _ncName -> xs_anyURI -> _NamespaceNode
val nsNodeId    : Nodeid.nodeid -> _ncName -> xs_anyURI -> _NamespaceNode

val nsPrefix 	: _NamespaceNode -> _ncName
val nsUri    	: _NamespaceNode -> xs_anyURI

(* Processing instructions Node operations *)

val piNode      : xs_string -> xs_string -> _ProcessingInstructionNode
val piNodeId    : Nodeid.nodeid -> xs_string -> xs_string -> _ProcessingInstructionNode

val piTarget 	: _ProcessingInstructionNode -> xs_string
val piValue  	: _ProcessingInstructionNode -> xs_string

(* Comments Node operations *)

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

val commentValue     : _CommentNode -> xs_string


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

(* 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 sequenceEmpty       : 'a _Sequence
val sequenceBuildSingle : 'a -> 'a _Sequence
val sequenceCons        : 'a -> 'a _Sequence -> 'a _Sequence
val sequenceAppend      : 'a _Sequence -> 'a _Sequence -> 'a _Sequence

(* Sequence accessors *)

val sequenceIsEmpty     : 'a _Sequence -> bool
val sequenceIsSingle    : 'a _Sequence -> bool
val sequenceIsOptional  : 'a _Sequence -> bool
val sequenceGetSingle   : 'a _Sequence -> 'a
val sequenceHead        : 'a _Sequence -> 'a
val sequenceTail        : 'a _Sequence -> 'a _Sequence
val sequenceLength      : 'a _Sequence -> int
val sequenceNth         : 'a _Sequence -> int -> 'a

(* Sequence iterators *)

val sequenceMap       : ('a -> 'b) -> 'a _Sequence -> 'b _Sequence
val sequenceIter      : ('a -> unit) -> 'a _Sequence -> unit
val sequenceFilter    : ('a -> bool) -> 'a _Sequence -> 'a _Sequence
val sequenceFold_left : ('a -> 'b -> 'a) -> 'a -> 'b _Sequence -> 'a
val sequenceConcat    : 'a _Sequence list -> 'a _Sequence
val sequenceConcatMap : ('a -> 'b _Sequence) -> 'a _Sequence -> 'b _Sequence

(* Casts from sequences to lists and back *)

val list_of_sequence : 'a _Sequence -> 'a list
val sequence_of_list : 'a list -> 'a _Sequence


(*****************************************)
(* 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 items to values *)

val buildAttrSequence        : _AttributeNode _Sequence -> _Value
val buildNSSequence          : _NamespaceNode _Sequence -> _Value
val buildTextSequence        : _TextNode _Sequence      -> _Value

val buildNode                : _Node                  	-> _Item
val buildNodeSequence        : _Node _Sequence        	-> _Value
  
val buildAtomicValue         : _AtomicValue           	-> _Item
val buildAtomicValueSequence : _AtomicValue _Sequence 	-> _Value

(* Casts from instances to nodes and values *)

val getNode                  : _Item -> _Node
val getAtomicValue           : _Item -> _AtomicValue

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

val isNode          	     : _Item -> bool
val isAtomicValue   	     : _Item -> bool

(* Separate nodes from atomic values *)

val filterValue              : _Value -> (_Node _Sequence * _AtomicValue _Sequence)


(***********************)
(* Operations on items *)
(***********************)

(* 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 -- compares items by value *)

val item_eq   : _Item -> _Item -> bool
val item_neq  : _Item -> _Item -> bool

val item_lteq : _Item -> _Item -> bool
val item_lt   : _Item -> _Item -> bool
val item_gteq : _Item -> _Item -> bool
val item_gt   : _Item -> _Item -> bool

val value_eq  : _Value -> _Value -> bool
val value_neq : _Value -> _Value -> bool

(* 
    [item_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.

    item_equal returns true if item_compare returns 0, otherwise false.

    Comparison between values uses the corresponding standard order.

    Comparison between two nodes uses document order.

    item_compare and item_equal raise an error if the two values are
    not of the same kind or if one is a node and the other is not.

    item_compare is used for the evaluation of sort by expressions.
*)
val item_compare : _Item -> _Item -> int
val item_equal   : _Item -> _Item -> bool

(* Some useful item constructors *)

val _true    : _Item
val _false   : _Item

val _int     : xs_int     -> _Item
val _integer : xs_integer -> _Item
val _decimal : xs_decimal -> _Item
val _float   : xs_float   -> _Item
val _double  : xs_double  -> _Item

val boolval : bool -> _Item

(* Some useful item destructors *)

val extract_optional_item : _Value -> _Item option

val extract_string_item : _Value -> string
val extract_bool_item : _Value -> bool
val extract_int_item : _Value -> int
val extract_float_item : _Value -> float

(* value_to_node_sequence converts an item sequence to a node
   sequence by applying rules in XQuery 1.0 specification, Section 3.7.1  *)
val value_to_node_sequence : _Value -> _Node _Sequence

(* value_to_untyped converts an item sequence to an untyped string
   by applying the rules in XQuery 1.0 specification, Section 3.7.1  *)
val value_to_untyped : _Value -> xdt_untyped

val attributes_and_nodes : _Node _Sequence -> (_AttributeNode _Sequence * _Node _Sequence)

val filterAttributesFromSequence : _Value -> (_AttributeNode _Sequence * _Value)

(*****************************)
(* 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 _Sequence
val ancestor_or_self_axis   : _Node -> _Node _Sequence
val attribute_axis          : _Node -> _Node _Sequence
val child_axis              : _Node -> _Node _Sequence
val descendant_axis         : _Node -> _Node _Sequence
val descendant_or_self_axis : _Node -> _Node _Sequence
val namespace_axis          : _Node -> _Node _Sequence
val parent_axis             : _Node -> _Node _Sequence
val self_axis               : _Node -> _Node _Sequence

(* 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 : _Item -> 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 *)


(*********************)
(* 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  : _Value -> unit

(* insert interface *)

val get_first_child : _Node -> _Node option
val get_next_sibling : _Node -> _Node -> _Node option
val insert : _Value -> _Node -> _Node option -> unit

(* replace interface *)

val replace_node  : _Value -> _Node -> _Node -> unit
val replace_value : _Value -> _Node -> unit

