I currently am generating a prolog tree with input such as:
the flight flew.
whose tree looks like this:
s(the, np(flight), vp(flew))
After I generate said tree I am attempting to check if, in this case, "the" is in fact "the". There is another case where it could be "did".
As far as I'm aware, a prolog if statement is formatted like:
( IF -> THEN; ELSE ),
and I'm trying to do:
( s(the, A, B)) -> assert(Tree); do_something_else ),
but when I do that, I cannot run the program. How would I go about asking about a specific value in a tree in an if statement? Am I doing an if statement correctly in the first place?
You need to be able to give useful information on what actually happens when you try to run your actual program. In other words, learn how to provide a minimal, complete, and verifiable example.
If you have your "tree" in a term like you show it, all you need is a rule that uses pattern matching (unification) in the head to check if the first argument of s/3 is the or did:
foo(s(the, A, B)) :- /* do some stuff */.
foo(s(did, A, B)) :- /* do other stuff */.
This is probably better than using an if-then-else construct. If you insist, you would have to say something like:
T = s(Foo, A, B),
( Foo == the
-> /* do something */
; Foo == did
-> /* do something else */
; /* anything else */
)
The point here is that the condition in the if-then-else has to be something that is evaluated and either succeeds or fails: you cannot use pattern matching as you do in the head of a predicate. Another roundabout way of writing the condition would be to use something like arg/3:
( arg(1, T, the)
-> /* ... */
; arg(1, T, did)
-> /* ... */
; /* ... */
)
But what is bothering me is that after parsing you end up with either an article, the, or a verb, did. What part of the sentence is the first argument of s/3 supposed to represent?
Related
So I want to print a list with all the squares of numbers up to n.(in sml nj)
Example
>printl 3 ;
> [0,1,4,9]
The thing is I have to print them using this function "creat" that creats a list with those:
(*print elements squares up to n*)
fun printl n =
( print(Int.toString(hd (creat n []))); printl(n-1); );
(*creat a list *)
fun creat n acc = if n<0 then acc
else (creat (n-1) ((n*n)::acc) );
As you can see, I tried to call "creat" with [] in order to create the desired list of squares up to n and then I tried to print the head while recursively calling what's left without it (printl n-1).
I generate this error though:
sml square.sml:2.55 Error: syntax error: replacing RPAREN with LET
So I guess there something wrong with the number of instructions in printl?
The problem comes from the semi-colon after printl(n-1) because your
compiler waits for another expression. Hence, the error message
meaning that he won't accept an ) here but rather a let. So just
remove that semi-colon.
Note that the semi-colon has two different meanings:
either to sequence expressions a ; b ; c. So in that context a ; b ; is syntactically incorrect ;
or either to mark the end of a declaration at a top level in order
to let the compiler know you are done with the current definition (as
you have done for your two functions).
I am trying to prove the following lemma in Coq:
Require Import Lists.List.
Import ListNotations.
Lemma not_empty : forall (A : Type) (a b : list A),
(a <> [] \/ b <> []) -> a ++ b <> [].
Right now my current strategy was to destruct on a, and after breaking the disjunction I could ideally just state that if a <> [] then a ++ b must also be <> []... That was the plan, but I can't seem to get past a subgoal that resembles the first " a ++ b <> []", even when my context clearly states that " b <> []". Any advice?
I've also looked through a lot of the pre-existing list theorems and haven't found anything particularly helpful (minus app_nil_l and app_nil_r, for some subgoals).
Starting with destruct a is a good idea indeed.
For the case where a is Nil, you should destruct the (a <> [] \/ b <> []) hypothesis. There will be two cases:
the right one the hypothesis [] <> [] is a contradiction,
the left one, the hypothesis b <> [] is your goal (since a = [])
For the case where a is a :: a0, you should use discriminate as Julien said.
You started the right way with your destruct a.
You should end up at some point with a0::a++b<>0. It ressembles a++b<>0 but it is quite different as you have a cons here, thus discriminate knows that it is different from nil.
first, I am not sure which Coq version you are using, the syntax certainly looks odd. Seconds, it is hard for us to help if you don't show us the proof you have so far. I should say that indeed your strategy seems correct, you should destruct both lists, tho it is better if you first inspect the or to see which list is not empty.
Another option is to use computation to show your lemma, in this case, equality will compute and thus you will get the result of the comparison. It suffices to destroy only one list in this case due the order or arguments:
From mathcomp Require Import all_ssreflect.
Lemma not_empty (A : eqType) (a b : seq A) :
[|| a != [::] | b != [::]] -> a ++ b != [::].
Proof. by case: a. Qed.
I'm trying to write a simple Ocaml function but im getting this error:
Error: This expression has type unit
but an expression was expected of type int
let rec euclid a b =
if a = b then a
else if a < b then 1
else if a > b then 2
To fix the immediate problem, you need else clauses in your function:
let rec euclid a b =
if a = b then a
else if a < b then 1
else 2 (* You know a > b is the only possible alternative *)
You may realize this, but this function is not recursive, nor, I think, is it doing what you want it to do.
However, there is an error in the way you're conceptualizing how a function works in Ocaml. The way you've written the function is imperative in nature; it is a series of if/then statements which are acted upon sequentially. Rather, the return value of euclid should be simply the result of one broad if/then statement (an integer value). Nesting, as I have done above, can be acceptable, but the essential thing to take away is that a function is just a single expression which is evaluated, not a series of imperative actions.
EDIT for updated question:
All OCaml if/then statements should have else clauses. Your very last nested if/then statement has no else clause. If OCaml detects an if/then statement with no else clause, an else clause is assumed returning () (unit). Essentially, if a > b is false, what should OCaml return? It assumes nothing, but returning () conflicts with the supposed type of your function (an integer).
Of course, that a > b is false is impossible in your function, since if not a = b and not a < b, the only other choice is a > b. Thus, you don't need another if statement at the end of your function; at that point, you know without a doubt that a > b, so you can simply say else 2.
Alright, so I was making some tests to get familiar with Scala, and wanted to see if I could make lists Java style rather than the fancy way you'd do it in Scala...
I know that you can do it like this: val lst = List.range(0, 100, 1) but I just wanted to see what java style would look like in scala
Alright so here's what I did:
var lst = List[Int]()
for(i <- 0 until 100) {
lst = lst :: i // here's where it complains
}
for some reason scala, or at least the scala ide for eclipse doesn't like that I append using infix notation, a-la lst :: i it wants me to do it like this: lst.::(i) otherwise it says :: isn't defined or something, it's not the first time it's happened either...
so can anyone here explain why it does that, or is it just a case of bad implementation in eclipse and thus something I have to live with
This isn't a problem with infix notation. Rather, it's because method names ending with : are applied as
a ??: b
b.??:(a)
So you simply have your arguments backwards.
lst = i :: lst
will work fine.
(Of course, you then have the issue that lists act like stacks, so you need to push the numbers on in reverse order.)
In Scala, a List is of immutable length. It can work like a LIFO (last in, first out) structure, but it cannot behave like a Java ArrayList.
You are doing this:
val lst = List[Int]()
which gives your lst a size of 0. It means you can't really do anything with it.
For a mutable collection, use ListBuffer.
Also, the :: operator is right associative, which means it will be called on the object found on the right side of the operator.
val lst = ListBuffer[Int]()
for (i <- 0 until 100) {
lst += i // will add to the tail.
}
I'm new to prolog and I'm trying to figure out how I can use if/else statement and recursion. To illustrate, I've written a simple prolog program. The program is useless (in that its functionality is useless), but it helps me illustrate my problem. The program takes a list, examines the head of the list, sees if it's the last element; if it's not, it adds the head to a temporary list variable and runs the program in recursion using the Tail of the list. It should output the list in the end. The program:
gothrough([H|T], B, C):-
append(B,H,B),
( (T == [])
-> C=B
; gothrough(T, B, C)
).
The call: gothrough([sample, phrase, here], [], C).
Expected output: C = [sample, phrase, here]
Current output: no
Any help on what I'm doing wrong?
Thanks!
From your comments I understand that you misunderstand how append (and Prolog in general) works.
This is not true at all: "if B = [yesterday] and H = [today], then append(B, H, B) = [yesterday, today]".
append(B, H, B) means "appending H to B yields B again". This is only possible if H is an empty list.
The key thing to understand is that both Bs in append(B, H, B) are the same, they must have the same value. It's like variables in algebra - all Xs in an equation means the same value.
You should use different name for the output variable, like append(B, H, Bnew) - then it will make more sense.
The first problem is append(B, H, B) which for most inputs doesn't make sense.
The second problem is that the consequence and alternative of an if-then-else, i.e. the parts after -> and after ; must both be Prolog goals (statements). C is not a goal. You may have meant C=B, though it's hard to tell because I find it hard to understand what your program is doing.
You're getting a no because append(B,H,B) fails unless H is []; remember, these are clauses, not assignments. And since you never bind anything to C, it will never have a value in it if your statement was ever proved.
This will accomplish your task:
gothrough([],L,L).
gothrough([H|T], B, C) :- gothrough(T,B,Cx), append([H],Cx,C).
This can be done even more simply:
gothrough([], []).
gothrough([H|T], [H|X]) :-
gothrough(T, X).
The first rule matches your empty list condition, which then forces the end of the recursion/the list to be built.
The second rule matches everything but an empty list, in which case the head H is appended onto X, where X is the result of list obtained from recursing the tail. ie. you don't need to use the append predicate - list appending is built into prolog.
?- gothrough([simple, phrase, here], X).
X = [simple, phrase, here].
This solution also uses one less variable.