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

(* $Id: schemautil.mli,v 1.21 2002/10/27 20:02:53 simeon Exp $ *)

(**********************************************************************)
(* This module implements a number of general-purpose type operations *)
(**********************************************************************)

open Xquery_ast

(***********************************************)
(* Some constructors/destructors on model ASTs *)
(***********************************************)

(* Test some type structures *)

val is_string_type : model -> bool
val is_bool_type : model -> bool
val is_empty_choice_type : model -> bool
val is_empty_seq_type : model -> bool
val is_none : model -> bool

(* Operations on unit types *)

val is_element   : Schema.schema -> Sym.rgroup_symbol -> bool
val is_attribute : Schema.schema -> Sym.rgroup_symbol -> bool
val is_unit_type : Schema.schema -> Sym.rgroup_symbol -> bool

val is_attribute_unit : Schema.schema -> model -> bool

val check_unit_type    : Schema.schema -> Sym.rgroup_symbol -> unit

val get_unit_tag            : Schema.schema -> Sym.rgroup_symbol -> Sym.resolved_unit_symbol
val get_unit_tag_unresolved : Schema.schema -> Namespace.nsenv -> Sym.rgroup_symbol -> Sym.resolved_unit_symbol
val get_unit_tag_from_model            : model -> Sym.resolved_unit_symbol
val get_unit_tag_from_unresolved_model : Namespace.nsenv -> model -> Sym.resolved_unit_symbol

val access_attribute : Schema.schema -> model -> Sym.rattr_symbol * typed_model
val access_element   : Schema.schema -> model -> Sym.relem_symbol * typed_model

(* Pair type *)

val pair_type : model -> model -> model
val unpair_type : model -> model * model

(* Union normalization *)

val union_types : model list -> model
val weakunion_types : model list -> model

(* Applies a function to each unit of a given type *)

val only_non_attribute_model : model -> model

val apply_to_unit_types : Schema.schema -> (model -> model) -> model -> model
val forall_unit_types : Schema.schema -> (model -> bool) -> model -> bool

(* emptyness and noneness *)

val empty_type : Schema.schema -> model -> bool
val none_type  : Schema.schema -> model -> bool

(***********************)
(* Low-level factoring *)
(***********************)

(* Factoring and rec factoring for non-empty types *)

val factor_aux    : Schema.schema -> model -> model list * Occurrence.occurs * Occurrence.occurs
val recfactor_aux :
    Schema.schema -> model
      -> Sym.group_symbol list
	-> Sym.elem_symbol list -> model list * Occurrence.occurs * Occurrence.occurs

(*************************************)
(* operations on regular expressions *)
(*************************************)

(* Accesses the content of a model as a regular expression over type names *)

val model_normalize : Schema.schema -> model -> model

(* Does the model contain empty ? *)

val empty : Schema.schema -> model -> bool

(* Derivatives of a model *)

(* first_rest computes all the type names that can be a first token,
   plus the rest of the regular expression *)

val first_rest :
    Schema.schema -> model -> (Sym.resolved_unit_symbol * Sym.rgroup_symbol * model) list

val first_rest_deterministic :
    Schema.schema -> model -> (Sym.resolved_unit_symbol * Sym.rgroup_symbol * model) list

(* Note:
     This last first_rest functions return the matched model and
     intermediate group names.
   - Jerome
 *)

val first_rest_with_model :
    Schema.schema -> model -> (Sym.resolved_unit_symbol * typed_model option * Sym.rgroup_symbol list * model) list

val first_rest_with_model_attributes :
    Schema.schema -> model -> (Sym.resolved_unit_symbol * typed_model option * Sym.rgroup_symbol list * model) list

(* Now, one function that applies first_rest_with_model recursively while gather attributes *)

val first_rest_with_model_discard_attributes :
    Schema.schema -> model -> (Sym.resolved_unit_symbol * typed_model option * Sym.rgroup_symbol list * model) list

(********************************)
(* Operations on content models *)
(********************************)

(* Note:
     These functions are used to classify content model for elements
     according to the XML Schema specification. There are three kinds
     of content models: simple content, complex content and mixed
     content.
   - Jerome
 *)

(* Attribute model kinds *)

type optional_attribute_model =
    (model * Sym.rgroup_symbol list)

type required_attribute_model =
    (model * Sym.rgroup_symbol list)

type attribute_model =
    optional_attribute_model list * required_attribute_model list

val process_attribute_model : Schema.schema -> model -> attribute_model

(* Split content model into attribute types & children types *)

val split_content_model : Schema.schema -> model -> model * model

(* Removes attributes from the content model *)

val extract_content_model : Schema.schema -> model -> model

(* Content model kind *)

type element_content_model_kind =
  | ElementEmptyContent   of model
  | ElementSimpleContent  of model
  | ElementComplexContent of model
  | ElementMixedContent   of model      (* cannot be exercised yet... *)

(* Note:
     The first model is the one describing attributes of the element,
     The second model is the one describing the content model of the
     element.
   - Jerome
 *)

type attribute_content_model_kind =
  | AttributeSimpleContent of model

val get_element_content_model_kind   : Schema.schema -> typed_model -> element_content_model_kind
val get_attribute_content_model_kind : Schema.schema -> typed_model -> attribute_content_model_kind
val extract_content_model : Schema.schema -> model -> model

