Proof: Difference between revisions

6,194 bytes added ,  3 years ago
Added Wren
No edit summary
(Added Wren)
Line 1,382:
%total D (sum-evens D _ _ _).
</lang>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
Most of what was said in the preamble to the Go entry applies equally to Wren though, as Wren is dynamically typed, we have to rely on runtime type checks.
<lang ecmascript>import "/fmt" for Fmt
 
// Represents a natural number.
class Number {
// Returns a Number with a null predecessor representing the natural number 0.
static zero { Number.new() }
 
// Generates a natural number from a non-negative integer.
static gen(n) {
if (n.type != Num || !n.isInteger || n < 0) Fiber.abort("Argument must be a non-negative integer.")
if (n > 0) return add1(gen(n-1))
return zero
}
 
// Increments a natural number.
static add1(x) {
if (x.type != Number) Fiber.abort("Argument must be a Number.")
var y = Number.new()
y.pred = x
return y
}
 
// Decrements a natural number.
static sub1(x) {
if (x.type != Number) Fiber.abort("Argument must be a Number.")
return x.pred
}
 
// Counts a natural number i.e returns its integer representation.
static count(x) {
if (x.type != Number) Fiber.abort("Argument must be a Number.")
if (x.isZero) return 0
return count(sub1(x)) + 1
}
 
// Constructs a new Number object with a null predecessor.
construct new() { _pred = null }
 
// Get or set predecessor.
pred { _pred }
pred=(p) {
if (p.type != Number) Fiber.abort("Argument must be a Number.")
_pred = p
}
 
// Tests whether the current instance is zero.
isZero { _pred == null }
 
// Add another Number.
+(other) {
if (other.type != Number) Fiber.abort("Argument must be a Number.")
if (other.isZero) return this
return Number.add1(this) + Number.sub1(other)
}
}
 
// Represents an even natural number: 2 * half.
class EvenNumber {
// Counts an even natural number i.e returns its integer representation.
static count(x) {
if (x.type != EvenNumber) Fiber.abort("Argument must be an EvenNumber.")
return Number.count(x.half) * 2
}
 
// Constructs a new EvenNumber object : 2 * half.
construct new(half) {
if (half.type != Number) Fiber.abort("Argument must be a Number.")
_half = half
}
 
// gets 'half' field
half { _half }
 
// Add another EvenNumber.
+(other) {
if (other.type != EvenNumber) Fiber.abort("Argument must be an EvenNumber.")
if (other.half.isZero) return this
return EvenNumber.new(this.half + other.half)
}
}
 
// Represents an odd natural number: 2 * half + 1.
class OddNumber {
// Counts an odd natural number i.e returns its integer representation.
static count(x) {
if (x.type != OddNumber) Fiber.abort("Argument must be an OddNumber.")
return Number.count(x.half) * 2 + 1
}
 
// Constructs a new OddNumber object : 2 * half + 1.
construct new(half) {
if (half.type != Number) Fiber.abort("Argument must be a Number.")
_half = half
}
 
// gets 'half' field
half { _half }
 
// Add another OddNumber. Note that it returns an EvenNumber.
+(other) {
if (other.type != OddNumber) Fiber.abort("Argument must be an OddNumber.")
var z = this.half + other.half
return EvenNumber.new(Number.add1(z))
}
}
 
// Tests if even number addition is commutative for given numbers.
var testCommutative = Fn.new { |e1, e2|
if (e1.type != EvenNumber || e2.type != EvenNumber) Fiber.abort("Arguments must be EvenNumbers.")
var c1 = EvenNumber.count(e1)
var c2 = EvenNumber.count(e2)
var passed = EvenNumber.count(e1 + e2) == EvenNumber.count(e2 + e1)
var symbol = passed ? "==" : "!="
Fmt.print("\n$d + $d $s $d + $d", c1, c2, symbol, c2, c1)
}
 
// Tests if even number arithmetic is associative for given numbers.
var testAssociative = Fn.new { |e1, e2, e3|
if (e1.type != EvenNumber || e2.type != EvenNumber || e3.type != EvenNumber) {
Fiber.abort("Arguments must be EvenNumbers.")
}
var c1 = EvenNumber.count(e1)
var c2 = EvenNumber.count(e2)
var c3 = EvenNumber.count(e3)
var passed = EvenNumber.count((e1 + e2) + e3) == EvenNumber.count(e1 + (e2 + e3))
var symbol = passed ? "==" : "!="
Fmt.lprint("\n($d + $d) + $d $s $d + ($d + $d)", [c1, c2, c3, symbol, c1, c2, c3])
}
 
var numbers = List.filled(10, null)
System.print("The first 10 natural numbers are:")
for (i in 0..9) {
numbers[i] = Number.gen(i)
Fmt.write("$d ", Number.count(numbers[i]))
}
 
System.print("\n\nThe first 10 even natural numbers are:")
for (i in 0..9) {
var e = EvenNumber.new(numbers[i])
Fmt.write("$d ", EvenNumber.count(e))
}
 
System.print("\n\nThe first 10 odd natural numbers are:")
for (i in 0..9) {
var o = OddNumber.new(numbers[i])
Fmt.write("$d ", OddNumber.count(o))
}
 
System.write("\n\nThe sum of the first 10 natural numbers is: ")
var sum = numbers[0]
for (i in 1..9) {
sum = sum + numbers[i]
}
System.print(Number.count(sum))
 
System.write("\nThe sum of the first 10 even natural numbers (increasing order) is: ")
var sumEven = EvenNumber.new(numbers[0])
for (i in 1..9) {
sumEven = sumEven + EvenNumber.new(numbers[i])
}
System.print(EvenNumber.count(sumEven))
 
System.write("\nThe sum of the first 10 even natural numbers (decreasing order) is: ")
sumEven = EvenNumber.new(numbers[9])
for (i in 8..0) {
sumEven = sumEven + EvenNumber.new(numbers[i])
}
System.print(EvenNumber.count(sumEven))
 
testCommutative.call(EvenNumber.new(numbers[8]), EvenNumber.new(numbers[9]))
testAssociative.call(EvenNumber.new(numbers[7]), EvenNumber.new(numbers[8]), EvenNumber.new(numbers[9]))</lang>
 
{{out}}
<pre>
The first 10 natural numbers are:
0 1 2 3 4 5 6 7 8 9
 
The first 10 even natural numbers are:
0 2 4 6 8 10 12 14 16 18
 
The first 10 odd natural numbers are:
1 3 5 7 9 11 13 15 17 19
 
The sum of the first 10 natural numbers is: 45
 
The sum of the first 10 even natural numbers (increasing order) is: 90
 
The sum of the first 10 even natural numbers (decreasing order) is: 90
 
16 + 18 == 18 + 16
 
(14 + 16) + 18 == 14 + (16 + 18)
</pre>
 
{{omit from|ALGOL 68}} <!-- might be possible, but would require a complex library like Maple, not sure -->
9,476

edits