Feed aggregator

Racket v5.0.1

comp.lang.scheme - Mon, 08/16/2010 - 07:00
Racket version 5.0.1 is now available from
[link]
* Datalog is a lightweight deductive database system with Racket
integration. It is now available in the `datalog' collection and
with `#lang datalog'.
* Racklog provides Prolog-style logic programming in Racket, adapted
from Dorai Sitaram's Schelog package. It is available in the

LV,coach,chanel boots wholesale <free shipping paypal payment>( http://www.cntrade09.com/ )

comp.lang.scheme - Sun, 08/15/2010 - 13:00
LV,coach,chanel boots wholesale <free shipping paypal payment>(
[link] )
air force ones <free shipping paypal payment>(http:// [link])
nike trading <free shipping paypal payment>( [link]
)
nike shox <free shipping paypal payment>( [link] )

Hot Sexy Star Nayanatara Sex Videos In All Angles

comp.lang.scheme - Sun, 08/15/2010 - 07:00
Hot Sexy Star Nayanatara Sex Videos In All Angles At [link]
i have hidden the videos in an image. in that website on
Top Side search box Above click on image and watch
videos in all angles. please don,t tell to anyone.

Doug Williams: Simple Simulation in Racket

Planet Scheme - Sat, 08/14/2010 - 21:13
I updated the simple simulation example from the simulation collection to Racket. The simple simulation example shows how a basic discrete-event simulation engine can be written in pure Racket (specifically, the racket/base language). Fully commented it is only about two and a half pages of code and does not contain any references to external packages. If you're curious about the usage of continuations, this might be a good example to look at. [If you're an expert in continuations, any critique would be welcome - particularly on the event loop in the start-simulation procedure.]

The code uses parameters for its global variables, which may be unfamiliar to some people. For example, the simulation clock is maintained by the current-time parameter. This parameter is created by (make-parameter current-time 0.0). A call to (current-time) will return its current value. The call (current-time (event-time (current-event))) in start-simulation sets its value to the time of the next event. Finally, the parameterize call in run-simulation creates new instances of the parameters and (I think) is cleaner than just resetting their values.

And, here is the actual code.


#lang racket/base
;;; Simplified Simulation System

;;; Global simulation control variables

;;; future-event-list : (parameter/c (list? event?))
;;; current-time : (parameter/c real?)
;;; current-event : (parameter/c (or/c false/c event?))
;;; event-loop-exit : (parameter/c (or/c false/c continuation?))
;;; event-loop-next : (parameter/c (or/c false/c continuation?))
(define future-event-list (make-parameter '()))
(define current-time (make-parameter 0.0))
(define current-event (make-parameter #f))
(define event-loop-exit (make-parameter #f))
(define event-loop-next (make-parameter #f))

;;; Event definition and scheduling

;;; (struct event (time function arguments))
;;; time : (>=/c 0.0)
;;; function : (or/c false/c procedure?)
;;; arguments : list?
;;; Each event has a time the event is to be executed, the function to
;;; be executed, and the (evaluated) arguments to the function.
(struct event (time function arguments))

;;; (schedule event) -> any
;;; event : event?
;;; Add an event to the event list.
(define (schedule event)
(future-event-list (event-schedule event (future-event-list))))

;;; (event-schedule event event-list) -> (list-of event?)
;;; event : event?
;;; event-list : (list-of event?)
;;; Return a new list of events corresponding to the given event added
;;; to the given list of events.
(define (event-schedule event event-list)
(cond ((null? event-list)
(list event))
((< (event-time event)
(event-time (car event-list)))
(cons event event-list))
(else
(cons (car event-list)
(event-schedule event (cdr event-list))))))
;;; Simulation control routines

;;; (wait/work delay) -> any
;;; delay : (>=/c 0.0)
;;; Simulate the delay while work is being done. Add an event to
;;; execute the current continuation to the event list.
(define (wait/work delay)
(let/cc continue
;; Add an event to execute the current continuation
(schedule (event (+ (current-time) delay) continue '()))
;; Return to the main loop
((event-loop-next))))

;;; (start-simulation) -> any
;;; This is the main simulation loop. As long as there are events to
;;; be executed (or until the simulation is explicitly stopped), remove
;;; the next event from the event list, advance the clock to the time
;;; of the event, and apply the event's functions to its arguments.
(define (start-simulation)
(let/ec exit
;; Save the event loop exit continuation
(event-loop-exit exit)
;; Event loop
(let loop ()
;; Exit if no more events
(when (null? (future-event-list))
((event-loop-exit)))
(let/cc next
;; Save the event loop next continuation
(event-loop-next next)
;; Execute the next event
(current-event (car (future-event-list)))
(future-event-list (cdr (future-event-list)))
(current-time (event-time (current-event)))
(apply (event-function (current-event))
(event-arguments (current-event))))
(loop))))

;;; (stop-simulation) -> any
;;; Stop the execution of the current simulation (by jumping to its
;;; exit continuation).
(define (stop-simulation)
((event-loop-exit)))

;;; Random Distributions (to remove external dependencies)

;;; (random-flat a b) -> inexact-real?
;;; a : real?
;;; b : real?
;;; Returns a random real number from a uniform distribution between a
;;; and b.
(define (random-flat a b)
(+ a (* (random) (- b a))))

;;; (random-exponential mu) -> inexact-real?
;;; mu : real?
;;; Returns a random real number from an exponential distribution with
;;; mean mu.
(define (random-exponential mu)
(* (- mu) (log (random))))

;;; Example Simulation Model

;;; (generator n) -> any
;;; n : exact-positive-integer?
;;; Process to generate n customers arriving into the system.
(define (generator n)
(do ((i 0 (+ i 1)))
((= i n) (void))
(wait/work (random-exponential 4.0))
(schedule (event (current-time) customer (list i)))))

;;; (customer i) -> any
;;; i : exact-nonnegative-integer?
;;; The ith customer into the system. The customer is in the system
;;; 2 to 10 minutes and then leaves.
(define (customer i)
(printf "~a: customer ~a enters~n" (current-time) i)
(wait/work (random-flat 2.0 10.0))
(printf "~a: customer ~a leaves~n" (current-time) i))

;;; (run-simulation n) -> any
;;; n : exact-positive-integer?
;;; Run the simulation for n customers (or until explicitly stopped at
;;; some specified time).
(define (run-simulation n)
;; Create new global values
(parameterize ((future-event-list '())
(current-time 0.0)
(current-event #f)
(event-loop-exit #f)
(event-loop-next #f))
;; Schedule the customer generator
(schedule (event 0.0 generator (list n)))
;; Stop the simulation at the specified time (optional)
;(schedule (event 50.0 stop-simulation '()))
;; Start the simulation main loop
(start-simulation)))

;;; Run the simulation for 10 customers.
(run-simulation 10)


An example of the output looks like:


2.3985738870908615: customer 0 enters
5.395876334125138: customer 1 enters
7.716207787604494: customer 2 enters
8.062394508850671: customer 1 leaves
9.204092461998275: customer 0 leaves
14.431739507072376: customer 3 enters
15.15611565215575: customer 2 leaves
19.107487138771972: customer 4 enters
19.67563344212178: customer 3 leaves
26.51109574171283: customer 5 enters
27.060305975366514: customer 4 leaves
31.04777263526701: customer 6 enters
32.83444054122948: customer 5 leaves
36.31758748274069: customer 7 enters
39.27687483880874: customer 6 leaves
40.643350655011744: customer 8 enters
41.76876758081738: customer 7 leaves
42.82235216823591: customer 8 leaves
47.63479457664656: customer 9 enters
57.31661407095231: customer 9 leaves


Your output will vary slightly because of the random numbers. That is, this is a stochastic model.

Doug Williams: Status Update

Planet Scheme - Sat, 08/14/2010 - 20:23
I haven't posted for a while, so I just wanted to provide an update on the status and (hopeful) direction of my various PLaneT packages. This post will cover the science, simulation, and inference collections, which work together to provide a knowledge-based simulation capability.

We at SET Corporation are using the science, simulation, and inference collections as part of our Multi-Agent, Dynamic NEtwork Simulation System (MADNESS). The inference collection is also used in our COntent GENeration from Templates (COGENT) system. These are used on a daily basis in our agent-based simulation work.

Science Collection

The current release of the science collection is version 3.10. I only expect to do bug fixes to the version 3 code. The next release should be version 4.0. For version 4.0 I plan to convert the code to Typed Racket, which has gotten to the point that typed code generally runs as fast or faster than my hand-optimized numeric code.

The only major new functionality planned for version 4.0 are fast Fourier transforms. This code is already written and ready for release, but the documentation has not been updated. Vincent St-Amour at Northeastern University converted the FFT code to Typed Racket to test the optimized code generation for numeric processing. The results were extremely impressive and I need to make a separate post on this.

Simulation Collection

The current version of the simulation collection is version 3.4. I only expect to do bug fixes to the version 3 code. At some point I will release a version 4.0, which may (or may not) be in Typed Racket. The decision to use Typed Racket will be based on my experience in converting the science collection. I will also rewrite the simulation language using syntax-parse to provide better syntax error handling.

Inference Collection

The current version of the inference collection is version 2.7. There was a flurry of releases earlier this year as we really began to use the inference collection in MADNESS and COGENT. Unfortunately, the documentation has not yet caught up with the code changes.

I made earlier posts on the upcoming version 3 rewrite. As with the simulation collection, this may (or may not) be in Typed Scheme. I will definitely use syntax-parse to implement a rule compiler for the rule language.

A portable LISP interpreter that includes all the major list-processing functions is described. A complete, annotated listing of the program's code, written in PASCAL, is included.

comp.lang.scheme - Sat, 08/14/2010 - 06:00
Title Portable LISP interpreter
Creator/Author Cox, L.A. Jr. ; Taylor, W.P.
Publication Date 1978 May 31
OSTI Identifier OSTI ID: 7017786
Report Number(s) UCRL-52417
DOE Contract Number W-7405-ENG-48
Resource Type Technical Report
Research Org California Univ., Livermore (USA). Lawrence Livermore

Joe Marshall: P ≠ NP (part 1)

Planet Scheme - Fri, 08/13/2010 - 22:22
I'm sure most people who read this blog know a bit about what this means, but I want to try to explain it in a way my mom could understand. I won't go into excruciating detail, and I'll probably gloss over interesting points.

Let's start with an analogy. Suppose you go to the store to buy a present for your nephew. He likes jigsaw puzzles, so you want to get him one. He's going to be twelve years old, so you need to find one that has the appropriate challenge. A simple one with four pieces might be great for a two year-old, but your nephew would find that boring. A big one with ten thousand pieces is probably too much for him. You know he just finished one with five hundred pieces, so you pick one with six hundred pieces because it won't be too easy, but not too frustrating. What you are doing is estimating the complexity of the puzzle.

When you get to the store you find that they are sold out of jigsaw puzzles. They have a variety of other puzzles, though. They have a Rubik's cube, a Sudoku book, some cryptograms, a Tower of Hanoi, etc. They have models you can put together as well. But these things aren't jigsaw puzzles. You can't estimate the complexity the same way. A model with five hundred pieces would be quite a bit more difficult to assemble than a jigsaw puzzle with the same number of pieces.

Perhaps you look at the age ratings for the various puzzles. The eight-piece Tower of Hanoi puzzle is rated for ages ten and up, so maybe a twelve piece? The standard 3x3x3 Rubik's cube is rated for ages eight and up, but would the 4x4x4 be too hard or too easy? What about the 5x5x5?

The kind of rating system you use to describe the difficulty of a puzzle is analogous to the “complexity class” of a problem. The complexity class roughly describes how hard a problem will be to solve, and more importantly, how much harder ‘big’ problems are compared to the ‘small’ ones. Here's what I mean: if I take a jigsaw puzzle, any jigsaw puzzle, and double the number of pieces in it, I'll make it roughly twice as hard (more or less). If I take a cryptogram and double the number of words in it, I'll actually make it a lot easier. If I take the Tower of Hanoi and double the number of discs, I'll make it incredibly harder, maybe even impossible. These puzzles are in different complexity classes.

As it turns out, a lot of puzzles are in the same complexity class as the jigsaw puzzle: the difficulty is reasonably proportional to the number of pieces. Adding a piece or two doesn't change things that much, and it is easy to figure out how long it will take to solve if you've done a few of them. A lot of puzzles are more like the Tower of Hanoi. Adding a single piece will double the amount of time it takes to solve them.

P and NP are complexity classes for problems you might want to solve on a computer. There are all sorts of rating systems, but everyone is familiar with the MPAA movie ratings. There are all sorts of complexity classes, but most computer scientists are familiar with P and NP.

I'll pause here because the analogy is wearing thin. The main point is that “P ≠ NP” is a statement about complexity classes. In particular, it talks about two of the most popular complexity classes and that is part of the reason it is interesting.

Programming Praxis: E

Planet Scheme - Fri, 08/13/2010 - 10:00

This puzzle made the rounds of the programmer mathematician blogs a while ago:

Given a random number generator that returns a real number between zero and one, how many random numbers must be selected, on average, to make their accumulated total greater than one?

Your task is to write a program that answers the question above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.


Joe Marshall: Rambling

Planet Scheme - Thu, 08/12/2010 - 18:00
Writing a blog is hard. I need practice so I'm going to ramble a bit.

First, I'm very pleased that Blogger has improved their comment spam detection. Every time I made a post I'd have to come back a day or two later and remove a bunch of pointless comment spam.

Second, I told my daughter that someone claims to have a proof that P ≠ NP. She replied “Well, now we know that N doesn't equal 1.”

I read through the proof and I confess that I don't get it. On the other hand, I think I want to get it, so I'll have to learn some interesting things.

Here's another thing I don't get.`` E8 is any of several closely related exceptional simple Lie groups and Lie algebras of dimension 248''

``a simple Lie group is a connected non-abelian Lie group G which does not have nontrivial connected normal subgroups.''

``a Lie group is a group which is also a differentiable manifold, with the property that the group operations are compatible with the smooth structure.''

``a non-abelian group is a group (G, * ) in which there are at least two elements a and b of G such that a * b ≠ b * a.''

``a connected space is a topological space which cannot be represented as the union of two or more disjoint nonempty open subsets''

I GOT $2000 FROM PAYPAL .

comp.lang.scheme - Wed, 08/11/2010 - 05:00
I GOT $2000 FROM PAYPAL At [link]
I Have hidden the PayPal Form link in an image.
in that website On Top Side Above search box , click on image
and enter your PayPal id And Your name. please don,t tell to any
One.

S9fES SOS

comp.lang.scheme - Wed, 08/11/2010 - 05:00
Scheme9 now has a (optional, slow, inefficient) object system.
Inspired by CLOS, but tinier than TinyCLOS. Completely written
in Scheme. With multi-method dispatch, multiple inheritance,
generics, built-ins, and a half-baked MOP.
Usual location.

Programming Praxis: Literate Programming

Planet Scheme - Tue, 08/10/2010 - 10:00

Literate programming is a style of programming invented by Donald Knuth that merges documentation and code in a single document, with code presented in an order that is conducive to the reader. Chunks of code can be written in any order; a program called tangle restructures the chunks into the order required by the compiler. Here is a short but complete example of a literate program, which you may recognize as the second program, after “hello world,” from K&R:

This program prints a fahrenheit/celsius conversion table.

<<*>>=
<< include standard headers >>
<< the main program >>

The only standard header required is stdio.h, which includes the printf function used by the program.

<< include standard headers >>=
#include <stdio.h>

The main program defines some variables, initializes them, then loops through the table printing output lines.

<< the main program >>=
main()
{
    << declare variables >>
    << initialize variables >>
    << loop through the table >>
}

Variables fahr and celsius hold the current temperatures. Variables lower, upper and step control the loop.

<< declare variables >>=
int fahr, celsius;
int lower, upper, step;

The loop control variables are initialized so that the table prints fahrenheit values from 0 to 300 in steps of 20, along with the corresponding celsius values.

<< initialize variables >>=
lower = 0;
upper = 300;
step = 20;

Temperatures are printed by a loop.

<< loop through the table >>=
fahr = lower;
while (fahr <= upper) {
    << calculate celsius and print one line >>
    fahr = fahr + step;
}

The celsius equivalent of a fahrenheit temperature is computed by the traditional formula C = 9/5 * (F-32). The two temperatures are printed separated by a tab character, each pair on a single line.

<< calculate celsius and print one line >>=
celsius = 5 * (fahr-32) / 9;
printf("%d\t%d\n", fahr, celsius);

This is a simple-minded literate programming system, and the form of the input file is correspondingly simple. Code chunks are introduced by a line beginning with double less-than signs and ending with double greater-than signs and an equals sign; there may be no white space at the beginning or end of the line. Code chunks are referenced on any line within another code chunk by surrounding the name of the chunk, which must exactly match the name given on the definition line, with double less-than and greater-than signs; there may be only one reference per line. A code chunk ends at the first blank line following its beginning, or at the end of the file, whichever comes sooner.

The tangle program collects all the code chunks, then performs depth-first search through the call-tree graph beginning with the top-level “*” chunk. Tangle is careful to preserve the formatting of the original, in case the programmer needs to look at its output. Tangle produces the following output from the example program shown above:

#include
main()
{
    int fahr, celsius;
    int lower, upper, step;
    lower = 0;
    upper = 300;
    step = 20;
    fahr = lower;
    while (fahr <= upper) {
        celsius = 5 * (fahr-32) / 9;
        printf("%d\t%d\n", fahr, celsius);
        fahr = fahr + step;
    }
}

This program is simple-minded for exposition, and doesn’t do justice to the literate programming concept. You’ll see a better example in the solution.

Your task is to write a program that tangles an input file and creates a program output. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.


James Gosling the Creator of EMACS and JAVA - leaves ORACLE - But then reports started coming in of odd failures. Systems would crash strangely. We'd get crashes in applications. All applications. Crashes in the kernel.

comp.lang.scheme - Tue, 08/10/2010 - 06:00
But then reports started coming in of odd failures. Systems would
crash strangely. We'd get crashes in applications. All applications.
Crashes in the kernel.
But then reports started coming in of odd failures. Systems would
crash strangely. We'd get crashes in applications. All applications.
Crashes in the kernel.

Grant Rettke: What is ATGATT?

Planet Scheme - Tue, 08/10/2010 - 01:55

ATGATT stands for “All The Gear All The Time”.

(via advrider)

symbol name display

comp.lang.scheme - Sun, 08/08/2010 - 05:00
Is there a consensus on how to print funny symbol names
in Scheme? I'm wondering about stuff like:
(list 1 (string->symbol (string #\; #\" #\))) 2)
Guile prints it as (1 #{.\\;\\\"}# 2). In CL:
[1]> (list 1 (make-symbol (coerce (list #\; #\" #\)) 'string)) 2)
(1 #:|;")| 2)
Both of these choices strike me as baroque, but

Jens Axel Soegaard: Orange Espresso

Planet Scheme - Fri, 08/06/2010 - 14:31

The blog has always needed colors. Today I finally did something about it.

Thanks to the Flickr user Doozzle and his great shot of espresso (pun intended).

Doozzle: Ok, this is a detail of the foam the espresso shot left on a transparent cup. Taken with a soft light slightly above and behind the cup.

Jens Axel Soegaard: New Scheme blogs?

Planet Scheme - Fri, 08/06/2010 - 14:11
Have you noticed any new (or old) blogs about Scheme, you (and the author)would like to be on Planet Scheme, then leave a comment.

Jens Axel Soegaard: Back in business

Planet Scheme - Fri, 08/06/2010 - 14:09
This blog has been quiet for a while. Besides being swamped in work, the main culprit was Google's change of publication methods. Now the blog content is hosted at Google, but itdid require some DNS magic (a big thank you goes to my brother) to make sure all the old links worked.

paypal payment)(www.cntrade09.com) Air Max Tn 6 Shoes Customize. Produce Burberry Talaria Shoes Training Shoes Trade Outlet Flightposite In stock. . ...

comp.lang.scheme - Fri, 08/06/2010 - 10:00
(paypal payment)([link]) Nike Air Max 90 Sneakers,
Nike Air Max 91
Sneakers.
(paypal payment)([link]) Sneakers Supplier Trainers
Wholesale Shop Catalogs Men's Women's Shoes Customize.
(paypal payment)([link]) Nike Air Max 95 Supplier,
Nike
Air Max 97 Shoes
Supplier.

Programming Praxis: Two Powering Predicates

Planet Scheme - Fri, 08/06/2010 - 10:00

In our study of prime numbers, we have sometimes been lax in specifying the limitations of particular factoring methods; for instance, elliptic curve factorization only works where the number being factored is co-prime to six. Two conditions that arise from time to time are that the number must not be a perfect square and that the number may not be an integer power of a prime number. In today’s exercise we will write predicates to identify such numbers.

The usual test for whether a number is a perfect square is to find the integer square root by Newton’s method and then test if the square of that number is the original number. A better algorithm exploits a theorem of number theory which states that a number is a square if and only if it is a quadratic residue modulo every prime not dividing it. Henri Cohen, in his book A Course in Computational Algebraic Number Theory, describes the algorithm:

The following computations are to be done and stored once and for all.

1. [Fill 11] For k = 0 to 10 set q11[k] ← 0. Then for k = 0 to 5 set q11[k2 mod 11] ← 1.

2. [Fill 63] For k = 0 to 62 set q63[k] ← 0. Then for k = 0 to 31 set q63[k2 mod 63] ← 1.

3. [Fill 64] For k = 0 to 63 set q64[k] ← 0. Then for k = 0 to 31 set q63[k2 mod 64] ← 1.

4. [Fill 65] For k = 0 to 64 set q65[k] ← 0. Then for k = 0 to 32 set q63[k2 mod 65] ← 1.

Then the algorithm is:

Given a positive integer n, this algorithm determines whether n is a square or not, and if it is, outputs the square root of n.

1. [Test 64] Set tn mod 64 (using if possible only an and statement). If q64[t] = 0, n is not a square and terminate the algorithm. Otherwise, set r = n mod 45045.

2. [Test 63] If q63[r mod 63] = 0, n is not a square and terminate the algorithm.

3. [Test 65] If q65[r mod 65] = 0, n is not a square and terminate the algorithm.

4. [Test 11] If q11[r mod 11] = 0, n is not a square and terminate the algorithm.

5. [Compute square root] Compute q ← ⌊ √ n ⌋ using Newton’s method. If nq2, n is not a square and terminate the algorithm. Otherwise, n is a square, output q and terminate the algorithm.

Our second predicate is the prime-power test, which determines, for a given n, if there exist two numbers p and k such that pk = n, with p prime. Stephen Wolfram’s Mathematica program implements the prime-power test as PrimePowerQ, which returns either True or False. According to the manual,

The algorithm for PrimePowerQ involves first computing the least prime factor p of n and then attempting division by n until either 1 is obtained, in which case n is a prime power, or until division is no longer possible, in which case n is not a prime power.

(Note: they probably meant “attempting division by p.”) Wolfram gives the example PrimePowerQ[12167], which is True, since 233 = 12167. That algorithm will take a while, as factoring is a non-trivial problem.

Cohen determines if n is a prime power by first assuming that n = pk, where p is prime. Then Fermat’s Little Theorem gives p | gcd(ana, n). If that fails, n is not a prime power. Here is Cohen’s algorithm:

Given a positive integer n > 1, this algorithm tests whether or not n is of the form pk with p prime, and if it is, outputs the prime p.

1. [Case n even] If n is even, set p ← 2 and go to Step 4. Otherwise, set qn.

2. [Apply Rabin-Miller] By using Algorithm 8.2.2 show that either q is a probable prime or exhibit a witness a to the compositeness of q. If q is a probable prime, set pq and go to Step 4.

3. [Compute GCD] Set d ← (aqa, q). If d = 1 or d = q, then n is not a prime power and terminate the algorithm. Otherwise set qd and go to Step 2.

4. [Final test] (Here p is a divisor of n which is almost certainly prime.) Using a primality test prove that p is prime. If it is not (an exceedingly rare occurrence), set qp and go to Step 2. Otherwise, by dividing n by p repeatedly, check whether n is a power of p or not. If it is not, n is not a prime power, otherwise output p. Terminate the algorithm.

We have been a little sloppy in this algorithm. For example in Step 4, instead of repeatedly dividing by p we could use a binary search analogous to the binary powering algorithm. We leave this as an exercise for the reader.

Cohen’s Algorithm 8.2.2 refers to the search for a witness to the compositeness of a number which we used in the exercise on the Miller-Rabin primality checker.

These two beautiful algorithms show the power and elegance of number theory. Cohen’s book is a fine example of the blend of mathematics and programming, and does an excellent job of explaining algorithms in a way that makes them easy to implement; most math textbooks aren’t so good.

Your task is to implement Cohen’s two powering predicates. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.


Syndicate content