I'm trying to test if a list of brackets is valid. My code:
checkbrackets([]).
checkbrackets(['('|T]):-
T = [')'|List],
checkbrackets(List).
checkbrackets(['('|T]):-
T = ['('|List],
append(Rest,[')'],T),
checkbrackets(Rest).
My code works for ['(', '(', ')', '(', '(', ')', ')', ')']
but it fails for ['(', '(', ')', ')', '(', ')'].
What am I doing wrong? Is it possible to write such a test without additional arguments like counters?
your append(Rest, [')'], T) will parse until the end of the list, but it is not said that the opening bracket will eventually match with the last closing bracket, for example ()() does not.
That being said, I think you make things overcomplicated. Instead of obtaining all sorts of sublists, you can use a single scan here: you use an accumulator that you initialize with 0, and the accumulator should eventually end with 0 and never be less than zero, so:
checkbrackets(B) :-
checkbrackets(B, 0).
checkbrackets([], 0). %% ← at the end, zero
checkbrackets([')'|T], N) :-
N > 0, %% ← always greater than or equal to zero.
N1 is N-1,
checkbrackets(T, N1).
checkbrackets(['('|T], N) :-
N1 is N+1,
checkbrackets(T, N1).
For the sake of completeness, here is a solution without additional arguments.
checkbrackets([]).
checkbrackets(['('|Rest]):-
append(Sub1,[')'|Sub2],Rest),
checkbrackets(Sub1),
checkbrackets(Sub2).
It simply follows the definition of "properly parenthesized" expression. Either it is empty, or it starts with a (, followed by a properly parenthesized subexpression (Sub1), followed by ), followed by another properly parenthesized subexpression (Sub2).
However, it is fairly inefficient as compared to the direct solution with one extra argument presented by Willem Van Onsem. The main issue is that the append/3 call needs to non-deterministically "guess" the position of the matching closing parenthesis and this generates a lot of backtracking.
Is it possible to write such a test without additional arguments like counters?
I'm fairly sure it's not possible to write such a test (edit: that does a single pass through the list) without tracking additional information such as a counter or a stack. This is because the language you are parsing is a proper context-free language as opposed to a regular one. Parsing context-free languages requires some sort of unbounded state representation, while regular languages get away with finite states.
You would typically handle that extra state using arguments. Possibly hidden ones using definite clause grammars (DCGs). But here -- and I very strongly suggest you do not use this for anything -- is a way of storing that state not in an extra argument but at the head of the list itself.
First, make sure we are using useful syntax for parsing:
:- set_prolog_flag(double_quotes, chars).
This means that anything between double quotes will get interpreted as a list of characters, so you can write "(()" equivalently to the very unreadable ['(', '(', ')'].
Here is the code itself:
checkbrackets([]).
checkbrackets(['(' | Xs]) :-
checkbrackets([count(1) | Xs]).
checkbrackets([count(0)]).
checkbrackets([count(N), '(' | Xs]) :-
N1 is N + 1,
checkbrackets([count(N1) | Xs]).
checkbrackets([count(N), ')' | Xs]) :-
N > 0,
N1 is N - 1,
checkbrackets([count(N1) | Xs]).
This "replaces" the first opening parenthesis with a counter initialized to 1. It increments and decrements that counter as it consumes other opening or closing parentheses. At every update of the counter, the new value is pushed to the front of the list that is passed into the recursive call. The predicate succeeds when all parentheses in the list have been consumed and the counter is at exactly 0. (You don't say if you want to accept ()() or not. This implementation resolves this ambiguity in a particular way that might not be what you intended.)
Examples:
?- checkbrackets("").
true.
?- checkbrackets("(()(()))").
true ;
false.
?- checkbrackets("()(()))").
false.
?- checkbrackets("(()(())").
false.
You could use the same trick to parse more complicated languages that need more complex state than a single counter. But you shouldn't. DCGs are the best way to do this in Prolog.
Note that the implementation above does accept a list that is not purely a list of parentheses:
?- checkbrackets([count(0)]).
true ;
false.
It's possible to fix this, but you shouldn't, since you shouldn't use this approach at all.
checkbrackets([]).
checkbrackets(L):-
append(Sub1,['(',')'|Sub2],L),
!,
append(Sub1,Sub2,New),
checkbrackets(New).
It does need only one attribute and checks in square time. Not as fast as Willems or Isabelles code but works.
The idea is that in each valid bracket constellation there is at least once the pattern of one opening and one closing bracket next to each other. Find them, delete them, repeat.
Related
I am new to using arithmetic in Prolog.
I’ve done a few small programs, but mostly involving logic. I am trying to implement a function that will return true or false if the difference between every consecutive pair of elements is the same or not.
My input would look like this: sameSeqDiffs([3, 5, 7, 9], 2)
I feel like I need to split the first two elements from the list, find their difference, and add the result to a new list. Once all the elements have been processed, check if the elements of the new list are all the same.
I’ve been taught some Prolog with building relationships and querying those, but this doesn’t seem to fit in with Prolog.
Update1: This is what I've come up with so far. I am brand new to this syntax and am still getting an error on my code, but I hope it conveys the general idea of what I'm trying to do.
diff([X,Y|Rest], Result):-
diff([Y,Z|Rest], Result2):-
Result2 = Result,
Z - Y = Result.
Update2: I know I still have much to do on this code, but here is where I will remain until this weekend, I have some other stuff to do. I think I understand the logic of it a bit more, and I think I need to figure out how to run the last line of the function only if there is at least two more things in the rest of the list to process.
diff([X,Y|Rest], Result):-
number(Y),
Y-X=Result,
diff([Rest], Result).
Update3: I believe I have the function the way I want it to. The only quirk I noticed is that when I run and input like: sameSeqDiffs([3,5,7],2).I get true returned immediately followed by a false. Is this the correct operation or am I still missing something?
sameSeqDiffs([X,Y], Result):-
A is Y - X,
A = Result.
sameSeqDiffs([X,Y,Z|T], Result):-
sameSeqDiffs([Y,Z|T], Result).
Update 4: I posted a new question about this....here is the link: Output seems to only test the very last in the list for difference function
Prolog's syntax
The syntax is a bit off: normally a clause has a head like foo(X, Y, Z), then an arrow (:-), followed by a body. That body normally does not contain any arrows :-. So the second arrow :- makes not much sense.
Predicates and unification
Secondly in Prolog predicates have no input or output, a predicate is true or false (well it can also error, or got stuck into an infinite loop, but that is typically behavior we want to avoid). It communicates answers by unifying variables. For example a call sameSeqDiffs([3, 5, 7, 9], X). can succeed by unifying X with 2, and then the predicate - given it is implemented correctly - will return true..
Inductive definitions
In order to design a predicate, on typically first aims to come up with an inductive definition: a definition that consists out of one or more base cases, and one or more "recursive" cases (where the predicate is defined by parts of itself).
For example here we can say:
(base case) For a list of exactly two elements [X, Y], the predicate sameSeqDiffs([X, Y], D) holds, given D is the difference between Y and X.
In Prolog this will look like:
sameSeqDiffs([X, Y], D) :-
___.
(with the ___ to be filled in).
Now for the inductive case we can define a sameSeqDiffs/2 in terms of itself, although not with the same parameters of course. In mathematics, one sometimes defines a function f such that for example f(i) = 2×f(i-1); with for example f(0) = 1 as base. We can in a similar way define an inductive case for sameSeqDiffs/2:
(inductive case) For a list of more than two elements, all elements in the list have the same difference, given the first two elements have a difference D, and in the list of elements except the first element, all elements have that difference D as well.
In Prolog this will look like:
sameSeqDiffs([X, Y, Z|T], D) :-
___,
sameSeqDiffs(___, ___).
Arithmetic in Prolog
A common mistake people who start programming in Prolog make is they think that, like it is common in many programming languages, Prolog add semantics to certain functors.
For example one can think that A - 1 will decrement A. For Prolog this is however just -(A, 1), it is not minus, or anything else, just a functor. As a result Prolog will not evaluate such expressions. So if you write X = A - 1, then X is just X = -(A,1).
Then how can we perform numerical operations? Prolog systems have a predicate is/2, that evaluates the right hand side by attaching semantics to the right hand side. So the is/2 predicate will interpret this (+)/2, (-)/2, etc. functors ((+)/2 as plus, (-)/2 as minus, etc.).
So we can evaluate an expression like:
A = 4, is(X, A - 1).
and then X will be set to 3, not 4-1. Prolog also allows to write the is infix, like:
A = 4, X is A - 1.
Here you will need this to calculate the difference between two elements.
You were very close with your second attempt. It should have been
samediffs( [X, Y | Rest], Result):-
Result is Y - X,
samediffs( [Y | Rest], Result).
And you don't even need "to split the first two elements from the list". This will take care of itself.
How? Simple: calling samediffs( List, D), on the first entry into the predicate, the not yet instantiated D = Result will be instantiated to the calculated difference between the second and the first element in the list by the call Result is Y - X.
On each subsequent entry into the predicate, which is to say, for each subsequent pair of elements X, Y in the list, the call Result is Y - X will calculate the difference for that pair, and will check the numerical equality for it and Result which at this point holds the previously calculated value.
In case they aren't equal, the predicate will fail.
In case they are, the recursion will continue.
The only thing missing is the base case for this recursion:
samediffs( [_], _Result).
samediffs( [], _Result).
In case it was a singleton (or even empty) list all along, this will leave the differences argument _Result uninstantiated. It can be interpreted as a checking predicate, in such a case. There's certainly no unequal differences between elements in a singleton (or even more so, empty) list.
In general, ......
recursion(A, B):- base_case( A, B).
recursion( Thing, NewThing):-
combined( Thing, Shell, Core),
recursion( Core, NewCore),
combined( NewThing, Shell, NewCore).
...... Recursion!
Is there a way of evaluating a list difference between infinite lists? For example, ([1..] \\ [2*n | n <- [1..]]) should evaluate to [1,3,5,7,...]. Unfortunately, it seems to be forcing evaluation on either the first or second list, or both. Is there a way of avoiding this to get answers? Even using take 5 ([1..] \\ [2*n | n <- [1..]]) doesn't evaluate to [1,3,5,7,9], which would be obviously correct. Note, the \\ operator is imported from Data.List.
If the lists are sorted, you may use the data-ordlist package.
Data.List.Ordered> take 5 ([1..] `minus` [2,4..])
[1,3,5,7,9]
I'm writing a prolog program to check if a variable is an integer.
The way I'm "returning" the result is strange, but I don't think it's important for answering my question.
The Tests
I've written passing unit tests for this behaviour; here they are...
foo_test.pl
:- begin_tests('foo').
:- consult('foo').
test('that_1_is_recognised_as_int') :-
count_ints(1, 1).
test('that_atom_is_not_recognised_as_int') :-
count_ints(arbitrary, 0).
:- end_tests('foo').
:- run_tests.
The Code
And here's the code that passes those tests...
foo.pl
count_ints(X, Answer) :-
integer(X),
Answer is 1.
count_ints(X, Answer) :-
\+ integer(X),
Answer is 0.
The Output
The tests are passing, which is good, but I'm receiving a warning when I run them. Here is the output when running the tests...
?- ['foo_test'].
% foo compiled into plunit_foo 0.00 sec, 3 clauses
% PL-Unit: foo
Warning: /home/brandon/projects/sillybin/prolog/foo_test.pl:11:
/home/brandon/projects/sillybin/prolog/foo_test.pl:4:
PL-Unit: Test that_1_is_recognised_as_int: Test succeeded with choicepoint
. done
% All 2 tests passed
% foo_test compiled 0.03 sec, 1,848 clauses
true.
I'm using SWI-Prolog (Multi-threaded, 64 bits, Version 6.6.6)
I have tried combining the two count_ints predicates into one, using ;, but it still produces the same warning.
I'm on Debian 8 (I doubt it makes a difference).
The Question(s)
What does this warning mean? And...
How do I prevent it?
First, let us forget the whole testing framework and simply consider the query on the toplevel:
?- count_ints(1, 1).
true ;
false.
This interaction tells you that after the first solution, a choice point is left. This means that alternatives are left to be tried, and they are tried on backtracking. In this case, there are no further solutions, but the system was not able to tell this before actually trying them.
Using all/1 option for test cases
There are several ways to fix the warning. A straight-forward one is to state the test case like this:
test('that_1_is_recognised_as_int', all(Count = [1])) :-
count_ints(1, Count).
This implicitly collects all solutions, and then makes a statement about all of them at once.
Using if-then-else
A somewhat more intelligent solution is to make count_ints/2 itself deterministic!
One way to do this is using if-then-else, like this:
count_ints(X, Answer) :-
( integer(X) -> Answer = 1
; Answer = 0
).
We now have:
?- count_ints(1, 1).
true.
i.e., the query now succeeds deterministically.
Pure solution: Clean data structures
However, the most elegant solution is to use a clean representation, so that you and the Prolog engine can distinguish all cases by pattern matching.
For example, we could represent integers as i(N), and everything else as other(T).
In this case, I am using the wrappers i/1 and other/1 to distinguish the cases.
Now we have:
count_ints(i(_), 1).
count_ints(other(_), 0).
And the test cases could look like:
test('that_1_is_recognised_as_int') :-
count_ints(i(1), 1).
test('that_atom_is_not_recognised_as_int') :-
count_ints(other(arbitrary), 0).
This also runs without warnings, and has the significant advantage that the code can actually be used for generating answers:
?- count_ints(Term, Count).
Term = i(_1900),
Count = 1 ;
Term = other(_1900),
Count = 0.
In comparison, we have with the other versions:
?- count_ints(Term, Count).
Count = 0.
Which, unfortunately, can at best be considered covering only 50% of the possible cases...
Tighter constraints
As Boris correctly points out in the comments, we can make the code even stricter by constraining the argument of i/1 terms to integers. For example, we can write:
count_ints(i(I), 1) :- I in inf..sup.
count_ints(other(_), 0).
Now, the argument must be an integer, which becomes clear by queries like:
?- count_ints(X, 1).
X = i(_1820),
_1820 in inf..sup.
?- count_ints(i(any), 1).
ERROR: Type error: `integer' expected, found `any' (an atom)
Note that the example Boris mentioned fails also without such stricter constraints:
?- count_ints(X, 1), X = anything.
false.
Still, it is often useful to add further constraints on arguments, and if you need to reason over integers, CLP(FD) constraints are often a good and general solution to explicitly state type constraints that are otherwise only implicit in your program.
Note that integer/1 did not get the memo:
?- X in inf..sup, integer(X).
false.
This shows that, although X is without a shadow of a doubt constrained to integers in this example, integer(X) still does not succeed. Thus, you cannot use predicates like integer/1 etc. as a reliable detector of types. It is much better to rely on pattern matching and using constraints to increase the generality of your program.
First things first: the documentation of the SWI-Prolog Prolog Unit Tests package is quite good. The different modes are explained in Section 2.2. Writing the test body. The relevant sentence in 2.2.1 is:
Deterministic predicates are predicates that must succeed exactly once and, for well behaved predicates, leave no choicepoints. [emphasis mine]
What is a choice point?
In procedural programming, when you call a function, it can return a value, or a set of values; it can modify state (local or global); whatever it does, it will do it exactly once.
In Prolog, when you evaluate a predicate, a proof tree is searched for solutions. It is possible that there is more than one solution! Say you use between/3 like this:
For x = 1, is x in [0, 1, 2]?
?- between(0, 2, 1).
true.
But you can also ask:
Enumerate all x such that x is in [0, 1, 2].
?- between(0, 2, X).
X = 0 ;
X = 1 ;
X = 2.
After you get the first solution, X = 0, Prolog stops and waits; this means:
The query between(0, 2, X) has at least one solution, X = 0. It might have further solutions; press ; and Prolog will search the proof tree for the next solution.
The choice point is the mark that Prolog puts in the search tree after finding a solution. It will resume the search for the next solution from that mark.
The warning "Test succeeded with choicepoint" means:
The solution Prolog found was the solution the test expected; however, there it leaves behind a choice point, so it is not "well-behaved".
Are choice points a problem?
Choice points you didn't put there on purpose could be a problem. Without going into detail, they can prevent certain optimizations and create inefficiencies. That's kind of OK, but sometimes only the first solution is the solution you (the programmer) intended, and a next solution can be misleading or wrong. Or, famously, after giving you one useful answer, Prolog can go into an infinite loop.
Again, this is fine if you know it: you just never ask for more than one solution when you evaluate this predicate. You can wrap it in once/1, like this:
?- once( between(0, 2, X) ).
or
?- once( count_ints(X, Answer) ).
If someone else uses your code though all bets are off. Succeeding with a choice point can mean anything from "there are other useful solutions" to "no more solutions, this will now fail" to "other solutions, but not the kind you wanted" to "going into an infinite loop now!"
Getting rid of choice points
To the particular example: You have a built-in, integer/1, which will succeed or fail without leaving choice points. So, these two clauses from your original definition of count_ints/2 are mutually exclusive for any value of X:
count_ints(X, Answer) :-
integer(X), ...
count_ints(X, Answer) :-
\+ integer(X), ...
However, Prolog doesn't know that. It only looks at the clause heads and those two are identical:
count_ints(X, Answer) :- ...
count_ints(X, Answer) :- ...
The two heads are identical, Prolog doesn't look any further that the clause head to decide whether the other clause is worth trying, so it tries the second clause even if the first argument is indeed an integer (this is the "choice point" in the warning you get), and invariably fails.
Since you know that the two clauses are mutually exclusive, it is safe to tell Prolog to forget about the other clause. You can use once/1, as show above. You can also cut the remainder of the proof tree when the first argument is indeed an integer:
count_ints(X, 1) :- integer(X), !.
count_ints(_, 0).
The exactly same operational semantics, but maybe easier for the Prolog compiler to optimize:
count_ints(X, Answer) :-
( integer(X)
-> Answer = 1
; Answer = 0
).
... as in the answer by mat. As for using pattern matching, it's all good, but if the X comes from somewhere else, and not from the code you have written yourself, you will still have to make this check at some point. You end up with something like:
variable_tagged(X, T) :-
( integer(X) -> T = i(X)
; float(X) -> T = f(X)
; atom(X) -> T = a(X)
; var(X) -> T = v(X)
% and so on
; T = other(X)
).
At that point you can write your count_ints/2 as suggested by mat, and Prolog will know by looking at the clause heads that your two clauses are mutually exclusive.
I once asked a question that boils down to the same Prolog behaviour and how to deal with it. The answer by mat recommends the same approach. The comment by mat to my comment below the answer is just as important as the answer itself (if you are writing real programs at least).
I have a list of terms as below
[t('L', 76), t('I', 73), t('V', 86), t('E', 69)]
I want to write a predicate in prolog so that it will return the term with minimum second value. i.e. from above list it should return t('E', 69)
Below is what I tried. But this is not working.
minChar(L, Min) :-
setof(t(_, A), member(t(_, A), L), Li),
Li = [Min|_].
Here is the output it gives for above input.
?- minChar([t('L', 76), t('I', 73), t('V', 86), t('E', 69)], Min).
Min = t(_G14650, 69) ;
Min = t(_G14672, 73) ;
Min = t(_G14683, 76) ;
Min = t(_G14661, 86).
As lurker says, predicates can't start with a capital letter, so fix that first.
There are two basic problems here: first off all, the two underscores in your second line refers to different variables, so setof/3 doesn't know that you want the same variable both in the template and in the member/2 call.
Second, setof sorts the result (which is why you can extract the minimum like that), but the way you've constructed the template, it will sort it incorrectly. Sorting in swi-prolog uses the standard order of terms definition, and in your case, you're sorting compound terms of the type t(A, B), where A is an atom and B is a number. This will sort it lexicographically first on A and then on B, which is not what you want, you want to sort on B.
The standard trick here when you want to sort things with a key that isn't identical to the term itself is to extract the key you want, bind it with the (-)/2 functor, and then sort it. So, for your example, this should work:
minChar(L, Min) :-
setof(B-t(A, B), member(t(A, B), L), Li),
Li = [_-Min|_].
Remember here that in Prolog, when you say X - Y, you're not actually doing any subtraction, even though it looks you are. You are simply binding X and Y together using the (-)/2 functor. It only does subtraction if you specifically ask it to, but using some operator that forces arithmetic evaluation (such as =:=, <, > or is, for instance). This is why 1+1 = 2 is false in Prolog, because = is a unification operator, and doesn't do any arithmetic evaluation.
To be clear: you don't have to use - for this, you can use whatever functor you like. But it's traditional to use the minus functor for this kind of thing.
Edit: also, setof/3 will backtrack over any free variables not found in the template, and since the two underscores don't refer to the same free variables, it will backtrack over every possible assignment for the second underscore, and then throw that result away and assign a new free variable for the first underscore. That's why you can backtrack over the result and get a bunch of anonymous variables that you don't know where they came from.
Instead of using a setof which runs in O(n log n) (at least), you can also write a minChar predicate yourself:
minChar([X],X) :-
!.
minChar([t(_,V1)|T],t(A2,V2)) :-
minChar(T,t(A2,V2)),
V2 < V1,
!.
minChar([X|_],X).
Or you could further boost performance, by using an accumulator:
minChar([X|T],Min) :-
minChar(T,X,Min).
minChar([],X,X).
minChar([t(A2,V2)|T],t(_,V1),Min) :-
V2 < V1,
!,
minChar(T,t(A2,V2),Min).
minChar([_|T],X,Min) :-
minChar(T,X,Min).
The code works as follows: first you unify the list as [X|T], (evidently there must be at least one items, otherwise there is no minimum). Now you take X as the first minimum. You iterate over the list, and at each time you compare t(A2,V2) (the new head of the list), with t(A1,V1) (the currently found minimum). If the second attribute V2 is less than V1, we know we have found a new minimum, and we continue our search with that term. Otherwise, the quest is continued with the old current minimum. If we reach the end of the list, we simply return the current minimum.
Another performance hack, is placing the empty list case as the last one, and place the the current minimum is the smallest case first:
minChar([t(_,V2)|T],t(A1,V1),Min) :-
V1 <= V2,
!,
minChar(T,t(A1,V1),Min).
minChar([X|T],_,Min) :-
minChar(T,X,Min).
minChar([],X,X).
This because Prolog always first executes the predicates in the order defined. It will occur only once that you reach the empty list case (at the end of the list). And after a will, the odds of finding a smaller value will be reduced significantly.
You are a beginner in Prolog, so try to think Prolog.
What is the minimum of a list ? An element of this list, and no other element of this list is smaller.
So you can write
my_min(L, Min) :-
member(Min, L),
\+((member(X, L), X < Min)).
One will say : "it's not efficient !". Yes, but I think it's a good way to learn Prolog.
You should adapt this code to your case.
EDIT I said adapt :
min_of_list(L, t(X,Y)) :-
member(t(X, Y), L),
\+((member(t(_, Z), L), Z < Y)).
I am stumped by this practice problem (not for marks):
{w is an element of {a,b}* : the number of a's is even and the number of b's is even }
I can't seem to figure this one out.
In this case 0 is considered even.
A few acceptable strings: {}, {aa}, {bb}, {aabb}, {abab}, {bbaa}, {babaabba}, and so on
I've done similar examples where the a's must be a prefix, where the answer would be:
(aa)(bb)
but in this case they can be in any order.
Kleene stars (*), unions (U), intersects (&), and concatenation may be used.
Edit: Also have trouble with this one
{w is an element of {0,1}* : w = 1^r 0 1^s 0 for some r,s >= 1}
This is kind of ugly, but it should work:
ε U ( (aa) U (bb) U ((ab) U (ba) (ab) U (ba)) )*
For the second one:
11*011*0
Generally I would use a+ instead of aa* here.
Edit: Undeleted re: the comments in NullUserException's answer.
1) I personally think this one is easier to conceptualize if you first construct a DFA that can accept the strings. I haven't written it down, but off the top of my head I think you can do this with 4 states and one accept state. From there you can create an equivalent regex by removing states one at a time using an algorithm such as this one. This is possible because DFAs and regexes are provably equivalent.
2) Consider the fact that the Kleene star only applies to the nearest regular expression. Hence, if you have two individual ungrouped atoms (an atom itself is a regex!), it only applies to the second one (as in, ab* would match a single a and then any number - including 0 - b's). You can use this to your advantage in a case where you want something to exist, but you're not sure of how many there are.