Related
Let L1, L2 be languages such that L2 is not the empty language.
Prove that if the empty word epsilon in L1, then L2 is a subset of L2•L1.
Assume towards a contradiction that L2 ⊈ L2•L1.
Thus, the language L1 contains words that are not the empty word, otherwise we could take ϵ and concatenate it to every word in L_2.
So ϵ ∉ L1 which is a contradiction.
Is that a good proof?
Thanks!
It looks fine. Have another one:
(1) ɛ•ω=ω•ɛ=ω for ∀ω∊L2;
(2) From (1) → ω∊L2•{ɛ} for ∀ω∊L2;
(3) From (2) and ɛ∊L1 → ω∊L2•L1 for ∀ω∊L2;
(4) From (3) and ω=ω for ∀ω∊L2 → L2=L2•L1 for L1={ɛ};
(5) If |L2⋂L2•L1|>0 then L2⊂L2•L1, where |X| is the number of elements in X;
(6) From (4) and (5) → L2⊆L2•L1
(5) Means "if new elements are actually created from the concatenation", which can be proven by giving an example of at least one such case:
L1={ɛ,a}
L2={b}
L2•L1={b,ba}
{b}⋂{b,ba}={ba}
|{ba}|=1
Its worth noting that, you can get equality when L1 has more elements than ɛ.
If |L2⋂L2•L1|=0 then L2=L2•L1
For example:
L1={ɛ,a}
L2=a+
L2•L1=L2=a+
How does this bubble sort solution work in Prolog?
bubblesort([], []).
bubblesort([H], [H]).
bubblesort([H|D], R) :-
bubblesort(D, E),
[B|G] = E,
( (H =< B, R = [H|E])
; (H > B, bubblesort([B,H|G], R))
).
Here is an example trace: https://pastebin.com/T0DLsmAV
I understand the the line bubblesort(D,E), is responsible for sorting it down to one element, but I don't understand how this works. I understand the basics of lists in prolog, but still cannot work out how this solution operates.
The main difficulty with this code is that bad variable names were chosen and are making the logic harder to follow than it needs to be.
The first two cases are obviously base cases. The first says "the empty list is already sorted" and the second says "a singleton list is already sorted." This should make sense. The third case is where things get interesting.
Let's examine the first part.
bubblesort([H|D], R) :-
bubblesort(D, E),
All that's happened so far is we've named our result R and broken our inputs into a first element H and a tail D. From there, we have said, let's bubblesort the tail of our input and call that E. Maybe this would be a little easier to follow?
bubblesort([H|T], Result) :-
bubblesort(T, TSorted),
Next up,
[B|G] = E,
Again, bad names, but what the author is intending to do here is straightforward: take apart the result of sorting the tail so we can talk about whether the next item in the sorted tail is the right element for that position, or if it needs to switch places with the head of our input. Let's rename:
[HeadOfTSorted|RestOfTSorted] = TSorted,
Now we have a condition. Think of it in terms of prepending onto a sorted list. Say you have some element, like 3, and I hand you a sorted list. You want to determine if your 3 goes at the front or somewhere else. Well, suppose I gave you a sorted list that looked like [5,7,19,23,...]. You'd know that your 3 is right where it needs to be, and you'd hand back [3,5,7,19,23,...]. That's exactly the first case of the condition:
( (H =< HeadOfTSorted, Result = [H|TSorted])
Now consider another case, where I hand you a list that starts with [1,2,...]. You know you can't just put the three at the start and give me back [3,1,2,...]. But you don't really know where the 3 goes; it just doesn't go at the start. So what you have to do is resort the rest of the list with the 3 at the start, after the 1: [1 | resorted([3,2,...])]. That's effectively the other branch of the condition:
; (H > HeadOfTSorted, bubblesort([HeadOfTSorted,H|RestOfTSorted], R))
).
Hope this helps!
note: the key to recursive problem solving is exactly not to think about the minutiae of our code's operations. Imagine you already have the solution, then just use it to solve a smaller subproblem, thus arriving at the full problem's solution.
Your code, with more suggestive variable names so I could follow it, reads:
bubblesort([], []). % empty list is already sorted
bubblesort([H], [H]). % singleton list is already sorted
bubblesort([H|T], S) :- % `[H|T]` sorted is `S`, *if*
bubblesort(T, [M|R]), % `T` sorted is `[M|R]`, *and*
( % *either*,
H =< M, % in case `H` is not greater than `M`,
S = [H,M|R] % `S` is `[H,M|R]`,
; % *or*
H > M, % in case `H` is greater than `M`,
bubblesort([M,H|R], S) % `S` is `[M,H|R]` sorted by the same algorithm
).
(H is for "head", T is for "tail", S is "sorted", R "rest" and M is "minimum" -- see below for that).
We prove its correctness by structural induction. The induction hypothesis (IH) is that this definition is correct for shorter lists. We need to prove it is then also correct for a longer list. Indeed T is one-element shorter than [H|T]. Thus IH says [M|R] is sorted. This means M is the minimum element in T. It also means T is non-empty (sorting doesn't change the number of elements), so the clauses are indeed mutually-exclusive.
If H is not larger than the minimum element in T, [H,M|R] is obviously sorted.
Otherwise, we sort [M,H|R]. M is the minimum element and thus guaranteed to be the first in the result. What's actually sorted is [H|R], which is one element shorter, thus by IH sorting it works. QED.
If the last step sounds fishy to you, consider replacing the second alternative with the equivalent
; H > M, % in case `H` is greater then `M`,
bubblesort([H|R], S1), % `S1` is `[H|R]` sorted by the same algorithm
S = [M|S1]
).
where the applicability of the induction step is even clearer.
I'm not so sure it's a bubble sort though.
update: Indeed, measuring the empirical orders of growth, its number of inferences grows as ~ n3 (or slower), but true bubble sort clocked at ~ n2.1 (close enough to the theoretical ~ n2), where n is the list's length:
tbs([], []). % 'true' bubble sort
tbs([H],[H]).
tbs(L,S):- bubble(L,B),
( L==B -> S=L ; tbs(B,S) ).
bubble([],[]).
bubble([A],[A]).
bubble([A,B|C],R):-
( A =< B -> bubble([B|C],X), R=[A|X]
; bubble([A|C],X), R=[B|X] ).
I am working on homework and the problem is where we get 2 int lists of the same size, and then add the numbers together. Example as follows.
vecadd [1;2;3] [4;5;6];; would return [5;7;9]
I am new to this and I need to keep my code pretty simple so I can learn from it. I have this so far. (Not working)
let rec vecadd L K =
if L <> [] then vecadd ((L.Head+K.Head)::L) K else [];;
I essentially want to just replace the first list (L) with the added numbers. Also I have tried to code it a different way using the match cases.
let rec vecadd L K =
match L with
|[]->[]
|h::[]-> L
|h::t -> vecadd ((h+K.Head)::[]) K
Neither of them are working and I would appreciate any help I can get.
First, your idea about modifying the first list instead of returning a new one is misguided. Mutation (i.e. modifying data in place) is the number one reason for bugs today (used to be goto, but that's been banned for a long time now). Making every operation produce a new datum rather than modify existing ones is much, much safer. And in some cases it may be even more performant, quite counterintuitively (see below).
Second, the way you're trying to do it, you're not doing what you think you're doing. The double-colon doesn't mean "modify the first item". It means "attach an item in front". For example:
let a = [1; 2; 3]
let b = 4 :: a // b = [4; 1; 2; 3]
let c = 5 :: b // c = [5; 4; 1; 2; 3]
That's how lists are actually built: you start with a empty list and prepend items to it. The [1; 2; 3] syntax you're using is just a syntactic sugar for that. That is, [1; 2; 3] === 1::2::3::[].
So how do I modify a list, you ask? The answer is, you don't! F# lists are immutable data structures. Once you've created a list, you can't modify it.
This immutability allows for an interesting optimization. Take another look at the example I posted above, the one with three lists a, b, and c. How many cells of memory do you think these three lists occupy? The first list has 3 items, second - 4, and third - 5, so the total amount of memory taken must be 12, right? Wrong! The total amount of memory taken up by these three lists is actually just 5 cells. This is because list b is not a block of memory of length 4, but rather just the number 4 paired with a pointer to the list a. The number 4 is called "head" of the list, and the pointer is called its "tail". Similarly, the list c consists of one number 5 (its "head") and a pointer to list b, which is its "tail".
If lists were not immutable, one couldn't organize them like this: what if somebody modifies my tail? Lists would have to be copied every time (google "defensive copy").
So the only way to do with lists is to return a new one. What you're trying to do can be described like this: if the input lists are empty, the result is an empty list; otherwise, the result is the sum of tails prepended with the sum of heads. You can write this down in F# almost verbatim:
let rec add a b =
match a, b with
| [], [] -> [] // sum of two empty lists is an empty list
| a::atail, b::btail -> (a + b) :: (add atail btail) // sum of non-empty lists is sum of their tails prepended with sum of their heads
Note that this program is incomplete: it doesn't specify what the result should be when one input is empty and the other is not. The compiler will generate a warning about this. I'll leave the solution as an exercise for the reader.
You can map over both lists together with List.map2 (see the docs)
It goes over both lists pairwise and you can give it a function (the first parameter of List.map2) to apply to every pair of elements from the lists. And that generates the new list.
let a = [1;2;3]
let b = [4;5;6]
let vecadd = List.map2 (+)
let result = vecadd a b
printfn "%A" result
And if you want't to do more work 'yourself' something like this?
let a = [1;2;3]
let b = [4;5;6]
let vecadd l1 l2 =
let rec step l1 l2 acc =
match l1, l2 with
| [], [] -> acc
| [], _ | _, [] -> failwithf "one list is bigger than the other"
| h1 :: t1, h2 :: t2 -> step t1 t2 (List.append acc [(h1 + h2)])
step l1 l2 []
let result = vecadd a b
printfn "%A" result
The step function is a recursive function that takes two lists and an accumulator to carry the result.
In the last match statement it does three things
Sum the head of both lists
Add the result to the accumulator
Recursively call itself with the new accumulator and the tails of the lists
The first match returns the accumulator when the remaining lists are empty
The second match returns an error when one of the lists is longer than the other.
The accumulator is returned as the result when the remaining lists are empty.
The call step l1 l2 [] kicks it off with the two supplied lists and an empty accumulator.
I have done this for crossing two lists (multiply items with same index together):
let items = [1I..50_000I]
let another = [1I..50_000I]
let rec cross a b =
let rec cross_internal = function
| r, [], [] -> r
| r, [], t -> r#t
| r, t, [] -> r#t
| r, head::t1, head2::t2 -> cross_internal(r#[head*head2], t1, t2)
cross_internal([], a, b)
let result = cross items another
result |> printf "%A,"
Note: not really performant. There are list object creations at each step which is horrible. Ideally the inner function cross_internal must create a mutable list and keep updating it.
Note2: my ranges were larger initially and using bigint (hence the I suffix in 50_000) but then reduced the sample code above to just 50,500 elements.
I just can't understand how this algorithm works. All the explanations I've seen say that if you have a set such as {A, B, C} and you want all the permutations, start with each letter distinctly, then find the permutations of the rest of the letters. So for example {A} + permutationsOf({B,C}).
But all the explanations seem to gloss over how you find the permutations of the rest. An example being this one.
Could someone try to explain this algorithm a little more clearly to me?
To understand recursion you need to understand recursion..
(c) Programmer's wisdom
Your question is about that fact, that "permutations of the rest" is that recursive part. Recursion always consist of two parts: trivial case and recursion case. Trivial case points to a case when there's no continue for recursion and something should be returned.
In your sample, trivial part would be {A} - there's only one permutation of this set - itself. Recursion part will be union of current element and this "rest part" - i.e. if you have more than one element, then your result will be union of permutation between this element and "rest part". In terms of permutation: the rest part is current set without selected element. I.e. for set {A,B,C} on first recursion step that will be {A} and "rest part": {B,C}, then {B} and "rest part": {A,C} - and, finally, {C} with "rest part": {A,B}
So your recursion will last till the moment when "the rest part" will be single element - and then it will end.
That is the whole point of recursive implementation. You define the solution recursively assuming you already have the solution for the simpler problem. With a little tought you will come to the conclusion that you can do the very same consideration for the simpler case making it even more simple. Going on until you reach a case that is simple enough to solve. This simple enough case is known as bottom for the recursion.
Also please note that you have to iterate over all letters not just A being the first element. Thus you get all permutations as:
{{A} + permutationsOf({B,C})} +{{B} + permutationsOf({A,C})} + {{C} + permutationsOf({A,B})}
Take a minute and try to write down all the permutations of a set of four letters say {A, B, C, D}. You will find that the algorithm you use is close to the recursion above.
The answer to your question is in the halting-criterion (in this case !inputString.length).
http://jsfiddle.net/mzPpa/
function permutate(inputString, outputString) {
if (!inputString.length) console.log(outputString);
else for (var i = 0; i < inputString.length; ++i) {
permutate(inputString.substring(0, i) +
inputString.substring(i + 1),
outputString + inputString[i]);
}
}
var inputString = "abcd";
var outputString = "";
permutate(inputString, outputString);
So, let's analyze the example {A, B, C}.
First, you want to take single element out of it, and get the rest. So you would need to write some function that would return a list of pairs:
pairs = [ (A, {B, C})
(B, {A, C})
(C, {A, B}) ]
for each of these pairs, you get a separate list of permutations that can be made out of it, like that:
for pair in pairs do
head <- pair.fst // e.g. for the first pair it will be A
tails <- perms(pair.snd) // e.g. tails will be a list of permutations computed from {B, C}
You need to attach the head to each tail from tails to get a complete permutation. So the complete loop will be:
permutations <- []
for pair in pairs do
head <- pair.fst // e.g. for the first pair it will be A
tails <- perms(pair.snd) // e.g. tails will be a list of permutations computed from {B, C}
for tail in tails do
permutations.add(head :: tail); // here we create a complete permutation
head :: tail means that we attach one element head to the beginning of the list tail.
Well now, how to implement perms function used in the fragment tails <- perm(pair.snd). We just did! That's what recursion is all about. :)
We still need a base case, so:
perms({X}) = [ {X} ] // return a list of one possible permutation
And the function for all other cases looks like that:
perms({X...}) =
permutations <- []
pairs <- createPairs({X...})
for pair in pairs do
head <- pair.fst // e.g. for the first pair it will be A
tails <- perms(pair.snd) // e.g. tails will be a list of permutations computed from {B, C}
for tail in tails do
permutations.add( head :: tail ); // here we create a complete permutation
return permutations
I am studying Prolog and I could not follow the lessons so I have some doubts relating to a particular use of the maplist built in SWI Prolog predicate.
So let me explain my situation:
I have a personal predicate named addavl(Tree/Height, Element, NewTree/Height) that insert the element Element into the AVL tree Tree (where Height is the height of this original tree) and generate a new AVL tree named NewTree that contains Element and that have a new height Height
Now I have a list of elements and I would add these elements to an AVL tree (that at the beginning is void), so I have the following predicate (that work fine).
I have some doubts related to the use of maplist/4 SWI Prolog built in predicate and I would also know if my general interpretation of all this predicate is correct or if am I missing something.
/* Predicate that from a given list of elements build an AVL Tree: */
buildTree(List,Tree):-
length(List, N), % N: the number of element in List
/* Create L1 as a list that have the same number of element of List
For example if List have N=4 element L1=[A,B,C,D] where A,B,C,D
are variable that are not yet set
*/
length(L1,N),
/* Se fosse: append(L1,[Tree],NewList) otterrei: NewList=[A,B,C,D|Tree]
ma essendo NewList=[_|L2] so L2=[B,C,D|Tree]
*/
append(L1,[Tree],[_|L2]),
/* Put the couple (nil,0) in the L1 head so I have that A=(nil,0) that
represents an empty AVL tree:
*/
L1=[nil/0 |_],
/* Call addavl passing as parameter the tree in the L1 head, the value
to insert in the List Head and the head of L2 as the current new Tree-
When the variable Tree is reached it represents the final AVL tree
*/
maplist(addavl, L1, List, L2).
My interpretation of the entire predicate is the following one:
First N variable contains the length of the original element list List that I would to insert in the AVL tree
Then is created a new list L1 that have the same number of element of the original list List, but in this case L1 contains variables that are not yet set up with a value.
So for example, if the original element list is:
List = [5, 8, 3, 4] the L1 list will be something like: L1 = [A, B, C, D]
where A, B, C, D are variables that are not yet valorized.
Now there is this statement that must be satisfied:
append(L1,[Tree],[_|L2]),
that I read in this way:
if I had append(L1,[Tree],NewList) instead the previous statement I would have that:
NewList = [A,B,C,D,Tree] where A,B,C,D are the previous not set variable of the L1 List and Tree is a new not set variable.
But in my case I have that NewList = [_|L2] so L2 = [B,C,D,Tree].
Now the meaning of the previous append operation is the creation of the L2 list that at the beginning contains n not valorized variables (in the previous example 4 not valorized variables: B,C,D, Tree).
Each of these variables represents a Tree in which it was inserted a new element in the original list List
So, at the beginning the program put the void AVL tree in the head of this list (in my example in the A variable) by this instruction: L1=[nil/0 |_],
So in the head of the L1 variabile there is the void tree that have 0 as height (and a void tree is a correct AVL Tree)
And now I have the FIRST DOUBT: by the previous operation I have valorized the head variable of the L1 list but previous of this operation I have created the NewList=[_|L2] list using this statement:
append(L1,[Tree],[_|L2])
This means that the _ anonymous variable of [_|L2] list match with nil/0 AVL tree?
This work in this way also if I have valorized the L1 head after that I have create the [_|L2] list appending L1 list to [Tree]?
Ok, if my interpretation is correct go on to my SECOND DOUBT that it is related to how exactly work the maplist SWI Prolog built in predicate..
I have:
maplist(addavl, L1, List, L2).
What exactly do this predicate?
Reading on the official documentation: http://www.swi-prolog.org/pldoc/man?predicate=maplist%2F2
it seems to me that work in the following way:
I have the addavl predicate that is the GOAL that have to be satisfied on each element of the lists
Remembering that addval predicate work in this way: addavl(Tree/Height, Element, NewTree/Height).
So:
1) L1 is the list of the AVL Tree (the first is the void AVL Tree: nil/0)
2) List is the original list that contain the element to insert
3) L2 is the list that contains the AVL tree that I will create.
So I think that now work in the following way:
First take the void AVL Tree (nil/0) from the head of L1, take the first element do add from List, execute the GOAL (insert this element into the void AVL Tree) and put the result in the head of the L2 list (that, according to my previous example, is the B variable, so the B variable contains the AVL Tree that contain the first element of the List element) list**
Then repeat this procedure inserting all the other elements in of the elements list List and finally, the last element of the L2 list (the Tree variable) will represent the final AVL Tree in which all the elements were inserted.
Is my reasoning correct or am I missing something?
in Prolog we say "not yet instantiated variable" or "uninstantited variable".
About L1=[nil/0 |_], we can call it "initializing it with an initial value".
the _ in [_|L2] does indeed match the init value, and we don't care about it.
(this gives an idea of calling append(L1, [Tree], [nil/0 | L2]), instead of the two calls in original code).
Yes, order of operations is not important. X=t(A), A=2 or A=2, X=t(A) both result in the same substitution, A=2, X=t(2).
maplist( pred, ...Lists ...) works so that pred must be satisfied on elements from lists, taken pair-wise (or by columns). E.g. maplist(plus, [1,2,3],[4,X,8],[5,6,Y]).
The lists L1 and L2 both share structure:
nil/0 B C D Tree
------------------
L1
-----------------
L2
maplist sees them, and processes them, by feeding them by columns to addavl:
nil/0 B C D % L1
E1 E2 E3 E4 % List
B C D Tree % L2
so yes, it does it like you say.
I don't think your teacher will accept this as an answer. You should write a direct recursive solution instead. Both variants describe same iterative computational process of progressively adding elements into a tree, using the output of previous call as input to the next. But in any given implementation one can be optimized far better than the other. Using lists, here, will most probably be less efficient than a recursive variant.