mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
505 lines
9.4 KiB
Plaintext
505 lines
9.4 KiB
Plaintext
(***********************************************************************)
|
|
(* *)
|
|
(* Applied Type System *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
(*
|
|
** ATS/Postiats - Unleashing the Potential of Types!
|
|
** Copyright (C) 2011-2013 Hongwei Xi, ATS Trustful Software, Inc.
|
|
** All rights reserved
|
|
**
|
|
** ATS is free software; you can redistribute it and/or modify it under
|
|
** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the
|
|
** Free Software Foundation; either version 3, or (at your option) any
|
|
** later version.
|
|
**
|
|
** ATS is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
** WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
** for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with ATS; see the file COPYING. If not, please write to the
|
|
** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|
** 02110-1301, USA.
|
|
*)
|
|
|
|
(* ****** ****** *)
|
|
|
|
(* Author: Hongwei Xi *)
|
|
(* Authoremail: hwxi AT cs DOT bu DOT edu *)
|
|
(* Start time: February, 2013 *)
|
|
|
|
(* ****** ****** *)
|
|
//
|
|
// HX-2013-08:
|
|
// a set is represented as a sorted list in descending order;
|
|
// note that descending order is chosen to faciliate set comparison
|
|
//
|
|
(* ****** ****** *)
|
|
|
|
staload
|
|
UN = "prelude/SATS/unsafe.sats"
|
|
|
|
(* ****** ****** *)
|
|
|
|
staload "libats/SATS/linset_listord.sats"
|
|
|
|
(* ****** ****** *)
|
|
|
|
#include "./SHARE/linset.hats" // code reuse
|
|
#include "./SHARE/linset_node.hats" // code reuse
|
|
|
|
(* ****** ****** *)
|
|
|
|
assume
|
|
set_vtype (elt:t@ype) = List0_vt (elt)
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{}
|
|
linset_nil () = list_vt_nil ()
|
|
implement{}
|
|
linset_make_nil () = list_vt_nil ()
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
linset_sing
|
|
(x) = list_vt_cons{a}(x, list_vt_nil)
|
|
// end of [linset_sing]
|
|
implement{a}
|
|
linset_make_sing
|
|
(x) = list_vt_cons{a}(x, list_vt_nil)
|
|
// end of [linset_make_sing]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{}
|
|
linset_is_nil (xs) = list_vt_is_nil (xs)
|
|
implement{}
|
|
linset_isnot_nil (xs) = list_vt_is_cons (xs)
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{a}
|
|
linset_size (xs) =
|
|
let val n = list_vt_length(xs) in i2sz(n) end
|
|
// end of [linset_size]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{a}
|
|
linset_is_member
|
|
(xs, x0) = let
|
|
//
|
|
fun aux
|
|
{n:nat} .<n>.
|
|
(
|
|
xs: !list_vt (a, n)
|
|
) :<> bool = let
|
|
in
|
|
//
|
|
case+ xs of
|
|
| list_vt_cons (x, xs) => let
|
|
val sgn = compare_elt_elt<a> (x0, x) in
|
|
if sgn > 0 then false else (if sgn < 0 then aux (xs) else true)
|
|
end // end of [list_vt_cons]
|
|
| list_vt_nil ((*void*)) => false
|
|
//
|
|
end // end of [aux]
|
|
//
|
|
in
|
|
aux (xs)
|
|
end // end of [linset_is_member]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{a}
|
|
linset_copy (xs) = list_vt_copy<a> (xs)
|
|
implement{a}
|
|
linset_free (xs) = list_vt_free<a> (xs)
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{a}
|
|
linset_insert
|
|
(xs, x0) = let
|
|
//
|
|
fun
|
|
mynode_cons
|
|
{n:nat} .<>.
|
|
(
|
|
nx: mynode1 (a), xs: list_vt (a, n)
|
|
) : list_vt (a, n+1) = let
|
|
//
|
|
val xs1 =
|
|
$UN.castvwtp0{List1_vt(a)}(nx)
|
|
val+@list_vt_cons (_, xs2) = xs1
|
|
prval () = $UN.cast2void (xs2); val () = (xs2 := xs)
|
|
//
|
|
in
|
|
fold@ (xs1); xs1
|
|
end // end of [mynode_cons]
|
|
//
|
|
fun ins
|
|
{n:nat} .<n>. // tail-recursive
|
|
(
|
|
xs: &list_vt (a, n) >> list_vt (a, n1)
|
|
) : #[n1:nat | n <= n1; n1 <= n+1] bool =
|
|
(
|
|
case+ xs of
|
|
| @list_vt_cons
|
|
(x, xs1) => let
|
|
val sgn =
|
|
compare_elt_elt<a> (x0, x)
|
|
// end of [val]
|
|
in
|
|
if sgn > 0 then let
|
|
prval () = fold@ (xs)
|
|
val nx = mynode_make_elt<a> (x0)
|
|
val ((*void*)) = xs := mynode_cons (nx, xs)
|
|
in
|
|
false
|
|
end else if sgn < 0 then let
|
|
val ans = ins (xs1)
|
|
prval () = fold@ (xs)
|
|
in
|
|
ans
|
|
end else let // [x0] is found
|
|
prval () = fold@ (xs)
|
|
in
|
|
true (* [x0] in [xs] *)
|
|
end (* end of [if] *)
|
|
end // end of [list_vt_cons]
|
|
| list_vt_nil () => let
|
|
val nx = mynode_make_elt<a> (x0)
|
|
val ((*void*)) = xs := mynode_cons (nx, xs)
|
|
in
|
|
false
|
|
end // end of [list_vt_nil]
|
|
) (* end of [ins] *)
|
|
//
|
|
in
|
|
$effmask_all (ins (xs))
|
|
end // end of [linset_insert]
|
|
|
|
(* ****** ****** *)
|
|
|
|
(*
|
|
//
|
|
HX-2013-08:
|
|
[linset_remove] moved up
|
|
//
|
|
implement{a}
|
|
linset_remove
|
|
(xs, x0) = let
|
|
//
|
|
fun rem
|
|
{n:nat} .<n>. // tail-recursive
|
|
(
|
|
xs: &list_vt (a, n) >> list_vt (a, n1)
|
|
) : #[n1:nat | n1 <= n; n <= n1+1] bool =
|
|
(
|
|
case+ xs of
|
|
| @list_vt_cons
|
|
(x, xs1) => let
|
|
val sgn =
|
|
compare_elt_elt<a> (x0, x)
|
|
// end of [val]
|
|
in
|
|
if sgn > 0 then let
|
|
prval () = fold@ (xs)
|
|
in
|
|
false
|
|
end else if sgn < 0 then let
|
|
val ans = rem (xs1)
|
|
prval () = fold@ (xs)
|
|
in
|
|
ans
|
|
end else let // x0 = x
|
|
val xs1_ = xs1
|
|
val ((*void*)) = free@{a}{0}(xs)
|
|
val () = xs := xs1_
|
|
in
|
|
true // [x0] in [xs]
|
|
end (* end of [if] *)
|
|
end // end of [list_vt_cons]
|
|
| list_vt_nil () => false
|
|
) (* end of [rem] *)
|
|
//
|
|
in
|
|
$effmask_all (rem (xs))
|
|
end // end of [linset_remove]
|
|
*)
|
|
|
|
(* ****** ****** *)
|
|
(*
|
|
** By Brandon Barker
|
|
*)
|
|
implement
|
|
{a}(*tmp*)
|
|
linset_choose
|
|
(xs, x0) = let
|
|
in
|
|
//
|
|
case+ xs of
|
|
| list_vt_cons
|
|
(x, xs1) => let
|
|
val () = x0 := x
|
|
prval () = opt_some{a}(x0)
|
|
in
|
|
true
|
|
end // end of [list_vt_cons]
|
|
| list_vt_nil () => let
|
|
prval () = opt_none{a}(x0)
|
|
in
|
|
false
|
|
end // end of [list_vt_nil]
|
|
//
|
|
end // end of [linset_choose]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}{env}
|
|
linset_foreach_env (xs, env) = let
|
|
//
|
|
implement
|
|
list_vt_foreach$fwork<a><env>
|
|
(x, env) = linset_foreach$fwork<a><env> (x, env)
|
|
//
|
|
in
|
|
list_vt_foreach_env<a><env> (xs, env)
|
|
end // end of [linset_foreach_env]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{a}
|
|
linset_listize (xs) = xs
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{a}
|
|
linset_listize1 (xs) = list_vt_copy (xs)
|
|
|
|
(* ****** ****** *)
|
|
//
|
|
// HX: functions for processing mynodes
|
|
//
|
|
(* ****** ****** *)
|
|
|
|
implement{
|
|
} mynode_null{a} () =
|
|
$UN.castvwtp0{mynode(a,null)}(the_null_ptr)
|
|
// end of [mynode_null]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
mynode_make_elt
|
|
(x) = let
|
|
//
|
|
val nx = list_vt_cons{a}{0}(x, _ )
|
|
//
|
|
in
|
|
$UN.castvwtp0{mynode1(a)}(nx)
|
|
end // end of [mynode_make_elt]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement{
|
|
} mynode_free
|
|
{a}(nx) = () where {
|
|
val nx =
|
|
$UN.castvwtp0{List1_vt(a)}(nx)
|
|
//
|
|
val+~list_vt_cons (_, nx2) = nx
|
|
//
|
|
prval ((*void*)) = $UN.cast2void (nx2)
|
|
//
|
|
} (* end of [mynode_free] *)
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
mynode_get_elt
|
|
(nx) = (x) where {
|
|
//
|
|
val nx1 =
|
|
$UN.castvwtp1{List1_vt(a)}(nx)
|
|
//
|
|
val+list_vt_cons (x, _) = nx1
|
|
//
|
|
prval ((*void*)) = $UN.cast2void (nx1)
|
|
//
|
|
} (* end of [mynode_get_elt] *)
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
mynode_set_elt
|
|
{l} (nx, x0) =
|
|
{
|
|
//
|
|
val nx1 =
|
|
$UN.castvwtp1{List1_vt(a)}(nx)
|
|
//
|
|
val+@list_vt_cons (x, _) = nx1
|
|
//
|
|
val () = x := x0
|
|
//
|
|
prval () = fold@ (nx1)
|
|
prval () = $UN.cast2void (nx1)
|
|
//
|
|
prval () = __assert (nx) where
|
|
{
|
|
extern praxi __assert (nx: !mynode(a?, l) >> mynode (a, l)): void
|
|
} (* end of [prval] *)
|
|
//
|
|
} (* end of [mynode_set_elt] *)
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
mynode_getfree_elt
|
|
(nx) = (x) where {
|
|
//
|
|
val nx =
|
|
$UN.castvwtp0{List1_vt(a)}(nx)
|
|
//
|
|
val+~list_vt_cons (x, nx2) = nx
|
|
//
|
|
prval ((*void*)) = $UN.cast2void (nx2)
|
|
//
|
|
} (* end of [mynode_getfree_elt] *)
|
|
|
|
(* ****** ****** *)
|
|
|
|
(*
|
|
fun{a:t0p}
|
|
linset_takeout_ngc
|
|
(set: &set(INV(a)) >> _, x0: a):<!wrt> mynode0 (a)
|
|
// end of [linset_takeout_ngc]
|
|
*)
|
|
implement
|
|
{a}(*tmp*)
|
|
linset_takeout_ngc
|
|
(set, x0) = let
|
|
//
|
|
fun takeout
|
|
(
|
|
xs: &List0_vt (a) >> _
|
|
) : mynode0(a) = let
|
|
in
|
|
//
|
|
case+ xs of
|
|
| @list_vt_cons
|
|
(x, xs1) => let
|
|
prval pf_x = view@x
|
|
prval pf_xs1 = view@xs1
|
|
val sgn =
|
|
compare_elt_elt<a> (x0, x)
|
|
// end of [val]
|
|
in
|
|
if sgn > 0 then let
|
|
prval () = fold@ (xs)
|
|
in
|
|
mynode_null{a}((*void*))
|
|
end else if sgn < 0 then let
|
|
val res = takeout (xs1)
|
|
prval ((*void*)) = fold@ (xs)
|
|
in
|
|
res
|
|
end else let // x0 = x
|
|
val xs1_ = xs1
|
|
val res = $UN.castvwtp0{mynode1(a)}((pf_x, pf_xs1 | xs))
|
|
val () = xs := xs1_
|
|
in
|
|
res // [x0] in [xs]
|
|
end (* end of [if] *)
|
|
end // end of [list_vt_cons]
|
|
| list_vt_nil () => mynode_null{a}((*void*))
|
|
//
|
|
end (* end of [takeout] *)
|
|
//
|
|
in
|
|
$effmask_all (takeout (set))
|
|
end // end of [linset_takeout_ngc]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
linset_takeoutmax_ngc
|
|
(xs) = let
|
|
in
|
|
//
|
|
case+ xs of
|
|
| @list_vt_cons
|
|
(x, xs1) => let
|
|
prval pf_x = view@x
|
|
prval pf_xs1 = view@xs1
|
|
val xs_ = xs
|
|
val () = xs := xs1
|
|
in
|
|
$UN.castvwtp0{mynode1(a)}((pf_x, pf_xs1 | xs_))
|
|
end // end of [list_vt_cons]
|
|
| @list_vt_nil () => let
|
|
prval () = fold@ (xs)
|
|
in
|
|
mynode_null{a}((*void*))
|
|
end // end of [list_vt_nil]
|
|
//
|
|
end // end of [linset_takeoutmax_ngc]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
{a}(*tmp*)
|
|
linset_takeoutmin_ngc
|
|
(xs) = let
|
|
//
|
|
fun unsnoc
|
|
{n:pos} .<n>.
|
|
(
|
|
xs: &list_vt (a, n) >> list_vt (a, n-1)
|
|
) :<!wrt> mynode1 (a) = let
|
|
//
|
|
val+@list_vt_cons (x, xs1) = xs
|
|
//
|
|
prval pf_x = view@x and pf_xs1 = view@xs1
|
|
//
|
|
in
|
|
//
|
|
case+ xs1 of
|
|
| list_vt_cons _ =>
|
|
let val res = unsnoc(xs1) in fold@xs; res end
|
|
// end of [list_vt_cons]
|
|
| list_vt_nil () => let
|
|
val xs_ = xs
|
|
val () = xs := list_vt_nil{a}()
|
|
in
|
|
$UN.castvwtp0{mynode1(a)}((pf_x, pf_xs1 | xs_))
|
|
end // end of [list_vt_nil]
|
|
//
|
|
end // end of [unsnoc]
|
|
//
|
|
in
|
|
//
|
|
case+ xs of
|
|
| list_vt_cons _ => unsnoc (xs)
|
|
| list_vt_nil () => mynode_null{a}((*void*))
|
|
//
|
|
end // end of [linset_takeoutmin_ngc]
|
|
|
|
(* ****** ****** *)
|
|
|
|
(* end of [linset_listord.dats] *)
|