diff --git a/examples/skiplist-1-4.p3l b/examples/skiplist-1-4.p3l deleted file mode 100644 index c60107c..0000000 --- a/examples/skiplist-1-4.p3l +++ /dev/null @@ -1,383 +0,0 @@ -// 0: own level (lowest level is 0) -// 1: entry below this one (exists iff level is greater than 0) -// 2: entry to the right of this one -type SkipList = (int, SkipListLink, Option>); - -type SkipListLink = Option>>; - -// 0: own level (lowest level is 0) -// 1: entry below this one (exists iff level is greater than 0) -// 2: entry to the right of this one -// 3: key of the column this entry belongs to -// 4: value of the column (only on the lowest level) -type SkipListNode = Rc<(int, Option>, Option>, int, Option)>; - -type Stack = Rc<(Option<(T, Stack)>,)>; - -// Unwrap an option. -fn unwrap(opt: Option) -> T { - if let Some(value) = opt { - return value; - } -} - -// Create a new, empty stack -fn stack_new() -> Stack { - return Rc((None,)); -} - -// Push a new value to the stack. -fn stack_push(stack: Stack, value: T) { - stack.0 = Some((value, Rc(*stack))); -} - -// Pop a value from the stack. -fn stack_pop(stack: Stack) -> Option { - if let Some(top) = (*stack).0 { - stack.0 = (*top.1).0; - return Some(top.0); - } - return None; -} - -// Return a new, empty skiplist. -fn skiplist_new() -> SkipList { - return (0, None, None); -} - -// Return the current maximum level of the skiplist. -fn skiplist_level(list: SkipList) -> int { - return list.0; -} - -// NOT PUBLIC API -// Insert a new value into the skiplist at the first position. -fn skiplist_insert_first( - list: SkipList, - new_lvl: int, - key: int, - value: V -) -> SkipList { - // decompose list into levels - let levels: Stack>> = - stack_new::>>(); - let _unit: () = stack_push::>>(levels, list.2); - while let Some(next) = list.1 { - list = *next; - let _unit: () = stack_push::>>(levels, list.2); - } - - // create new list with just the lowest level - let lvl: int = 0; - let top: Option>> = - stack_pop::>>(levels); - let new_node: SkipListNode = Rc(( - 0, - None, - unwrap::>>(top), - key, - Some(value) - )); - list = (0, None, Some(new_node)); - - // rebuild list up to its original level - while let Some(top) = stack_pop::>>(levels) { - lvl = lvl + 1; - if new_lvl >= lvl { - new_node = Rc((lvl, Some(new_node), top, key, None)); - } else { - let top: SkipListNode = unwrap::>(top); - new_node = Rc((lvl, Some(new_node), (*top).2, (*top).3, None)); - } - list = (lvl, Some(Rc(list)), Some(new_node)); - } - - // add new levels if necessary - while new_lvl > lvl { - lvl = lvl + 1; - new_node = Rc((lvl, Some(new_node), None, key, None)); - list = (lvl, Some(Rc(list)), Some(new_node)); - } - - return list; -} - -// NOT PUBLIC API -// Insert a new value into the skiplist that needs to be inserted after -// the current node. Will be called when entering a new level while -// searching for the insert position. Returns the level of the inserted -// node. -fn skiplist_insert_impl( - node: SkipListNode, - new_lvl: int, - key: int, - value: V -) -> Option> { - // go to the last node in the level whose key is less than the new key - while true { - if let Some(next) = (*node).2 { - if (*next).3 < key { - node = next; - continue; - } - } - break; - } - - // when not at the lowest level, descend - if let Some(below) = (*node).1 { - let new_node: Option> = - skiplist_insert_impl::(below, new_lvl, key, value); - if let Some(new_node) = new_node { - let node_lvl: int = (*node).0; - if new_lvl >= node_lvl { - let new_node: SkipListNode = - Rc((node_lvl, Some(new_node), (*node).2, key, None)); - node.2 = Some(new_node); - return Some(new_node); - } - } - return new_node; - } - - // if we found a node with the exact key, just update the value - if (*node).3 == key { - node.4 = Some(value); - return None; - } - - // otherwise, we need to create a new node immediately following the - // current one - let new_node: SkipListNode = - Rc((0, None, (*node).2, key, Some(value))); - node.2 = Some(new_node); - return Some(new_node); -} - -// NOT PUBLIC API -// Insert a new value with a set level. -fn skiplist_insert_with_level( - orig_list: SkipList, - new_lvl: int, - key: int, - value: V -) -> SkipList { - // find the level at which to start search for the insert position - let list: SkipList = orig_list; - while true { - if let Some(level) = list.2 { - if (*level).3 <= key { - break; - } - } - - if let Some(below) = list.1 { - list = *below; - } else { - return skiplist_insert_first::(list, new_lvl, key, value); - } - } - - if let Some(node) = list.2 { - let new_node: Option> = - skiplist_insert_impl::(node, new_lvl, key, value); - if let Some(new_node) = new_node { - let node_lvl: int = (*node).0; - - // update levels above node_lvl if necessary - list = orig_list; - if new_lvl >= list.0 { - let new_node: SkipListNode = - Rc((list.0, None, list.2, key, None)); - list.2 = Some(new_node); - } - while let Some(below) = list.1 { - list = *below; - if list.0 <= node_lvl || list.0 < new_lvl { - break; - } - let new_node: SkipListNode = - Rc((list.0, None, list.2, key, None)); - list.2 = Some(new_node); - } - - // add levels above the list level if necessary - list = orig_list; - while new_lvl > list.0 { - new_node = Rc((list.0, Some(new_node), None, key, None)); - list = (list.0 + 1, Some(Rc(list)), Some(new_node)); - } - - return list; - } else { - return orig_list; - } - } else { - // we are inserting into an empty list - return skiplist_insert_first::(list, new_lvl, key, value); - } -} - -// NOT PUBLIC API -// Return a random level. -fn skiplist_random_level() -> int { - let lvl: int = 0; - while true { - { lvl = lvl + 1; } [0.25] { return lvl; } - } -} - -// Take the skiplist, insert a new value, and return the skiplist. -fn skiplist_insert( - list: SkipList, - key: int, - value: V -) -> SkipList { - let lvl: int = skiplist_random_level(); - return skiplist_insert_with_level::(list, lvl, key, value); -} - -// NOT PUBLIC API -// Find a value in the skiplist, starting the search at a specific node. -// Return the value along with the path length of the search. -fn skiplist_get_impl( - node: SkipListNode, - key: int -) -> (Option, int) { - let pathlen: int = 1; - - if (*node).3 < key { - while true { - if let Some(next) = (*node).2 { - let next_key: int = (*next).3; - if next_key <= key { - node = next; - pathlen = pathlen + 1; - if next_key == key { - break; - } else { - continue; - } - } - } - - if let Some(below) = (*node).1 { - node = below; - continue; - } - - break; - } - } - - if (*node).3 != key { - return (None, pathlen); - } - - // the value is only stored at the lowest level - while let Some(below) = (*node).1 { - node = below; - } - return (Some(unwrap::((*node).4)), pathlen); -} - -// Find a value in the skiplist. Return the value along with the path -// length of the search. -fn skiplist_get(list: SkipList, key: int) -> (Option, int) { - let pathlen: int = 0; - - while true { - if let Some(node) = list.2 { - if (*node).3 <= key { - let tmp: (Option, int) = skiplist_get_impl::(node, key); - return (tmp.0, pathlen + tmp.1); - } - } - - if let Some(below) = list.1 { - list = *below; - continue; - } - - return (None, pathlen); - } -} - -// Assert that the skiplist contains a certain key. -fn assert_contains(list: SkipList, key: int) -> () { - if let Some(_value) = skiplist_get::(list, key).0 { - return (); - } -} - -// Return the length of the skiplist. -fn skiplist_len(list: SkipList) -> int { - // descend to the lowest level - while let Some(next) = list.1 { - list = *next; - } - - // count the lowest level - let node: Option> = list.2; - let len: int = 0; - while let Some(next) = node { - len = len + 1; - node = (*next).2; - } - return len; -} - -// Assert that the skiplist has the correct length. -fn assert_len(list: SkipList, len: int) -> () { - if skiplist_len::(list) == len { - return (); - } -} - -// Assert that a value is in a certain range. -fn assert_in_range(value: int, min_incl: int, max_excl: int) -> () { - if value >= min_incl && value < max_excl { - return (); - } -} - -// Return a random number between 0 (inclusive) and -// max (exclusive). -fn random(max: int) -> int { - while true { - let value: int = 0; - let max_value: int = 0; - while max_value < max { - max_value = max_value * 2 + 1; - value = value * 2; - { value = value + 1; } [0.25] {} - } - if value < max { - return value; - } - } -} - -input!(len); - -// create a new list with entries 0..len -let list: SkipList<()> = skiplist_new::<()>(); -let i: int = 0; -while i < len { - list = skiplist_insert::<()>(list, i, ()); - let _unit: () = assert_contains::<()>(list, i); - i = i + 1; -} -let _unit: () = assert_len::<()>(list, len); - -// lookup a random value in the list -let key: int = random(len); -let _unit: () = assert_in_range(key, 0, len); -let lookup: (Option<()>, int) = skiplist_get::<()>(list, key); -let _unit: () = unwrap::<()>(lookup.0); - -let pathlen: int = lookup.1; -let lvl: int = skiplist_level::<()>(list); - -output!(len); -output!(lvl, pathlen); diff --git a/examples/skiplist-3-8.p3l b/examples/skiplist-3-8.p3l deleted file mode 100644 index 356d95d..0000000 --- a/examples/skiplist-3-8.p3l +++ /dev/null @@ -1,383 +0,0 @@ -// 0: own level (lowest level is 0) -// 1: entry below this one (exists iff level is greater than 0) -// 2: entry to the right of this one -type SkipList = (int, SkipListLink, Option>); - -type SkipListLink = Option>>; - -// 0: own level (lowest level is 0) -// 1: entry below this one (exists iff level is greater than 0) -// 2: entry to the right of this one -// 3: key of the column this entry belongs to -// 4: value of the column (only on the lowest level) -type SkipListNode = Rc<(int, Option>, Option>, int, Option)>; - -type Stack = Rc<(Option<(T, Stack)>,)>; - -// Unwrap an option. -fn unwrap(opt: Option) -> T { - if let Some(value) = opt { - return value; - } -} - -// Create a new, empty stack -fn stack_new() -> Stack { - return Rc((None,)); -} - -// Push a new value to the stack. -fn stack_push(stack: Stack, value: T) { - stack.0 = Some((value, Rc(*stack))); -} - -// Pop a value from the stack. -fn stack_pop(stack: Stack) -> Option { - if let Some(top) = (*stack).0 { - stack.0 = (*top.1).0; - return Some(top.0); - } - return None; -} - -// Return a new, empty skiplist. -fn skiplist_new() -> SkipList { - return (0, None, None); -} - -// Return the current maximum level of the skiplist. -fn skiplist_level(list: SkipList) -> int { - return list.0; -} - -// NOT PUBLIC API -// Insert a new value into the skiplist at the first position. -fn skiplist_insert_first( - list: SkipList, - new_lvl: int, - key: int, - value: V -) -> SkipList { - // decompose list into levels - let levels: Stack>> = - stack_new::>>(); - let _unit: () = stack_push::>>(levels, list.2); - while let Some(next) = list.1 { - list = *next; - let _unit: () = stack_push::>>(levels, list.2); - } - - // create new list with just the lowest level - let lvl: int = 0; - let top: Option>> = - stack_pop::>>(levels); - let new_node: SkipListNode = Rc(( - 0, - None, - unwrap::>>(top), - key, - Some(value) - )); - list = (0, None, Some(new_node)); - - // rebuild list up to its original level - while let Some(top) = stack_pop::>>(levels) { - lvl = lvl + 1; - if new_lvl >= lvl { - new_node = Rc((lvl, Some(new_node), top, key, None)); - } else { - let top: SkipListNode = unwrap::>(top); - new_node = Rc((lvl, Some(new_node), (*top).2, (*top).3, None)); - } - list = (lvl, Some(Rc(list)), Some(new_node)); - } - - // add new levels if necessary - while new_lvl > lvl { - lvl = lvl + 1; - new_node = Rc((lvl, Some(new_node), None, key, None)); - list = (lvl, Some(Rc(list)), Some(new_node)); - } - - return list; -} - -// NOT PUBLIC API -// Insert a new value into the skiplist that needs to be inserted after -// the current node. Will be called when entering a new level while -// searching for the insert position. Returns the level of the inserted -// node. -fn skiplist_insert_impl( - node: SkipListNode, - new_lvl: int, - key: int, - value: V -) -> Option> { - // go to the last node in the level whose key is less than the new key - while true { - if let Some(next) = (*node).2 { - if (*next).3 < key { - node = next; - continue; - } - } - break; - } - - // when not at the lowest level, descend - if let Some(below) = (*node).1 { - let new_node: Option> = - skiplist_insert_impl::(below, new_lvl, key, value); - if let Some(new_node) = new_node { - let node_lvl: int = (*node).0; - if new_lvl >= node_lvl { - let new_node: SkipListNode = - Rc((node_lvl, Some(new_node), (*node).2, key, None)); - node.2 = Some(new_node); - return Some(new_node); - } - } - return new_node; - } - - // if we found a node with the exact key, just update the value - if (*node).3 == key { - node.4 = Some(value); - return None; - } - - // otherwise, we need to create a new node immediately following the - // current one - let new_node: SkipListNode = - Rc((0, None, (*node).2, key, Some(value))); - node.2 = Some(new_node); - return Some(new_node); -} - -// NOT PUBLIC API -// Insert a new value with a set level. -fn skiplist_insert_with_level( - orig_list: SkipList, - new_lvl: int, - key: int, - value: V -) -> SkipList { - // find the level at which to start search for the insert position - let list: SkipList = orig_list; - while true { - if let Some(level) = list.2 { - if (*level).3 <= key { - break; - } - } - - if let Some(below) = list.1 { - list = *below; - } else { - return skiplist_insert_first::(list, new_lvl, key, value); - } - } - - if let Some(node) = list.2 { - let new_node: Option> = - skiplist_insert_impl::(node, new_lvl, key, value); - if let Some(new_node) = new_node { - let node_lvl: int = (*node).0; - - // update levels above node_lvl if necessary - list = orig_list; - if new_lvl >= list.0 { - let new_node: SkipListNode = - Rc((list.0, None, list.2, key, None)); - list.2 = Some(new_node); - } - while let Some(below) = list.1 { - list = *below; - if list.0 <= node_lvl || list.0 < new_lvl { - break; - } - let new_node: SkipListNode = - Rc((list.0, None, list.2, key, None)); - list.2 = Some(new_node); - } - - // add levels above the list level if necessary - list = orig_list; - while new_lvl > list.0 { - new_node = Rc((list.0, Some(new_node), None, key, None)); - list = (list.0 + 1, Some(Rc(list)), Some(new_node)); - } - - return list; - } else { - return orig_list; - } - } else { - // we are inserting into an empty list - return skiplist_insert_first::(list, new_lvl, key, value); - } -} - -// NOT PUBLIC API -// Return a random level. -fn skiplist_random_level() -> int { - let lvl: int = 0; - while true { - { lvl = lvl + 1; } [0.375] { return lvl; } - } -} - -// Take the skiplist, insert a new value, and return the skiplist. -fn skiplist_insert( - list: SkipList, - key: int, - value: V -) -> SkipList { - let lvl: int = skiplist_random_level(); - return skiplist_insert_with_level::(list, lvl, key, value); -} - -// NOT PUBLIC API -// Find a value in the skiplist, starting the search at a specific node. -// Return the value along with the path length of the search. -fn skiplist_get_impl( - node: SkipListNode, - key: int -) -> (Option, int) { - let pathlen: int = 1; - - if (*node).3 < key { - while true { - if let Some(next) = (*node).2 { - let next_key: int = (*next).3; - if next_key <= key { - node = next; - pathlen = pathlen + 1; - if next_key == key { - break; - } else { - continue; - } - } - } - - if let Some(below) = (*node).1 { - node = below; - continue; - } - - break; - } - } - - if (*node).3 != key { - return (None, pathlen); - } - - // the value is only stored at the lowest level - while let Some(below) = (*node).1 { - node = below; - } - return (Some(unwrap::((*node).4)), pathlen); -} - -// Find a value in the skiplist. Return the value along with the path -// length of the search. -fn skiplist_get(list: SkipList, key: int) -> (Option, int) { - let pathlen: int = 0; - - while true { - if let Some(node) = list.2 { - if (*node).3 <= key { - let tmp: (Option, int) = skiplist_get_impl::(node, key); - return (tmp.0, pathlen + tmp.1); - } - } - - if let Some(below) = list.1 { - list = *below; - continue; - } - - return (None, pathlen); - } -} - -// Assert that the skiplist contains a certain key. -fn assert_contains(list: SkipList, key: int) -> () { - if let Some(_value) = skiplist_get::(list, key).0 { - return (); - } -} - -// Return the length of the skiplist. -fn skiplist_len(list: SkipList) -> int { - // descend to the lowest level - while let Some(next) = list.1 { - list = *next; - } - - // count the lowest level - let node: Option> = list.2; - let len: int = 0; - while let Some(next) = node { - len = len + 1; - node = (*next).2; - } - return len; -} - -// Assert that the skiplist has the correct length. -fn assert_len(list: SkipList, len: int) -> () { - if skiplist_len::(list) == len { - return (); - } -} - -// Assert that a value is in a certain range. -fn assert_in_range(value: int, min_incl: int, max_excl: int) -> () { - if value >= min_incl && value < max_excl { - return (); - } -} - -// Return a random number between 0 (inclusive) and -// max (exclusive). -fn random(max: int) -> int { - while true { - let value: int = 0; - let max_value: int = 0; - while max_value < max { - max_value = max_value * 2 + 1; - value = value * 2; - { value = value + 1; } [0.375] {} - } - if value < max { - return value; - } - } -} - -input!(len); - -// create a new list with entries 0..len -let list: SkipList<()> = skiplist_new::<()>(); -let i: int = 0; -while i < len { - list = skiplist_insert::<()>(list, i, ()); - let _unit: () = assert_contains::<()>(list, i); - i = i + 1; -} -let _unit: () = assert_len::<()>(list, len); - -// lookup a random value in the list -let key: int = random(len); -let _unit: () = assert_in_range(key, 0, len); -let lookup: (Option<()>, int) = skiplist_get::<()>(list, key); -let _unit: () = unwrap::<()>(lookup.0); - -let pathlen: int = lookup.1; -let lvl: int = skiplist_level::<()>(list); - -output!(len); -output!(lvl, pathlen);