2011-09-26 22:34:07 -05:00
|
|
|
use std;
|
|
|
|
import std::rand;
|
2012-02-24 21:26:42 -06:00
|
|
|
import uint::range;
|
2011-09-26 22:34:07 -05:00
|
|
|
|
|
|
|
// random uint less than n
|
2012-04-13 13:59:17 -05:00
|
|
|
fn under(r : rand::rng, n : uint) -> uint {
|
|
|
|
assert n != 0u; r.next() as uint % n
|
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
|
|
|
|
// random choice from a vec
|
2012-06-29 18:26:56 -05:00
|
|
|
fn choice<T: copy>(r : rand::rng, v : ~[const T]) -> T {
|
2012-04-13 13:59:17 -05:00
|
|
|
assert vec::len(v) != 0u; v[under(r, vec::len(v))]
|
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
|
2012-02-24 21:26:42 -06:00
|
|
|
// k in n chance of being true
|
|
|
|
fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }
|
|
|
|
|
|
|
|
|
|
|
|
const iters : uint = 1000u;
|
|
|
|
const vlen : uint = 100u;
|
2011-09-26 22:34:07 -05:00
|
|
|
|
2012-01-19 18:21:33 -06:00
|
|
|
enum maybe_pointy {
|
2012-02-24 21:26:42 -06:00
|
|
|
none,
|
|
|
|
p(@pointy)
|
2011-09-26 22:34:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
type pointy = {
|
2012-02-24 21:26:42 -06:00
|
|
|
mut a : maybe_pointy,
|
|
|
|
mut b : ~maybe_pointy,
|
|
|
|
mut c : @maybe_pointy,
|
|
|
|
|
|
|
|
mut f : fn@()->(),
|
|
|
|
mut g : fn~()->(),
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
mut m : ~[maybe_pointy],
|
|
|
|
mut n : ~[mut maybe_pointy],
|
2012-02-24 21:26:42 -06:00
|
|
|
mut o : {x : int, y : maybe_pointy}
|
2011-09-26 22:34:07 -05:00
|
|
|
};
|
2012-07-31 12:27:51 -05:00
|
|
|
// To add: objects; traits; anything type-parameterized?
|
2012-02-24 21:26:42 -06:00
|
|
|
|
|
|
|
fn empty_pointy() -> @pointy {
|
2012-08-01 19:30:05 -05:00
|
|
|
return @{
|
2012-02-24 21:26:42 -06:00
|
|
|
mut a : none,
|
|
|
|
mut b : ~none,
|
|
|
|
mut c : @none,
|
2011-09-26 22:34:07 -05:00
|
|
|
|
2012-02-24 21:26:42 -06:00
|
|
|
mut f : fn@()->(){},
|
|
|
|
mut g : fn~()->(){},
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
mut m : ~[],
|
|
|
|
mut n : ~[mut],
|
2012-02-24 21:26:42 -06:00
|
|
|
mut o : {x : 0, y : none}
|
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
}
|
|
|
|
|
2012-02-24 21:26:42 -06:00
|
|
|
fn nopP(_x : @pointy) { }
|
|
|
|
fn nop<T>(_x: T) { }
|
2011-09-26 22:34:07 -05:00
|
|
|
|
2012-02-24 21:26:42 -06:00
|
|
|
fn test_cycles(r : rand::rng, k: uint, n: uint)
|
2011-09-26 22:34:07 -05:00
|
|
|
{
|
2012-06-29 18:26:56 -05:00
|
|
|
let v : ~[mut @pointy] = ~[mut];
|
2011-09-26 22:34:07 -05:00
|
|
|
|
2012-02-24 21:26:42 -06:00
|
|
|
// Create a graph with no edges
|
|
|
|
range(0u, vlen) {|_i|
|
2012-06-15 20:16:42 -05:00
|
|
|
vec::push(v, empty_pointy());
|
2011-10-21 07:12:12 -05:00
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
|
2012-02-24 21:26:42 -06:00
|
|
|
// Fill in the graph with random edges, with density k/n
|
|
|
|
range(0u, vlen) {|i|
|
|
|
|
if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
|
|
|
|
if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
|
|
|
|
if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }
|
|
|
|
|
|
|
|
if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
|
2012-04-13 13:59:17 -05:00
|
|
|
//if (false) { v[i].g = bind (fn~(_x: @pointy) { })(
|
|
|
|
// choice(r, v)); }
|
2012-02-24 21:26:42 -06:00
|
|
|
// https://github.com/mozilla/rust/issues/1899
|
|
|
|
|
|
|
|
if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
|
2012-06-15 20:16:42 -05:00
|
|
|
if (likelihood(r, k, n)) { vec::push(v[i].n, mut p(choice(r, v))); }
|
2012-02-24 21:26:42 -06:00
|
|
|
if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
|
2011-10-21 07:12:12 -05:00
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
|
|
|
|
// Drop refs one at a time
|
2012-02-24 21:26:42 -06:00
|
|
|
range(0u, vlen) {|i|
|
|
|
|
v[i] = empty_pointy()
|
2011-10-21 07:12:12 -05:00
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main()
|
|
|
|
{
|
2012-03-28 14:30:07 -05:00
|
|
|
let r = rand::rng();
|
2012-02-24 21:26:42 -06:00
|
|
|
range(0u, iters) {|i|
|
|
|
|
test_cycles(r, i, iters);
|
|
|
|
}
|
2011-09-26 22:34:07 -05:00
|
|
|
}
|