Beispiel #1
0
// Match attempts to match the internal constant representations of x and y.
// If the attempt is successful, the result is the values of x and y,
// if necessary converted to have the same internal representation; otherwise
// the results are invalid.
func (x Const) Match(y Const) (u, v Const) {
	switch a := x.val.(type) {
	case bool:
		if _, ok := y.val.(bool); ok {
			u, v = x, y
		}
	case *big.Int:
		switch y.val.(type) {
		case *big.Int:
			u, v = x, y
		case *big.Rat:
			var z big.Rat
			z.SetInt(a)
			u, v = Const{&z}, y
		case cmplx:
			var z big.Rat
			z.SetInt(a)
			u, v = Const{cmplx{&z, big.NewRat(0, 1)}}, y
		}
	case *big.Rat:
		switch y.val.(type) {
		case *big.Int:
			v, u = y.Match(x)
		case *big.Rat:
			u, v = x, y
		case cmplx:
			u, v = Const{cmplx{a, big.NewRat(0, 0)}}, y
		}
	case cmplx:
		switch y.val.(type) {
		case *big.Int, *big.Rat:
			v, u = y.Match(x)
		case cmplx:
			u, v = x, y
		}
	case string:
		if _, ok := y.val.(string); ok {
			u, v = x, y
		}
	default:
		panic("unreachable")
	}
	return
}
func split(turn, maxTurns int, blueDiscsDrawn int, current, result *big.Rat) {

	if blueDiscsDrawn > (maxTurns / 2) {
		result.Add(result, current)
		//fmt.Println(blueDiscsDrawn, current)
		return
	} else if turn > maxTurns {
		return
	}

	redCurrent := big.NewRat(1, 1)
	blueCurrent := big.NewRat(1, 1)

	redCurrent.Mul(current, big.NewRat(int64(turn), int64(turn+1)))
	blueCurrent.Mul(current, big.NewRat(1, int64(turn+1)))

	split(turn+1, maxTurns, blueDiscsDrawn, redCurrent, result)
	split(turn+1, maxTurns, blueDiscsDrawn+1, blueCurrent, result)

}
Beispiel #3
0
// MakeConst makes an ideal constant from a literal
// token and the corresponding literal string.
func MakeConst(tok token.Token, lit string) Const {
	switch tok {
	case token.INT:
		var x big.Int
		_, ok := x.SetString(lit, 0)
		assert(ok)
		return Const{&x}
	case token.FLOAT:
		var y big.Rat
		_, ok := y.SetString(lit)
		assert(ok)
		return Const{&y}
	case token.IMAG:
		assert(lit[len(lit)-1] == 'i')
		var im big.Rat
		_, ok := im.SetString(lit[0 : len(lit)-1])
		assert(ok)
		return Const{cmplx{big.NewRat(0, 1), &im}}
	case token.CHAR:
		assert(lit[0] == '\'' && lit[len(lit)-1] == '\'')
		code, _, _, err := strconv.UnquoteChar(lit[1:len(lit)-1], '\'')
		assert(err == nil)
		return Const{big.NewInt(int64(code))}
	case token.STRING:
		s, err := strconv.Unquote(lit)
		assert(err == nil)
		return Const{s}
	}
	panic("unreachable")
}
func assertProb(t *T, b *Bayesian, expected *big.Rat, word string) {
	actual := b.ProbAWhenB(word)
	if expected.Cmp(actual) != 0 {
		t.Errorf("'%s' should be correlated %v:%v with Grinnell tweets, but was %v:%v\n",
			word,
			expected.Num(), expected.Denom(),
			actual.Num(), actual.Denom())
	}
}
// a.convertTo(t) converts the value of the analyzed expression a,
// which must be a constant, ideal number, to a new analyzed
// expression with a constant value of type t.
//
// TODO(austin) Rename to resolveIdeal or something?
func (a *expr) convertTo(t Type) *expr {
	if !a.t.isIdeal() {
		log.Panicf("attempted to convert from %v, expected ideal", a.t)
	}

	var rat *big.Rat

	// XXX(Spec)  The spec says "It is erroneous".
	//
	// It is an error to assign a value with a non-zero fractional
	// part to an integer, or if the assignment would overflow or
	// underflow, or in general if the value cannot be represented
	// by the type of the variable.
	switch a.t {
	case IdealFloatType:
		rat = a.asIdealFloat()()
		if t.isInteger() && !rat.IsInt() {
			a.diag("constant %v truncated to integer", rat.FloatString(6))
			return nil
		}
	case IdealIntType:
		i := a.asIdealInt()()
		rat = new(big.Rat).SetInt(i)
	default:
		log.Panicf("unexpected ideal type %v", a.t)
	}

	// Check bounds
	if t, ok := t.lit().(BoundedType); ok {
		if rat.Cmp(t.minVal()) < 0 {
			a.diag("constant %v underflows %v", rat.FloatString(6), t)
			return nil
		}
		if rat.Cmp(t.maxVal()) > 0 {
			a.diag("constant %v overflows %v", rat.FloatString(6), t)
			return nil
		}
	}

	// Convert rat to type t.
	res := a.newExpr(t, a.desc)
	switch t := t.lit().(type) {
	case *uintType:
		n, d := rat.Num(), rat.Denom()
		f := new(big.Int).Quo(n, d)
		f = f.Abs(f)
		v := uint64(f.Int64())
		res.eval = func(*Thread) uint64 { return v }
	case *intType:
		n, d := rat.Num(), rat.Denom()
		f := new(big.Int).Quo(n, d)
		v := f.Int64()
		res.eval = func(*Thread) int64 { return v }
	case *idealIntType:
		n, d := rat.Num(), rat.Denom()
		f := new(big.Int).Quo(n, d)
		res.eval = func() *big.Int { return f }
	case *floatType:
		n, d := rat.Num(), rat.Denom()
		v := float64(n.Int64()) / float64(d.Int64())
		res.eval = func(*Thread) float64 { return v }
	case *idealFloatType:
		res.eval = func() *big.Rat { return rat }
	default:
		log.Panicf("cannot convert to type %T", t)
	}

	return res
}
Beispiel #6
0
func simpRat(x *big.Rat) Obj {
	if x.Denom().Cmp(one_Int) == 0 {
		return simpBig(x.Num())
	}
	return wrap(x)
}
Beispiel #7
0
func binaryCmplxOp(x cmplx, op token.Token, y cmplx) interface{} {
	a, b := x.re, x.im
	c, d := y.re, y.im
	switch op {
	case token.ADD:
		// (a+c) + i(b+d)
		var re, im big.Rat
		re.Add(a, c)
		im.Add(b, d)
		return cmplx{&re, &im}
	case token.SUB:
		// (a-c) + i(b-d)
		var re, im big.Rat
		re.Sub(a, c)
		im.Sub(b, d)
		return cmplx{&re, &im}
	case token.MUL:
		// (ac-bd) + i(bc+ad)
		var ac, bd, bc, ad big.Rat
		ac.Mul(a, c)
		bd.Mul(b, d)
		bc.Mul(b, c)
		ad.Mul(a, d)
		var re, im big.Rat
		re.Sub(&ac, &bd)
		im.Add(&bc, &ad)
		return cmplx{&re, &im}
	case token.QUO:
		// (ac+bd)/s + i(bc-ad)/s, with s = cc + dd
		var ac, bd, bc, ad, s big.Rat
		ac.Mul(a, c)
		bd.Mul(b, d)
		bc.Mul(b, c)
		ad.Mul(a, d)
		s.Add(c.Mul(c, c), d.Mul(d, d))
		var re, im big.Rat
		re.Add(&ac, &bd)
		re.Quo(&re, &s)
		im.Sub(&bc, &ad)
		im.Quo(&im, &s)
		return cmplx{&re, &im}
	case token.EQL:
		return a.Cmp(c) == 0 && b.Cmp(d) == 0
	case token.NEQ:
		return a.Cmp(c) != 0 || b.Cmp(d) != 0
	}
	panic("unreachable")
}
Beispiel #8
0
func binaryFloatOp(x *big.Rat, op token.Token, y *big.Rat) interface{} {
	var z big.Rat
	switch op {
	case token.ADD:
		return z.Add(x, y)
	case token.SUB:
		return z.Sub(x, y)
	case token.MUL:
		return z.Mul(x, y)
	case token.QUO:
		return z.Quo(x, y)
	case token.EQL:
		return x.Cmp(y) == 0
	case token.NEQ:
		return x.Cmp(y) != 0
	case token.LSS:
		return x.Cmp(y) < 0
	case token.LEQ:
		return x.Cmp(y) <= 0
	case token.GTR:
		return x.Cmp(y) > 0
	case token.GEQ:
		return x.Cmp(y) >= 0
	}
	panic("unreachable")
}