There is a tool called FindBugs it can detect infinite never ending loops in a given program/ code base.
This implies FindBugs can detect if a program will end or not by analyzing the code.
Halting problem is the problem defining that:
Given a description of an arbitrary computer program, decide whether
the program finishes running or continues to run forever
So does this imply that the halting problem is solved or a subset of the halting problem is solved?
No, it's not solved. Findbugs only finds some of the cases of infinite never ending loops, such as this one:
public void myMethod() {
int a = 0;
while (true) {
a++;
}
}
IIRC, the only false negative it suffers from is, if the above method myMethod is never called, in which case you 'll still want to delete it as it's dead code.
It does suffers from false positives: there are many cases of non-ending programs that findbugs will not detect.
Imagine that you have a tool that always detects infinite loops.
Suppose there exists a unievrsal machine HALT(CODE, INPUT) that halts iff CODE halts on INPUT. Now consider this:
if HALT(CODE, CODE), loop forever
else halt
If CODE halts on CODE, you'll get a contradiction, and also if it doesn't. Why?
Assuming CODE halts on CODE, then the program will loop forever.. meaning that... it doesn't stop..Now assume that CODE doesn't halt on CODE, you'll get that.... it does stop..
If you were to make a program to analyze a program for the same platform with the same limits as the analyzing programs it's impossible for such analyzer to exist. This is known as the halting problem.
When that said, halting problem is solvable for programs that has a lot less memory consumption and code length than the analyzing program can have. Eg. I can make a halt? procedure for all 2 byte BrainFuck-programs like this:
;; takes a valid 2 byte BF-program
;; and returns if it will halt
(define (halt? x)
(cond ((equal? x "[]") #f)
(else #t)))
A larger example is by making an interpreter and hash memory states and pc-location. If a previous state is found it's an infinite loop. Even with a very good data model the memory used by the interpreter must be considerable larger than what it interprets.
I'm thinking of constant folding programs by doing and the halting problem becomes an issue. My idea is to have a data structure that has the number of times a particular branch in AST has been seen and have a cutoff limit that is very large. Thus if the interpreter has been at a branch more than the cutoff it will end up in the compiled program instead of it's computation. It takes a lot less memory and will establish that some or all parts of a program certainly does return (halt).
Imagine this code:
(define (make-list n f)
(if (zero? n)
'()
(cons (f) (make-list (- n 1) f))))
(define (a)
(b))
(define (b)
(c))
(define (c)
(b))
(display (make-list 4 read))
(display (make-list 4 a))
It's actually pretty bad code since you don't know which order the input might get. The compiler get to choose whats best and it might turn into:
(display-const "(")
(display (read))
(display-const " ")
(display (read))
(display-const " ")
(display (read))
(display-const " ")
(display (read))
(display-const ")")
(display (cons (b) (cons (b) (cons (b) (cons (b) '())))) ; gave up on (b)
Related
Can any case of using call/cc be rewritten equivalently without using it?
For example
In (g (call/cc f)), is the purpose of f to evaluate the value of
some expression, so that g can be applied to the value?
Is (g (call/cc f)) always able to be rewritten equivalently
without call/cc e.g. (g expression)?
In ((call/cc f) arg), is the purpose of f to evaluate the
definition of some function g, so that function g can be
applied to the value of arg?
Is ((call/cc f) arg) always able to be rewritten equivalently
without call/cc e.g. (g arg)?
If the answers are yes, why do we need to use call/cc?
I am trying to understand the purpose of using call/cc, by contrasting it to not using it.
The key to the direct answer here is the notion of "Turing equivalence". That is, essentially all of the commonly used programming languages (C, Java, Scheme, Haskell, Lambda Calculus etc. etc.) are equivalent in the sense that for any program in one of these languages, there is a corresponding program in each of the other languages which has the same meaning.
Beyond this, though, some of these equivalences may be "nice" and some may be really horrible. This suggests that we reframe the question: which features can be rewritten in a "nice" way into languages without that feature, and which cannot?
A formal treatment of this comes from Matthias Felleisen, in his 1991 paper "On the Expressive Power of Programming Languages" (https://www.sciencedirect.com/science/article/pii/016764239190036W), which introduces a notion of macro expressibility, pointing out that some features can be rewritten in a local way, and some require global rewrites.
The answer to your original question is obviously yes. Scheme is Turing-complete, with or without call/cc, so even without call/cc, you can still compute anything that is computable.
Why "it is more convenient than writing the equivalent expression using lambda"?
The classic paper On the Expressive Power of Programming Languages by Matthias Felleisen gives one answer to this question. Pretty much, to rewrite a program with call/cc to one without it, you might potentially need to transform your whole program (global transformation). This is to contrast some other constructs that only need a local transformation (i.e., can be written as macro) to remove them.
The key is: If your program is written in continuation passing style, you don't need call/cc. If not, good luck.
I whole-heartedly recommend:
Daniel P. Friedman. "Applications of Continuations: Invited Tutorial". 1988 Principles of Programming Languages (POPL88). January 1988
https://cs.indiana.edu/~dfried/appcont.pdf
If you enjoy reading that paper, then check out:
https://github.com/scheme-live/bibliography/blob/master/page6.md
Of course anything that is written with call/cc can be written without it, because everything in Scheme is ultimately written using lambda. You use call/cc because it is more convenient than writing the equivalent expression using lambda.
There are two senses to this question: an uninteresting one and an interesting one:
The uninteresting one. Is there some computation that you can do with call/cc that you can't do in a language which does not have it?
No, there isn't: call/cc doesn't make a language properly more powerful: it is famously the case that a language with only λ and function application is equivalent to a universal Turing machine, and thus there is no (known...) more powerful computational system.
But that's kind of uninteresting from the point of view of programming-language design: subject to the normal constraints on memory &c, pretty much all programming languages are equivalent to UTMs, but people still prefer to use languages which don't involve punching holes in paper tape if they can.
The interesting one. Is it the case that call/cc makes some desirable features of a programming language easier to express?
The answer to this is yes, it does. I'll just give a couple of examples. Let's say you want to have some kind of non-local exit feature in your language, so some deeply-nested bit of program can just say 'to hell with this I want out', without having to climb back out through some great layer of functions. This is trivial with call/cc: the continuation procedure is the escape procedure. You can wrap it in some syntax if you want it to be nicer:
(define-syntax with-escape
(syntax-rules ()
[(_ (e) form ...)
(call/cc (λ (e) form ...))]))
(with-escape (e)
... code in here, and can call e to escape, and return some values ...)
Can you implement this without call/cc? Well, yes, but not without either relying on some other special construct (say block and return-from in CL), or without turning the language inside out in some way.
And you can build on things like this to implement all sorts of non-local escapes.
Or, well, let's say you want GO TO (the following example is Racket):
(define (test n)
(define m 0)
(define start (call/cc (λ (c) c)))
(printf "here ~A~%" m)
(set! m (+ m 1))
(when (< m n)
(start start)))
Or, with some syntax around this:
(define-syntax-rule (label place)
(define place (call/cc identity)))
(define (go place)
(place place))
(define (horrid n)
(define m 0)
(label start)
(printf "here ~A~%" m)
(set! m (+ m 1))
(when (< m n)
(go start)))
So, OK, this perhaps is not a desirable feature of a programming language. But, well, Scheme doesn't have GO TO right, and yet, here, it does.
So, yes, call/cc (especially when combined with macros) makes a lot of desirable features of a programming language possible to express. Other languages have all these special-purpose, limited hacks, Scheme has this universal thing from which all these special-purpose hacks can be built.
The problem is that call/cc doesn't stop with the good special-purpose hacks: you can also build all the awful horrors that used to blight programming languages out of it. call/cc is like having access to an elder god: it's really convenient if you want dread power, but you'd better be careful what comes with it when you call, because it may well be an unspeakable horror from beyond spacetime.
An easy use of call/cc is as a bail out. eg.
;; (1 2) => (2 4)
;; #f if one element is not a number
(define (double-numbers lst)
(call/cc
(lambda (exit)
(let helper ((lst lst))
(cond ((null? lst) '())
((not (number? (car lst))) (exit #f))
(else (cons (* 2 (car lst)) (helper (cdr lst)))))))))
So to understand this. If we are doing (double-numbers '(1 2 r)) the result is #f, but the helper has done (cons 1 (cons 2 (exit #f)))
Without call/cc we see the continuation would be whatever called double-numbers since it actually return normally from it. Here is an example without call/cc:
;; (1 2) => (2 4)
;; #f if one element is not a number
(define (double-numbers lst)
(define (helper& lst cont)
(cond ((null? lst) (cont '()))
((not (number? (car lst))) #f) ; bail out, not using cont
(else (helper& (cdr lst)
(lambda (result)
(cont (cons (* 2 (car lst)) result)))))))
(helper& lst values)) ; values works as an identity procedure
I imagine it gets harder pretty quick. Eg. my generator implementation. The generator relies on having access to continuations to mix the generator code with where it's used, but without call/cc you'll need to do CPS in both the generator, the generated generator and the code that uses it.
I am a newbie in scheme, and I am in the process of writing a function that checks pairwise disjointess of rules (for the time being is incomplete), I used symbols and lists in order to represent the rues of the grammar. Uppercase symbol is a non-terminal in the grammar, and lowercase is a terminal. I am trying to check if a rule passes the pairwise disjointness test.
I will basically check if a rule has only one unique terminal in it. if it is the case, that rule passes the pairwise disjointness test. In scheme, I am thinking to realize that by representing the terminal symbol in lower case. An example of that rule would be:
'(A <= (a b c))
I will then check the case of a rule that contains an or. like:
'(A <= (a (OR (a b) (a c))))
Finally, I will check recursively for non terminals. A rule for that case would be
'(A <= (B b c))
However, What is keeping me stuck is how to use those symbols as data in order to be processed and recurse upon it. I thought about converting the symbols to strings, but that did not in case of having a list like that for example '(a b c) How can I do it?
Here is what I reached so far:
#lang racket
(define grammar
'(A <= (a A b))
)
(define (pairwise-disjoint lst)
(print(symbol->string (car lst)))
(print( cddr lst))
)
Pairwise Disjoint
As far as I know, the only way to check if a set is pairwise disjoint is to enumerate every possible pair and check for matches. Note that this does not follow the racket syntax, but the meaning should still be pretty clear.
(define (contains-match? x lst)
(cond ((null? x) #f) ; Nothing to do
((null? lst) #f) ; Finished walking full list
((eq? x (car lst)) #t) ; Found a match, no need to go further
(else
(contains-match? x (cdr lst))))) ; recursive call to keep walking
(define (pairwise-disjoint? lst)
(if (null? lst) #f
(let ((x (car lst)) ; let inner vars just for readability
(tail (cdr lst)))
(not
;; for each element, check against all later elements in the list
(or (contains-match? x tail)
(contains-match? (car tail) (cdr tail)))))))
It's not clear to me what else you're trying to do, but this is the going to be the general method. Depending on your data, you may need to use a different (or even custom-made) check for equality, but this works as is for normal symbols:
]=> (pairwise-disjoint? '(a b c d e))
;Value: #t
]=> (pairwise-disjoint? '(a b c d e a))
;Value: #f
Symbols & Data
This section is based on what I perceive to be a pretty fundamental misunderstanding of scheme basics by OP, and some speculation about what their actual goal is. Please clarify the question if this next bit doesn't help you!
However, What is keeping me stuck is how to use those symbols as data...
In scheme, you can associate a symbol with whatever you want. In fact, the define keyword really just tells the interpreter "Whenever I say contains-match? (which is a symbol) I'm actually referring to this big set of instructions over there, so remember that." The interpreter remembers this by storing the symbol and the thing it refers to in a big table so that it can be found later.
Whenever the interpreter runs into a symbol, it will look in its table to see if it knows what it actually means and substitute the real value, in this case a function.
]=> pairwise-disjoint?
;Value 2: #[compound-procedure 2 pairwise-disjoint?]
We tell the interpreter to keep the symbol in place rather than substituting by using the quote operator, ' or (quote ...):
]=> 'pairwise-disjoint?
;Value: pairwise-disjoint?
All that said, using define for your purposes is probably a really poor decision for all of the same reasons that global variables are generally bad.
To hold the definitions of all your particular symbols important to the grammar, you're probably looking for something like a hash table where each symbol you know about is a key and its particulars are the associated value.
And, if you want to pass around symbols, you really need to understand the quote and quasiquote.
Once you have your definitions somewhere that you can find them, the only work that's left to you is writing something like I did above that is maybe a little more tailored to your particular situation.
Data Types
If you have Terminals and Non-Terminals, why not make data-types for each? In #lang racket the way to introduce new data type is with struct.
;; A Terminal is just has a name.
(struct Terminal (name))
;; A Non-terminal has a name and a list of terms
;; The list of terms may contain Terminals, Non-Terminals, or both.
(struct Non-terminal (name terms))
Processing Non-terminals
Now we can find the Terminals in a Non-Terminal's list of terms using the predicate Terminal? which is provided automatically when we define the Terminal as a struct.
(define (find-terminals non-terminal)
(filter Terminal? (Non-terminal-terms non-terminal)))
Pairwise Disjoint Terminals
Once we have filtered the list of terms we can determine properties:
;; List(Terminal) -> Boolean
define (pairwise-disjoint? terminals)
(define (roundtrip terms)
(set->list (list->set terms)))
(= (length (roundtrip terminals)
(length terminals))))
The round trip list->set->list isn't necessarily optimized for speed, of course and profiling actual working implementations may justify refactoring, but at least it's been black-boxed.
Notes
Defining data types with struct provides all sorts of options for validating data as the type is instantiated. If you look at the Racket code base, you will see struct used frequently in the more recent portions.
Since grammar has a list within a list, I think you'll have to either test via list? before calling symbol->string (since, as you discovered, symbol->string won't work on a list), or else you could do something like this:
(map symbol->string (flatten grammar))
> '("A" "<=" "a" "A" "b")
Edit: For what you're doing, i guess the flatten route might not be that helpful. so ya, test via list? each time when parsing and handle accordingly.
I was working on the solution of the exercise 1.6 of the SICP book when I saw two different behaviors when I run the code depending on the numbers that I used.
If I use natural numbers when I call the sqrt-iter procedure the interpreter just never stop but when I force the decimal division using float-point numbers the interpreter responds: Aborting!: maximum recursion depth exceeded.
Does anyone know the reason for the different behavior?
I made a gist with my answer to help anyone that wants to run the code, just copy & paste: http://bit.ly/Qv1wru. The mit-scheme version is 9.1.1.
Your good-enough? procedure seems wrong, try with this one:
(define (good-enough? guess x)
(< (abs (- (sqr guess) x)) 0.001))
Okay so I have started a new language in class. We are learning Scheme and i'm not sure on how to do it. When I say learning a new language, I mean thrown a homework and told to figure it out. A couple of them have got me stumped.
My first problem is:
Write a Scheme function that returns true (the Boolean constant #t) ifthe parameter is a list containing n a's followed by n b's. and false otherwise.
Here's what I have right now:
(define aequalb
(lambda (list)
(let ((head (car list)) (tail (cdr list)))
(if (= 'a head)
((let ((count (count + 1)))
(let ((newTail (aequalb tail))))
#f
(if (= 'b head)
((let ((count (count - 1)))
(let ((newTail (aequalb tail))))
#f
(if (null? tail)
(if (= count 0)
#t
#f)))))))))))
I know this is completely wrong, but I've been trying so please take it easy on me. Any help would be much appreciated.
A trick I picked up from Essentials of Programming Languages is to always write recursive list functions by handling the two important cases first: null (end of list) and not null.
So, the basic structure of a list function looks something like this:
(define some-list-function
(lambda (list)
(if (null? list)
#f
(do-some-work-here (head list)
(some-list-function (tail list))))))
Usually you (1) check for null (2) do some work on the head and (3) recur on the tail.
The first thing you need to do is decide what the answer is for a null list. It's either #t or #f, but which? Does a null list have the same number of a as b?
Next, you need to do something about the recursive case. Your basic approach is pretty good (although your example code is wrong): keep a count that goes up when you see a and down when you see b. The problem is how to keep track of the count. Scheme doesn't have loops* so you have to do everything with recursion. That means you'll need to pass along an extra counter variable.
(define some-list-function
(lambda (list counter)
(if (null? list)
; skip null's code for a second
Now you have to decide whether the head is 'a or not and increment count if so (decrement otherwise). But there's no count variable, just passing between functions. So how to do it?
Well, you have to update it in-line, like so:
(some-list-function (tail list) (+ 1 count))
By the way, don't use = for anything but numbers. The newer, cooler Lisps allow it, but Scheme requires you to use eq? for symbols and = for numbers. So for your 'a vs 'b test, you'll need
(if (eq? 'a (head tail)) ...)
; not
(if (= 'a (head tail)) ...)
I hope this helps. I think I gave you all the pieces, although there are a few things I skipped over. You need to change the null case now to check count. If it's not = 0 at the end, the answer is false.
You should also maintain a separate flag variable to make sure that once you switched to 'b, you return #f if you see another 'a. That way a list like '(a a a b b a b b) won't pass by mistake. Add the flag the same way I added counter above, by adding another function parameter and passing along the value at each recursive call.
Finally, if your teacher really isn't giving you any help, and won't, then you might want to read a basic book on Scheme. I haven't used any of these myself, but I've heard they're good: The Scheme Programming Language, How to Design Programs or err umm I thought there was a third book online for free, but I can't find it now. I guess if you have lots of extra time and want to blow your mind, you can read Structure and Interpretation of Computer Programs. It teaches a little Scheme and lot about programming languages.
*It does have some of these things, but it's better to ignore them for now.
Isn't list a keyword? I always used to use "alist" as my variable name to get around it.
You could use counters like you are, but I might go for a recursive function that has the following conditions:
params: alist
returns true if the list is nil,
false if the first element is not a,
false if the last element is not b,
(aequalb (reverse (cdr (reverse (cdr alist))))) ;; pick off the front and back, and recurse
in this case, you may need to write a reverse function... can't remember if it was there already.
Also, from a syntax perspective, you don't need to introduce a lambda expression...
(define (foo arg) (+ 1 arg))
is a function called foo, takes a number, and adds one to it. You would call it (foo 1)
I'd take a look at andmap, take and drop, which (between them) make this pretty trivial. Oh and at least for now, I'd probably try to forget that let even exists. Not that there's anything particularly wrong with it, but I'd guess most of the problems you're going to get (at least for a while) don't/won't require it.
Here's a first-cut that may help you. It handles the basic problem, although you need to test to make sure there are no edge cases.
Anyway, the function checks several conditions:
It first checks a base case (recursive functions need to have this, to avoid the possibility of infinite recursion). If the input list is empty then return true (assumption is that all items have been removed, so at this point we are done).
Then the code checks to see if the first items is an a and the last is a b. If so, it strips these chars off and recurses.
Otherwise something is wrong, so the function returns false
(define (aeqb items)
(cond
((equal? '() items) #t)
((and (equal? "a" (car items))
(equal? "b" (car (reverse items))))
(aeqb (cdr (reverse (cdr (reverse items))))))
(else #f)))
(aeqb '("a" "a" "b" "b"))
I'm trying to find out how I can do an "early return" in a scheme procedure without using a top-level if or cond like construct.
(define (win b)
(let* ((test (first (first b)))
(result (every (lambda (i) (= (list-ref (list-ref b i) i) test))
(enumerate (length b)))))
(when (and (not (= test 0)) result) test))
0)
For example, in the code above, I want win to return test if the when condition is met, otherwise return 0. However, what happens is that the procedure will always return 0, regardless of the result of the when condition.
The reason I am structuring my code this way is because in this procedure I need to do numerous complex checks (multiple blocks similar to the let* in the example) and putting everything in a big cond would be very unwieldy.
Here is how to use call/cc to build return yourself.
(define (example x)
(call/cc (lambda (return)
(when (< x 0) (return #f))
; more code, including possible more calls to return
0)))
Some Schemes define a macro called let/cc that lets you drop some of the noise of the lambda:
(define (example x)
(let/cc return
(when (< x 0) (return #f))
0))
Of course if your Scheme doesn't, let/cc is trivial to write.
This works because call/cc saves the point at which it was called as a continuation. It passes that continuation to its function argument. When the function calls that continuation, Scheme abandons whatever call stack it had built up so far and continues from the end of the call/cc call. Of course if the function never calls the continuation, then it just returns normally.
Continuations don't get truly mind-bending until you start returning them from that function, or maybe storing them in a global data structure and calling them later. Otherwise, they're just like any other language's structured-goto statements (while/for/break/return/continue/exceptions/conditions).
I don't know what your complete code looks like, but it might be better to go with the cond and to factor out the complex checks into separate functions. Needing return and let* is usually a symptom of overly imperative code. However, the call/cc method should get your code working for now.
One way would be to use recursion instead of looping, then an early exit is achieved by not recursing further.
You can use the "call with current continuation" support to simulate a return. There's an example on wikipedia. The function is called call-with-current-continuation, although there's often an alias called call/cc which is exactly the same thing. There's also a slightly cleaner example here
Note: This is quite an advanced Scheme programming technique and can be a bit mind bending at first...!!!!
In this case you don't want a when, you want an if, albeit not top-level.
(define (win b)
(let* ((test (first (first b)))
(result (every (lambda (i) (= (list-ref (list-ref b i) i) test))
(enumerate (length b)))))
(if (and (not (= test 0)) result)
test
0)))
The reason it was always returning zero is that whether or not the body of the when got executed, its result would be dropped on the floor. You see, the lambda implicit in the function define form creates an implicit begin block too, so
(define foo
(lambda (b)
(begin
(let ...)
0)))
and the way begin works is that it returns the result of the last form inside, while dropping all the intermediate results on the floor. Those intermediate results are intended to have side effects. You're not using any of that, which is great(!), but you have to be careful to only have one form (whose result you really want) inside the function definition.
Grem