Related
I'm looking at the requirements for automated software verification, i.e. a program that takes in code (ordinary procedural code written in languages like C and Java), generates a bunch of theorems saying that each loop must eventually halt, no assertion will be violated, there will never be a dereference of a null pointer etc., then passes same to a theorem prover to prove they are actually true (or else find a counterexample indicating a bug in the code).
The question is what kind of logic to use. The two major positions seem to be:
First-order logic is just fine.
First-order logic isn't expressive enough, you need higher order logic.
Problem is, there seems to be a lot of support for both positions. So which one is right? If it's the second one, are there any available examples of things you want to do, that verifiers based on first-order logic have trouble with?
You can do everything you need in FOL, but it's a lot of extra work - a LOT! Most existing systems were developed by academics / people with not a lot of time, so they are tempted to take short cuts to save time / effort, and thus are attracted to HOLs, functional languages, etc. However, if you want to build a system that is to be used by hundreds of thousands of people, rather than merely hundreds, we believe that FOL is the way to go because it is far more accessible to a wider audience. There's just no substitute for doing the work; we've been at this for 25 years now! Please take a look at our project (http://www.manmademinions.com)
Regards, Aaron.
In my practical experience, it seems to be "1. First-order logic is just fine". For examples of complete specifications for various functions written entirely in a specification language based on first-order logic, see for instance ACSL by Example or this case study.
First-order logic has automated provers (not proof assistants) that have been refined over the years to handle well properties that come from program verification. Notable automated provers for these uses are for instance Simplify, Z3, and Alt-ergo. If these provers fail and there is no obvious lemma/assertion you can add to help them, you still have the recourse of starting up a proof assistant for the difficult proof obligations. If you use HOL on the other hand, you cannot use Simplify, Z3 or Alt-ergo at all, and while I have heard of automated provers for high-order logic, I have never heard them praised for their efficiency when it comes to properties from programs.
We've found that FOL is fine for most verification conditions, but higher order logic is invaluable for a small number, for example for proving properties about summation of the elements in a collection. So our theorem prover (used in Perfect Developer and Escher C Verifier) is basically first order, but with the ability to do some higher order reasoning as well.
My company has a project running in Prolog and I want to clarify few things about how to go about learning it. I know Prolog is different. It should not be learnt just like any other language.
Having said that, and considering the fact that I did not lay my hands on any Prolog book yet, Is there any book or online resource, where I can learn Prolog the way how we learn C/C++? What I mean is , just to be operational in C/C++, you just need to know the structure of the program, like main { } , loops, conditions, branches, and few functions that you can use to start writing basic programs in C/C++.
Just this way can I learn Prolog and is there any book that just gives me an idea how to Program in Prolog? (basics, loops, how to implement conditions, program structure, what's predicate? how to use it? how to define it? and so on...).
If you're after a single book, I can highly recommend "The Art of Prolog":
Coming to Prolog from something like C/C++ isn't just a matter of learning a programming language. It's a wholly different way of thinking about programming.
Prolog is about asking the computer questions (or 'queries' if you like). Computation is almost a side-effect of the computer trying to answer your question. There is no meaningful equivalent to loops or conditionals because a prolog programmer wouldn't think in those terms.
A good Prolog program looks like a description of the problem that you're trying to solve decomposed into recursive cases and subproblems rather than lists of instructions organised into functions or classes.
The best way to learn Prolog is to set aside all your previous programming experience. Actually thinking about C and C++ will make Prolog harder to learn and use. Try to adopt a beginner's mind and maybe an approach more like an algebraist than a programmer.
As a supplement to the Prolog tutorials and textbooks mentioned in the other answers, I would suggest having a quick look at this short document:
Prolog for Imperative Programmers
I think it's part of what you're looking for. It won't teach you Prolog, but it will help bridge the gap to understanding Prolog. It describes the basics of Prolog using terminology that experienced non-Prolog programmers would understand. For example, it shows you control structures in Prolog, i.e. sequence, selection and repetition. It does assume that you've already started learning Prolog, though.
It's good if you want to understand something new in terms of something you already know. However, armed with this knowledge/understanding, there is a risk that you could end up writing C code in Prolog syntax. Good luck!
What's wrong with Learn Prolog Now, which is usually the top recommendation each time this kind of question gets asked?
It may not give you exactly the terminology you want -- I believe it doesn't even mention "predicate" (uses "Facts, Rules, and Queries" instead) or "loops" (it just shows how to use recursion instead) -- but getting the terminology right once the concepts are clear should be simple, fast, and easy, and "Learn Prolog Now" does seem to do a good job about making the concepts clear.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Every language that is being used is being used for its advantages, generally.
What are the advantages of Prolog?
What are the general situations/ category of problems where one can use Prolog more efficiently than any other language?
Compared to what exactly? Prolog is really just the pre-eminent implementation of logic programming so if your question is really about a comparison of programming paradigms well that's really very broad indeed and you should look here.
If your question is more specifically about prolog vs the more commonly seen OO languages I would argue that you're really comparing apples to oranges - the "advantage" (such as it is) is just a different way of thinking about the world, and sometimes changing the way you ask a question provides a better tool for solving a problem.
Basically, if your program can be stated easily as declaritive formal logic statements, Prolog (or another language in that family) will give the fastest development time. If you use a good Prolog compiler, it will also give the best performance and reliability, because the engine will have had a lot of design and development effort.
Trying to implement this kind of thing in another language tends to be a mess. The cleanest and most general solution probably involves implementing your own unification engine. Even naive implementations aren't exactly trivial, the Warren Abstract Machine has a book or two written about it, and doing better will at the very least involve a fair bit of research, reading some headache-inducing papers.
Of course in the real world, key parts of your program may benefit from Prolog, but a lot of other stuff is better handled using another language. That's why a lot of Prolog compilers can interface with, e.g., C.
One of the best times to use Prolog is when you have a problem suited to solving with backtracking. And that is when you have lots of possible solutions to a problem, and perhaps you want to order them to include/exclude depending on some context. This suggests a lot of ambiguity... as in natural language processing.
It sure would be a lot tidier to write all the potential answers as Prolog clauses. With a imperative language all I think you can really do is write a giant (really giant) CASE statement, which is not too fun.
The stuff that are inherent in Prolog:
pattern matching!
anything that involves a depth first search. ( in Java if you want to do a DFS, you may want to implement it by a visitor pattern or do a (really giant) CASE
unification
??
Paul Graham, is a Lisp person nonetheless he argues that Prolog is really good for 2% of the problems, I am myself like to break this 2% down and figure how he'd come up with such number.
His argument for "better" languages is "less code, more power". Prolog is definitely "less code" and if you go for latter flavours of it (typed ones), you get more power too. The only thing that bothered me when using Prolog is the fact that I don't have random access in lists (no arrays).
Prolog is a very high level programming language. An analogy could be (Prolog : C) as (C : Assembler)
Why is not used that much then? I think that it has to do with the machines we use; They are based on turing machines. C can be compiled into byte code automatically, but Prolog is compiled to run on an emulation of the Abstract Warren Machine, thus, it is not that efficient.
Also, prolog is based on first order logic which is not capable of solving every solvable problem in a declarative manner, thus, at some point, you need to rely on imperative-like code.
I'd say prolog works well for problems where a knowledge base forms an important part of the solution. Especially when the knowledge structure is suited to be encoded as logical rules.
For example, writing a natural language interpreter for a particular problem domain would require a lot of knowledge in that domain. Expert systems also fall within this knowledge driven category.
It's also a nice language to explore solutions to logical puzzles ;-)
I have been programming (for fun) over a year with Swi-Prolog. I think one of the advantages of Prolog is that Prolog has no side effects: Prolog is language that kind of has no use for (local or class member) variables, it kind of forces the programmer not use variables. Prolog objects have no state, kind of. I think. I have been writing command line Prolog (no GUI, except few XPCE tests): it is like a train on a track.
First of all, is this only possible on algorithms which have no side effects?
Secondly, where could I learn about this process, any good books, articles, etc?
COQ is a proof assistant that produces correct ocaml output. It's pretty complicated though. I never got around to looking at it, but my coworker started and then stopped using it after two months. It was mostly because he wanted to get things done quicker, but if you need to verify an algorithm this might be a good idea.
Here is a course that uses COQ and talks about proving algorithms.
And here is a tutorial about writing academic papers in COQ.
It's generally a lot easier to verify/prove correctness when no side effects are involved, but it's not an absolute requirement.
You might want to look at some of the documentation for a formal specification language like Z. A formal specification isn't a proof itself, but is often the basis for one.
I think that verifying the correctness of an algorithm would be validating its conformance with a specification. There is a branch of theoretical Computer Science called Formal Methods which may be what you are looking for if you need to get as close to proof as you can. From wikipedia,
Formal Methods are a particular kind
of mathematically-based techniques for
the specification, development and
verification of software and hardware
systems
You will be able to find many learning resources and tools from the multitude of links on the linked Wikipedia page and from the Formal Methods wiki.
Usually proofs of correctness are very specific to the algorithm at hand.
However, there are several well known tricks that are used and re-used again. For example, with recursive algorithms you can use loop invariants.
Another common trick is reducing the original problem to a problem for which your algorithm's proof of correctness is easier to show, then either generalizing the easier problem or showing that the easier problem can be translated to a solution to the original problem. Here is a description.
If you have a particular algorithm in mind, you may do better in asking how to construct a proof for that algorithm rather than a general answer.
Buy these books: http://www.amazon.com/Science-Programming-Monographs-Computer/dp/0387964800
The Gries book, Scientific Programming is great stuff. Patient, thorough, complete.
Logic in Computer Science, by Huth and Ryan, gives a reasonably readable overview of modern systems for verifying systems. Once upon a time people talked about proving programs correct - with programming languages which may or may not have side effects. The impression I get from this book and elsewhere is that real applications are different - for instance proving that a protocol is correct, or that a chip's floating point unit can divide correctly, or that a lock-free routine for manipulating linked lists is correct.
ACM Computing Surveys Vol 41 Issue 4 (October 2009) is a special issue on software verification. It looks like you can get to at least one of the papers without an ACM account by searching for "Formal Methods: Practice and Experience".
The tool Frama-C, for which Elazar suggests a demo video in the comments, gives you a specification language, ACSL, for writing function contracts and various analyzers for verifying that a C function satisfies its contract and safety properties such as the absence of run-time errors.
An extended tutorial, ACSL by example, shows examples of actual C algorithms being specified and verified, and separates the side-effect-free functions from the effectful ones (the side-effect-free ones are considered easier and come first in the tutorial). This document is also interesting in that it was not written by the designers of the tools it describe, so it gives a fresher and more didactic look at these techniques.
If you are familiar with LISP then you should definitely check out ACL2: http://www.cs.utexas.edu/~moore/acl2/acl2-doc.html
Dijkstra's Discipline of Programming and his EWDs lay the foundation for formal verification as a science in programming. A simpler work is Wirth's Systematic Programming, which begins with the simple approach to using verification. Wirth uses pre-ISO Pascal for the language; Dijkstra uses an Algol-68-like formalism called Guarded (GCL). Formal verification has matured since Dijkstra and Hoare, but these older texts may still be a good starting point.
PVS tool developed by Stanford guys is a specification and verification system. I worked on it and found it very useful for Theoram Proving.
WRT (1), you will probably have to create a model of the algorithm in a way that "captures" the side-effects of the algorithm in a program variable intended to model such state-based side-effects.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I'm about to start (with fellow programmers) a programming & algorithms club in my high school. The language of choice is C++ - sorry about that, I can't change this. We can assume students have little to no experience in the aforementioned topics.
What do you think are the most basic concepts I should focus on?
I know that teaching something that's already obvious to me isn't an easy task. I realize that the very first meeting should be given an extreme attention - to not scare students away - hence I ask you.
Edit: I noticed that probably the main difference between programmers and beginners is "programmer's way of thinking" - I mean, conceptualizing problems as, you know, algorithms. I know it's just a matter of practice, but do you know any kind of exercises/concepts/things that could stimulate development in this area?
Make programming fun!
Possible things to talk about would be Programming Competitions that either your club could hold itself or it could enter in locally. I compete in programming competitions at the University (ACM) level and I know for a fact that they have them at lower levels as well.
Those kind of events can really draw out some competitive spirit and bring the club members closer.
Things don't always have to be about programming either. Perhaps suggest having a LAN party where you play games, discuss programming, etc could be a good idea as well.
In terms of actual topics to go over that are programming/algorithm related, I would suggest as a group attempting some of these programming problems in this programming competition primer "Programming Challenges": Amazon Link
They start out with fairly basic programming problems and slowly progress into problems that require various Data Structures like:
Stacks
Queues
Dictionaries
Trees
Etc
Most of the problems are given in C++.
Eventually they progress into more advanced problems involving Graph Traversal and popular Graph algorithms (Dijkstra's, etc) , Combinatrics problems, etc. Each problem is fun and given in small "story" like format. Be warned though, some of these are very hard!
Edit:
Pizza and Soda never hurts either when it comes to getting people to show up for your club meetings. Our ACM club has pizza every meeting (once a month). Even though most of us would still show up it is a nice ice breaker. Especially for new clubs or members.
Breaking it Down
To me, what's unique about programming is the need to break down tasks into small enough steps for the computer. This varies by language, but the fact that you may have to write a "for loop" just to count to 100 takes getting used to.
The "top-down" approach may help with this concept. You start by creating a master function for your program, like filterItemsByCriteria();
You have no idea how that will work, so you break it down into further steps:
(Note: I don't know C++, so this is just a generic example)
filterItemsByCritera() {
makeCriteriaList();
lookAtItems();
removeNonMatchingItems();
}
Then you break each of those down further. Pretty soon you can define all the small steps it takes to make your criteria list, etc. When all of the little functions work, the big one will work.
It's kind of like the game kids play where they keep asking "why?" after everything you say, except you have to keep asking "how?"
Linked lists - a classic interview question, and for good reason.
I would try to work with a C subset, and not try to start with the OO stuff. That can be introduced after they understand some of the basics.
Greetings!
I think you are getting WAY ahead of yourself in forcing a specific language and working on specific topics and a curriculum.. It sounds like you (and some of the responders) are confusing "advising a programming club" with "leading a programming class". They are very different things.
I would get the group together, and the group should decide what exactly they want to get out of the club. In essence, make a "charter" for the club. Then (and only then) can you make determinations such as preferred language/platform, how often to meet, what will happen at the meetings, etc.
It may turn out that the best approach is a "survey", where different languages/platforms are explored. Or it may turn out that the best approach is a "topical"one, where there topic changes (like a book club) on a regular basis (this month is pointers, next month is sorting, the following is recursion, etc.) and then examples and discussions occur in various languages.
As an aside, I would consider a "language-agnostic" orientation for the club. Encourage the kids to explore different languages and platforms.
Good luck, and great work!
Well, it's a programming club, so it should be FUN! So I would say dive into some hand on experience right away. Start with explaining what a main() method is,then have students write a hello world program. Gradually improve the hello world program so it has functions and prints out user inputs.
I would say don't go into algorithm too fast for beginners, let them play with C++ first.
Someone mentioned above, "make programming fun". It is interesting today that people don't learn for the sake of learning. Most people want instant gratification.
Teach a bit of logic using Programming. This helps with(and is) problem solving. The classing one I have in my head are guessing games.
Have them make a program that guesses at a number between 0 and 100.
Have them make a black jack clone ... I have done this in basic :-(
Make paper instructions.
Explain the "Fried eggs" story. Ask the auditory what they would do to make themselves fried eggs. Make them note the step they think about. Probably you will receive less than 5 steps algorithm. Then explain them how many steps should be written down if we want to teach a computer to fry eggs. Something like:
1) Go to the Fridge
2) Open the fridge door
3) Search for eggs
4) If there are no eggs - go to the shop to buy eggs ( this is another function ;) )
5) If there are eggs - calculate how many do you need to fry
6) Close the fridge door
7) e.t.c. :)
Start with basics of C - syntax semantics e.t.c, and in parallel with that explain the very basic algorithms like bubble sort.
After the auditory is familiar with structured programming (this could take several weeks or months, depending how often you make the lessons), you can advance to C++ and OOP.
The content in Deitel&Deitel's C++ programming is a decent introduction, and the exercises proposed at the end of each chapter are nice toy problems.
Basically, you're talking about:
- control structures
- functions
- arrays
- pointers and strings
You might want to follow up with an introduction to the STL ("ok, now that we've done it the hard way... here's a simpler option")
Start out by making them understand a problem like for instance sorting. This is very basic and they should be able to relate quite fast. Once they see the problem then present them with the tools/solution to solve it.
I remember how it felt when I first was show an example of merge-sort. I could follow all the steps but what the hell was I for? Make then crave a solution to a problem and they will understand the tool and solution much better.
start out with a simple "hello world" program. This introduces fundamentals such as variables, writing to a stream and program flow.
Then add complexity from there (linked lists, file io, getting user input, etc).
The reason I say start with hello world is because the kid will get to see a running program really quick. It's nearly immediate feedback-as they will have written a running program right from the start.
IMO, Big-O is one of the more important concepts for beginning programmers to learn.
Have a debugging contest. Provide code samples that include a bug. Have a contest to see who can find the most or fastest.
There is an excellent book, How Not to Program in C++, that you could use to start with.
You always learn best from mistakes and I prefer to learn from some else's.
It will also let those with little experience learn by see code, even if the code only almost works.
In addition to the answers to this question, there are certain important topics to cover. Here's an example of how you could structure the lessons.
First Lesson: Terminology and Syntax
Terminology to cover: variable, operator, loop (iteration), method, reserved word, data type, class
Syntax to cover: assignment, operation, if/then/else, for loop, while loop, select, input/output
Second Lesson: Basic Algorithm Construction
Cover a few simple algorithms, involving some input, maybe a for or a while loop.
Third Lesson: More Advanced Algorithm Topics
This is for things like recursion, matrix manipulation, and higher-level mathematics. You don't have to get into too complex of topics, but introduce enough complexity to be useful in a real project.
Final Lesson: Group Project
Make a project that groups can get involved in doing.
These don't have to be single day lessons. You can spread the topics across multiple days.
Pseudocode should be a very first.
Edit: If they are total programming beginners then I would make the first half just about programming. Once you get to a level where talking about algorithms would make sense then pseudocode is really important to get under the nails.
Thanks for your replies!
And how would you teach them actual problem solving?
I know a bunch of students that know C++ syntax and a few basic algorithms, but they can't apply the knowledge they know when they solve real problems - they don't know the approach, the way to transcribe their thoughts into a set of strict steps. I do not talk about 'high-level' approaches like dynamic programming, greedy etc., but about basic algorithmic mindset.
I assume it's just because of the poor learning process they were going through. In other sciences - math, for example - they are really brilliant.
Just because you are familiar with algorithms does not mean you can implement them and just because you can program does not mean you can implement an algorithm.
Start simple with each topic (keep programming separate from designing algorithms). Once they have a handle on each, slowly start to bring the two concepts together.
Wow. C++ is one of the worst possible languages to start with, in terms of the amount of unrelated crap you need to get anything working (Java would be slightly worse, I guess).
When teaching beginners in a boilerplate-heavy environment, it's usual to start with "here's a simple C program. We'll discuss what all this crap at the top of the file is for later, but for now, concentrate on the lines between 'int main(void)' and the 'return' statement, which is where all the useful work is accomplished".
Once you're past that point, basic concepts to cover include the basic data structures (arrays, linked lists, trees, and dictionaries), and the basic algorithms (sorting, searching, etc).
Have your club learn how to actually program in any language by teaching the concepts of building software. Instead of running out an buying a dozen licenses for Visual Studio, have students use compilers, make systems, source files, objects and librarys in order to turn their C code into programs. I feel this is truly the beginning and actually empowers these kids to understand how to make software on any platform, without crutches that many educational institutions like to rely on.
As for the language of choice - congratulations - you'll find C++ is very rich in making you think of mathematical shortcuts and millions of ways to make your code perform even better (or to implement fancy patterns).
To the question: When I was beggining to program I would always try to break down one real life problem into several steps and then as I see similarity between tasks or data they transform I would always try to find a lazier, easier, meanier way to implement it.
Elegance came after when learning patterns and real algorithms.
Hank: Big O??? you mean tell beginning programmers that their code is of O(n^2) and yours is of n log n ??
I could see a few different ways to take this:
1) Basic programming building blocks. What are conditional statements, e.g. switch and if/else? What are repetition statements, e.g. for and while loops? How do we combine these to get a program to be the sequence of steps we want? You could take something as easy as adding up a grocery bill or converting temperatures or distances from metric to imperial or vice versa. What are basic variable types like a string, integer, or double? Also in here you could have Boolean Algebra for an advanced idea or possibly teach how to do arithmetic in base 2 or 16 which some people may find easy and others find hard.
2) Algorithmically what are similar building blocks. Sorting is a pretty simple topic that can be widely discussed and analysed to try to figure out how to make this faster than just swapping elements that seem out of order if you learn the Bubblesort which is the most brain dead way to do.
3) Compiling and run-time elements. What is a call stack? What is a heap? How is memory handled to run a program,e.g. the code pieces and data pieces? How do we open and manipulate files? What is compiling and linking? What are make files? Some of this is simple, but it can also be eye-opening just to see how things work which may be what the club covers most of the time.
These next 2 are somewhat more challenging but could be fun:
4) Discuss various ideas behind algorithms such as: 1) Divide and conquer, 2) Dynamic programming, 3) Brute force, 4) Creation of a data structure, 5) Reducing a problem to a similar one already solved for example Fibonacci numbers is a classic recursive problem to give beginning programmers, and 6) The idea of being, "greedy," like in a making change example if you were in a country where coin denominations where a,b, and c. You could also get into some graph theory examples like a minimum weight spanning tree if you want something somewhat exotic, or the travelling salesmen for something that can be easy to describe but a pain to solve.
5) Mathematical functions. How would you program a factorial, which is the product of all numbers from 1 to n? How would you compute the sums of various Arithmetic or Geometric Series? Or compute the number of Combinations or Permutations of r elements from a set of n? Given a set of points, approximate the polynomial that meets this requirement, e.g. in a 2-dimensional plane called x and y you could give 2 points and have people figure out what are the slope and y intercept if you have solved pairs of linear equations already.
6) Lists which can be implemented using linked lists and arrays. Which is better for various cases? How do you implement basic functions such as insert, delete, find, and sort?
7) Abstract Data Structures. What are stacks and queues? How do you build and test classes?
8) Pointers. This just leads to huge amounts of topics like how to allocate/de-allocate memory, what is a memory leak?
Those are my suggestions for various starting points. I think starting a discussion may lead to some interesting places if you can get a few people together that don't mind talking on the same subject week after week in some cases as sorting may be a huge topic to cover well if you want to get into the finer points of things.
You guys could build the TinyPIM project from "C++ Standard Library from Scratch" and then, when it's working, start designing your own extensions.