Read e-book Lectures on the Logic of Computer Programming

Free download. Book file PDF easily for everyone and every device. You can download and read online Lectures on the Logic of Computer Programming file PDF Book only if you are registered here. And also you can download or read online all Book PDF file that related with Lectures on the Logic of Computer Programming book. Happy reading Lectures on the Logic of Computer Programming Bookeveryone. Download file Free Book PDF Lectures on the Logic of Computer Programming at Complete PDF Library. This Book have some digital formats such us :paperbook, ebook, kindle, epub, fb2 and another formats. Here is The CompletePDF Book Library. It's free to register here to get Book file PDF Lectures on the Logic of Computer Programming Pocket Guide.
An Introduction to the PL/CV2 Programming Logic (Lecture Notes in Computer Science) [R. L. Constable, S. D. Johnson, C. D. Eichenlaub] on
Table of contents

And a unifier is a slight generalization of a pattern matcher. What a unifier does is take two patterns and say what's the most general thing you can substitute for the variables in those two patterns to make them satisfy the pattern simultaneously? Let me give you an example. If I have the pattern two-element list, which is x and x, so I have a two-element list where both elements are the same and otherwise I don't care what they are, and I unify that against the pattern that says there's a two-element list, and the first one is a and something in c and the second one is a and b and z, then what the unifier should tell me is, oh yeah, in that dictionary, x has to be a, b, c, and y has to be d and z has to be c.

Those are the restrictions I'd have to put on the values of x, y, and z to make these two unify, or in other words, to make this match x and make this match x. The unifier should be able to deduce that. But the unifier may-- there are more complicated things. I might have said something a little bit more complicated. I might have said there's a list with two elements, and they're both the same, and they should unify against something of this form. And the unifier should be able to deduce from that. Like that y would have to be b.

Because these two are the same, so y's got to be b. And v here would have to be a. And z and w can be anything, but they have to be the same thing. And x would have to be b, followed by a, followed by whatever w is or whatever z is, which is the same. So you see, the unifier somehow has to deduce things to unify these patterns.

So you might think there's some kind of magic deduction going on, but there's not. A unifier is basically a very simple modification of a pattern matcher. And if you look in the book, you'll see something like three or four lines of code added to the pattern matcher you just saw to handle the symmetric case.

Remember, the pattern matcher has a place where it says is this variable matching a constant. And if so, it checks in the dictionary. There's only one other clause in the unifier, which says is this variable matching a variable, in which case you go look in the dictionary and see if that's consistent with what's in the dictionary. So all the, quote, deduction that's in this language, if you sort of look at it, sort of sits in the rule applications, which, if you look at that, sits in the unifier, which, if you look at that under a microscope, sits essentially in the pattern matcher.

There's no magic at all going on in there.

  • Contesting the Saudi State: Islamic Voices from a New Generation (Cambridge Middle East Studies).
  • The corporate forms kit.
  • Free Online Programming & Computer Science Courses You Can Start in February.

And the, quote, deduction that you see is just the fact that there's this recursion, which is unwinding the matches bit by bit. So it looks like this thing is being very clever, but in fact, it's not being very clever at all. There are cases where a unifier might have to be clever. Let me show you one more. Suppose I want to unify a list of two elements, x and x, with a thing that says it's y followed by a dot y. Now, if you think of what that would have to mean, it would have to mean that x had better be the same as y, but also x had better be the same as a list whose first element is a and whose rest is y.

And if you think about what that would have to mean, it would have to mean that y is the infinite list of a's. In some sense, in order to do that unification, I have to solve the fixed-point equation cons of a to y is equal to y. And in general, I wrote a very simple one. Really doing unification might have to solve an arbitrary fixed-point equation: f of y equals y. And basically, you can't do that and make the thing finite all the time. So how does the logic language handle that? The answer is it doesn't. It just punts.

And there's a little check in the unifier, which says, oh, is this one of the hard cases which when I go to match things would involve solving a fixed-point equation? And in this case, I will throw up my hands. And if that check were not in there, what would happen? In most cases is that the unifier would just go into an infinite loop. And other logic programming languages work like that.

So there's really no magic. The easy case is done in a matcher. The hard case is not done at all. And that's about the state of this technology. Let me just say again formally how rules work now that I talked about unifiers. So the official definition is that to apply a rule, we-- well, let's start using some words we've used before.

Let's talk about sticking dictionaries into these big boxes of query things as evaluating these large queries relative to an environment or a frame. So when you think of that dictionary, what's the dictionary after all? It's a bunch of meanings for symbols. That's what we've been calling frames or environments. What does it mean to do some processing relevant to an environment? That's what we've been calling evaluation. So we can say the way that you apply a rule is to evaluate the rule body relative to an environment that's formed by unifying the rule conclusion with the given query.

And the thing I want you to notice is the complete formal similarity to the net of circular evaluator or the substitution model. To apply a procedure, we evaluate the procedure body relative to an environment that's formed by blinding the procedure parameters to the arguments. There's a complete formal similarity here between the rules, rule application, and procedure application even though these things are very, very different. So in general, I might be processing some combined expression that will turn into a rule application, which will generate some dictionaries or frames or environments-- whatever you want to call them-- from match, which will then be the input to some big compound thing like this.

This has pieces of it and may have other rule applications. And you have essentially the same cycle even though there's nothing here at all that looks like procedures. It really has to do with the fact you've built a language whose means of combination and abstraction unwind in certain ways. And then in general, what happens at the very top level, you might have rules in your database also, so things in this database might be rules.

There are ways to check that things are true. So it might come in here and have to do a rule check. And then there's some control structure which says, well, you look at some rules, and you look at some data elements, and you look at some rules and data elements, and these fan out and out and out. So it becomes essentially impossible to say what order it's looking at these things in, whether it's breadth first or depth first or anything.

And it's even more impossible because the actual order is somehow buried in the delays of the streams. So what's very hard to tell from this is the order in which it's scanned. But what's true, because you're looking at the stream view, is that all of them eventually get looked at. Let me just mention one tiny technical problem. Suppose I tried saying boss of y is computer, then a funny thing would happen. As I stuck a dictionary with y in here, I might get-- this y is not the same as that y, which was the other piece of somebody's job description. So if I really only did literally what I said, we'd get some variable conflict problems.

So I lied to you a little bit. Notice that problem is exactly a problem we've run into before. It is precisely the need for local variables in a language. When I have the sum of squares, that x had better not be that x. That's exactly the same as this y had better not be that y. And we know how to solve that. That was this whole environment model, and we built chains of frames and all sorts of things like that.

There's a much more brutal way to solve it. In the query language, we didn't even do that. We did something completely brutal. We said every time you apply a rule, rename consistently all the variables in the rule to some new unique names that won't conflict with anything. That's conceptually simpler, but really brutal and not particularly efficient. But notice, we could have gotten rid of all of our environment structures if we defined for procedures in Lisp the same thing.

If every time we applied a procedure and did the substitution model we renamed all the variables in the procedure, then we never would have had to worry about local variables because they would never arise. OK, well, that would be inefficient, and it's inefficient here in the query language, too, but we did it to keep it simple. Let's break for questions.

And then you say we're going to have this language which is so different. It turns out that this language, as you just pointed out, is very much the same. I'm wondering if you're arguing that all languages end up coming down to this you can apply a rule or apply a procedure or some kind of apply? PROFESSOR: I would say that pretty much any language where you really are building up these means of combination and giving them simpler names and you're saying anything of the sort, like here's a general kind of expression, like how to square something, almost anything that you would call a procedure.

If that's got to have parts, you have to unwind those parts. You have to have some kind of organization which says when I look at the abstract variables or tags or whatever you want to call them that might stand for particular things, you have to keep track of that, and that's going to be something like an environment. And then if you say this part can have parts which I have to unwind, you've got to have something like this cycle.

And lots and lots of languages have that character when they sort of get put together in this way. This language again really is different because there's nothing like procedures on the outside. When you go below the surface and you see the implementation, of course, it starts looking the same. But from the outside, it's a very different world view. You're not computing functions of inputs. AUDIENCE: You mentioned earlier that when you build all of these rules in pattern matcher and with the delayed action of streams, you really have no way to know in what order things are evaluated.

Otherwise, these things get all The question is this really is set up for doing declarative knowledge, and as I presented it-- and I'll show you some of the ugly warts under this after the break. As I presented it, it's just doing logic. And in principle, if it were logic, it wouldn't matter what order it's getting done. And it's quite true when you start doing things where you have side effects like adding things to the database and taking things out, and we'll see some others, you use that kind of control.

So, for example, contrasting with Prolog. Say Prolog has various features where you really exploit the order of evaluation. And people write Prolog programs that way. That turns out to be very complicated in Prolog, although if you're an expert Prolog programmer, you can do it. However, here I don't think you can do it at all. It's very complicated because you really are giving up control over any prearranged order of trying things. And when you started out this lecture, you said that we express the declarative knowledge which is a relation, and we don't talk about the inputs and the outputs.

  • The American eclectic practice of medicine ...?
  • Microarchitecture of VLSI Computers!
  • Islam and Democracy: Fear of the Modern World (Revised Edition).
  • Aspects of Littorinid Biology: Proceedings of the Fifth International Symposium on Littorinid Biology, held in Cork, Ireland, 7–13 September 1996.
  • Online Computer Science Education!
  • Sex and Money: How I Lived, Breathed, Read, Wrote, Loved, Hated, Slept, Dreamed and Drank Mens Magazines?

There's function in the sense of no side effects and not depending on what order is going on. And then there's functional in the sense of mathematical function, which means input and output. And it's just that pun that you're making, I think. Is the first one building up the database and the second one a query or What I meant here, if I type something like this in as a query-- I should have given an example way at the very beginning.

If I type in job, Ben Bitdiddle, computer wizard, what the processing will do is if it finds a match, it'll find a match to that exact thing, and it'll type out a job, Ben Bitdiddle, computer wizard. If it doesn't find a match, it won't find anything. So what I should have said is the way you use the query language to check whether something is true, remember, that's one of the things you want to do in logic programming, is you type in your query and either that comes out or it doesn't.

So what I was trying to illustrate here, I wanted to start with a very simple example before talking about unifiers. So what I should have said, if I just wanted to check whether this is true, I could type that in and see if anything came out. And this will pass through, and then by the time it got out of here, who would pick up a binding. If the unifying-- the rule here says-- OK, so you say that you can't make question mark equal to question mark who. That's what the matcher can't do.

But what this will mean to a unifier is that there's an environment with three variables. So if later on in the matcher routine it said, for example, who has to be 3, then when I looked up in the dictionary, it will say, oh, z is 3 because it's the same as who. And that's in some sense the only thing you need to do to extend the unifier to a matcher. AUDIENCE: OK, because it looked like when you were telling how to unify it, it looked like you would put the things together in such a way that you'd actually solve and have a value for both of them.

And what it looks like now is that you're actually pass a dictionary with two variables and the variables are linked. It only looks like you're solving for both of them because you're sort of looking at the whole solution at once. If you sort of watch the thing getting built up recursively, it's merely this. It just looks like an ordinary dictionary. Can you add some properties either to the rules itself or to the formula that you're writing so that you avoid the problem of not finding unification?

See, because what you're getting-- see, the place where you get into problems is when you-- well, again, you're trying to match things like that against things where these have structure, where a, y, b, y something. So this is the kind of place where you're going to get into trouble. It's a problem either-- not quite the builder of the database, the person who is expressing the rules, or the builder of the database. What the unifier actually does is you can check at the next level down when you actually get to the unifier and you'll see in the code where it looks up in the dictionary.

If it sort of says what does y have to be? Oh, does y have to be something that contains a y as its expression? At that point, the unifier and say, oh my God, I'm trying to solve a fixed-point equation. I'll give it up here. Are the rules added to the database? Yes, I should have said that.

One way to think about rules is that they're just other things in the database. So if you want to check the things that have to be checked in the database, they're kind of virtual facts that are in the database. The only reason to do that is in terms of the implementation. When you look at the implementation, there's a part which says check either primitive assertions in the database or check rules. And then the real reason why you can't tell what order things are going to come out in and is that the rules database and the data database sort of get merged in a kind of delayed evaluation way.

And so that's what makes the order very complicated. OK, let's break. We've just seen how the logic language works and how rules work. Now, let's turn to a more profound question. What do these things mean? That brings us to the subtlest, most devious part of this whole query language business, and that is that it's not quite what it seems to be. Let me give you an example of that. But let's look here. Here's an example. Let's talk about somebody outranking somebody else in our little database organization. We'll say s is outranked by b or if either the supervisor of this is b or there's some middle manager here, that supervisor of s is m, and m is outranked by b.

So there's one way to define rule outranked by. Or we can write exactly the same thing, except at the bottom here, we reversed the order of these two clauses. And certainly if this were logic, those ought to mean the same thing. However, in our particular implementation, if you say something like who's outranked by Ben Bitdiddle, what you'll find is that this rule will work perfectly well and generate answers, whereas this rule will go into an infinite loop.

And the reason for that is that this will come in and say, oh, who's outranked by Ben Bitdiddle?

How to become a Computer Programmer

Find an s which is outranked by b, where b is Ben Bitdiddle, which is going to happen in it a subproblem. Oh gee, find an m such as m is outranked by Ben Bitdiddle with no restrictions on m. So this will say in order to solve this problem, I solve exactly the same problem. And then after I've solved that, I'll check for a supervisory relationship.

Whereas this one won't get into that, because before it tries to find this outranked by, it'll already have had a restriction on m here. So these two things which ought to mean the same, in fact, one goes into an infinite loop. One does not. That's a very extreme case of a general thing that you'll find in logic programming that if you start changing the order of the things in the ANDs or ORs, you'll find tremendous differences in efficiency. And we just saw an infinitely big difference in efficiency and an infinite loop.

And there are similar things having to do with the order in which you enter rules. The order in which it happens to look at rules in the database may vastly change the efficiency with which it gets out answers or, in fact, send it into an infinite loop for some orderings. And this whole thing has to do with the fact that you're checking these rules in some order.

On-line books, lecture notes, etc

And some rules may lead to really long paths of implication. Others might not. And you don't know a priori which ones are good and which ones are bad. And there's a whole bunch of research having to do with that, mostly having to do with thinking about making parallel implementations of logic programming languages. And in some sense, what you'd like to do is check all rules in parallel and whichever ones get answers, you bubble them up.

And if some go down infinite deductive changed, well, you just-- you know, memory is cheap and processors are cheap, and you just let them buzz for as for as long as you want. There's a deeper problem, though, in comparing this logic language to real logic. The example I just showed you, it went into an infinite loop maybe, but at least it didn't give the wrong answer. Time Management. Computer Science. Computer Networking. Information Technology. Internet of Things.

Algorithms and Data Structures. Data Algorithms. Data Structures. Artificial Intelligence. Computer Vision. Deep Learning. Machine Learning. Natural Language Processing. Neural Networks. Theoretical Computer Science. Data Science. Big Data.

Logic and its Applications, Lecture Notes in Computer Science 10119

Data Mining. Data Analysis. Data Visualization. Data Science Tools. Apache Hadoop. Apache Spark. Higher Education. Museum Studies. Educational Technology. Instructional Design. Teacher Development. Course Development. Test Prep. Mental Health. Global Health.

CS402 Introduction to Logic for Computer Science (Spring 2018)

Public Health. Clinical Trials. Health Research. Medical Research. Ethnicity and Race. Indigenous Peoples. Ancient History. Middle Ages. World History. Regional Culture. Latin America. Middle East. North America. South America. Falun Gong.

The 15th Reasoning Web Summer School

Linear Algebra. Differential Equations. Game Development. Software Development. High-Level Programming Languages. Mobile Development. Android Development. Web Development. Web Design. Molecular Biology. Regenerative Biology. Stem Cells. Systems Biology. Organic Chemistry.

Synthesis Lectures on Computer Science

Chemical Engineering. Systems Science. Civil Engineering. Electrical Engineering. IITBombay also offers self-paced beginner courses in programming including Programming Basics and Object-Oriented Programming that focus on logical thinking and programming best practices. Next, dive into different computer programming languages.

Discover the similarities between different languages and gain an understanding of which language is the right one for a particular task. Want to go further? Enroll in an advance MicroMasters program to build on your knowledge and experience. A skilled and experienced computer programmer can essentially write their own ticket. There are thousands of open jobs in programming and related fields. For example, a search for available positions for Java programmers on Indeed.

People wishing to enter the world of computer programming can choose to specialize in any number of popular programming languages and find many entry-level opportunities. Get started as a junior programmer in the language of your choice and gain the experience and skills to move up the ladder to software engineer or even Chief Technology Officer.

Take a beginner course in computer science or any number of programming languages and see if this exciting, in-demand field is right for you. Introductory, self-paced courses are available now to help you learn to code in many different languages.