src/Tools/isac/BaseDefinitions/store.sml
author wneuper <Walther.Neuper@jku.at>
Tue, 15 Aug 2023 12:22:49 +0200
changeset 60729 43d11e7742e1
parent 60636 be8a52bf330b
child 60768 14da2230d5c3
permissions -rw-r--r--
prepare 13: Testi_Isac_Short without errors
walther@59891
     1
(* Title:  BaseDefinitions/store.sml
walther@59882
     2
   Author: Walther Neuper
walther@59882
     3
   (c) due to copyright terms
walther@59882
     4
Walther@60636
     5
A tree for storing collections of Problem and MethodC.
walther@59891
     6
*)
walther@59890
     7
signature STORE_TREE =
walther@59882
     8
sig
wenzelm@60293
     9
  type key = string list
walther@59897
    10
  datatype 'a node = Node of string * 'a list * 'a node list
walther@59897
    11
  type 'a T = 'a node list
walther@59897
    12
walther@59897
    13
  val merge: 'a T * 'a T -> 'a T
walther@59897
    14
  val insert: key -> 'a -> string list -> 'a T -> 'a T
walther@59971
    15
  val scan : string list -> 'a T -> string list list
walther@59971
    16
walther@59897
    17
  val get: 'a T -> key -> (*rev*)key -> 'a
walther@59971
    18
  val get_all: 'a T -> 'a list
walther@59971
    19
walther@59897
    20
  val update: key -> string list -> 'a -> 'a T -> 'a T
walther@59897
    21
  val apply: 'a T -> ('a node -> 'b) -> key -> (*rev*)key -> 'b
Walther@60729
    22
Walther@60729
    23
(*from isac_test for Minisubpbl*)
Walther@60729
    24
  val get_node: string list -> string list -> 'a T -> 'a node
Walther@60729
    25
walther@59882
    26
end
walther@59882
    27
walther@59882
    28
(**)
walther@59890
    29
structure Store(**): STORE_TREE(**) =
walther@59882
    30
struct
walther@59882
    31
(**)
walther@59882
    32
walther@59892
    33
type key = string list; (*will become pblID, methID, theID*)
walther@59914
    34
walther@59884
    35
(* A tree for storing data defined in different theories 
walther@59884
    36
  for access from the Interpreter and from dialogue authoring 
walther@59884
    37
  using a string list as key.
walther@59884
    38
  'a is for pbt | met | thydata; after WN030424 naming "pbt" became inappropriate *)
walther@59897
    39
datatype 'a node =
walther@59897
    40
	Node of string *  (* element of the key                                                        *)
walther@59884
    41
		'a list *       (* several pbts with different domIDs/thy TODO: select by subthy (isaref.p.69)
walther@59884
    42
			                 presently only _ONE_ elem FOR ALL KINDS OF CONTENT pbt | met | thydata    *)
walther@59897
    43
		('a node) list; (* the children nodes                                                        *)
walther@59897
    44
type 'a T = ('a node) list
walther@59884
    45
walther@59884
    46
(* this function only works wrt. the way Isabelle evaluates Theories and is not a general merge
walther@59884
    47
  function for trees / ptyps *)
walther@59897
    48
fun merge ([], pt) = pt
walther@59897
    49
  | merge (pt, []) = pt
walther@59897
    50
  | merge ((x' as Node (k, _, ps)) :: xs, (xs' as Node (k', y, ps') :: ys)) =
walther@59884
    51
      if k = k'
walther@59897
    52
      then Node (k, y, merge (ps, ps')) :: merge (xs, ys)
walther@59897
    53
      else x' :: merge (xs, xs');
walther@59884
    54
walther@59897
    55
fun insert _ pbt [k] [] = [Node (k, [pbt], [])]
walther@59897
    56
  | insert d pbt [k] ((Node (k', [p], ps)) :: pys) =
walther@59884
    57
    ((*writeln ("### insert 1: ks = " ^ strs2str [k] ^ "    k'= " ^ k');*)
walther@59884
    58
    if k = k'
walther@59897
    59
    then ((Node (k', [pbt], ps)) :: pys)
walther@59897
    60
    else  ((Node (k', [p], ps)) :: (insert d pbt [k] pys))
walther@59884
    61
    )			 
walther@59897
    62
  | insert d pbt (k::ks) ((Node (k', [p], ps)) :: pys) =
walther@59884
    63
    ((*writeln ("### insert 2: ks = "^(strs2str (k::ks))^"    k'= "^k');*)
walther@59884
    64
    if k = k'
walther@59897
    65
    then ((Node (k', [p], insert d pbt ks ps)) :: pys)
walther@59884
    66
    else 
walther@59884
    67
      if length pys = 0
walther@59962
    68
      then raise ERROR ("insert: not found " ^ (strs2str (d(* : pblID*))))
walther@59897
    69
      else ((Node (k', [p], ps)) :: (insert d pbt (k :: ks) pys))
walther@59884
    70
    )
walther@59897
    71
  | insert _ _ _ _ = raise ERROR "";
walther@59884
    72
walther@59971
    73
fun scan _  [] = [] (* no base case, for empty doms only *)
walther@59971
    74
  | scan id ((Node ((i, _, []))) :: []) = [id @ [i]]
walther@59971
    75
  | scan id ((Node ((i, _, pl))) :: []) = scan (id @ [i]) pl
walther@59971
    76
  | scan id ((Node ((i, _, []))) :: ps) = [id @ [i]] @ (scan id ps)
walther@59971
    77
  | scan id ((Node ((i, _, pl))) :: ps) = (scan (id @ [i]) pl) @ (scan id ps);
walther@59971
    78
walther@59971
    79
walther@59971
    80
 fun apply p f (d(*:pblID*)) (k(*:pblRD*)) =
walther@59884
    81
  let
walther@59897
    82
    fun py_err _ = raise ERROR ("apply: not found: " ^ strs2str d);
walther@59884
    83
    fun app_py' _ [] = py_err ()
walther@59884
    84
      | app_py' [] _ = py_err ()
walther@59897
    85
      | app_py' [k0] ((p' as Node (k', _, _  )) :: ps) =
walther@59884
    86
        if k0 = k' then f p' else app_py' [k0] ps
walther@59897
    87
      | app_py' (k' as (k0 :: ks)) (Node (k'', _, ps) :: ps') =
walther@59884
    88
        if k0 = k'' then app_py' ks ps else app_py' k' ps';
walther@59884
    89
  in app_py' k p end;
walther@59897
    90
fun get p =
walther@59884
    91
  let
walther@59897
    92
    fun extract_py (Node (_, [py], _)) = py
walther@59897
    93
      | extract_py _ = raise ERROR ("extract_py: Node has wrong format.");
walther@59897
    94
  in apply p extract_py end;
walther@59884
    95
walther@59971
    96
fun get_all ptyp =
walther@59971
    97
let
walther@59971
    98
  fun scan [] = []
walther@59971
    99
    | scan ((Node ((_, data, []))) :: []) = data
walther@59971
   100
    | scan ((Node ((_, data, pl))) :: []) = data @ scan pl
walther@59971
   101
    | scan ((Node ((_, data, []))) :: ps) = data @ scan ps
walther@59971
   102
    | scan ((Node ((_, data, pl))) :: ps) = data @ scan pl @ scan ps
walther@59971
   103
in scan ptyp end
walther@59971
   104
walther@59897
   105
fun update ID _ _ [] =
walther@59962
   106
    raise ERROR ("update: " ^ strs2str' ID ^ " does not exist")
walther@59897
   107
  | update ID [i] data ((py as Node (key, _, pys)) :: pyss) =
walther@59884
   108
    if i = key
walther@59884
   109
    then 
walther@59884
   110
      if length pys = 0
walther@59897
   111
      then ((Node (key, [data], [])) :: pyss)
walther@59962
   112
      else raise ERROR ("update: " ^ strs2str' ID ^ " has descendants")
walther@59897
   113
    else py :: update ID [i] data pyss
walther@59897
   114
  | update ID (i :: is) data ((py as Node (key, d, pys)) :: pyss) =
walther@59884
   115
    if i = key
walther@59897
   116
    then ((Node (key,  d, update ID is data pys)) :: pyss)
walther@59897
   117
    else (py :: (update ID (i :: is) data pyss))
walther@59897
   118
  | update _ _ _ _ = raise ERROR "update called with undef pattern.";
walther@59882
   119
Walther@60729
   120
fun get_node(*1*) _ revkey [] = raise ERROR ("Store.get_node []: not found: " ^ strs2str revkey)
Walther@60729
   121
  | get_node(*2*) (key as (k1 :: _)) revkey ((node as Node (key', _, [])) :: ns) = (*spec.case same l.*)
Walther@60729
   122
(writeln ("get_node 2 " ^ key');
Walther@60729
   123
    if k1 = key' then node
Walther@60729
   124
    else get_node key revkey ns (*continue on same level*)
Walther@60729
   125
)
Walther@60729
   126
  | get_node(*3*) [k1] revkey ((node as Node (key', _, bs)) :: ns) =
Walther@60729
   127
(writeln ("get_node 3 " ^ key');
Walther@60729
   128
    if k1 = key' then node
Walther@60729
   129
    else get_node [k1] revkey ns
Walther@60729
   130
)
Walther@60729
   131
  | get_node(*4*) (key as (k1 :: ks)) revkey (Node (key', _, bs) :: ns) =
Walther@60729
   132
(writeln ("get_node 4 " ^ key');
Walther@60729
   133
    if k1 = key'
Walther@60729
   134
    then get_node_down ks revkey bs
Walther@60729
   135
    else get_node key revkey ns
Walther@60729
   136
)
Walther@60729
   137
  | get_node(*5*) _ revkey _ =
Walther@60729
   138
    raise ERROR ("Store.get_node: probably more than one node element for " ^ strs2str revkey)
Walther@60729
   139
and get_node_down(*6*) [k1] revkey ((node as Node (key', _, _)) :: ns) = (*base case go down*)
Walther@60729
   140
(writeln ("get_node_down 6 " ^ key');
Walther@60729
   141
    if k1 = key' then node
Walther@60729
   142
    else get_node [k1] revkey ns
Walther@60729
   143
)
Walther@60729
   144
  | get_node_down(*7*) (key as (k1 :: ks)) revkey (Node (key', _, bs) :: ns) =
Walther@60729
   145
(writeln ("get_node_down 7 " ^ key');
Walther@60729
   146
    if k1 = key'
Walther@60729
   147
    then get_node_down ks revkey bs
Walther@60729
   148
    else get_node key revkey ns
Walther@60729
   149
)
Walther@60729
   150
  | get_node_down(*8*) _ revkey _ =
Walther@60729
   151
    raise ERROR ("Store.get_node: probably more than one node element for " ^ strs2str revkey)
Walther@60729
   152
walther@59882
   153
(**)end(**)