Sunday, December 27, 2009

Logic Programming with Prolog (contd...)


Prolog code for Water-Jug Problem


Problem: You are given two jugs, a 4-gallon one and 3-gallon one. Neither has any measuring marks on it. There is a pump that can be used to fill the jugs with water. How can you get exactly 2 gallons of water into the 4-gallon jug?

Predicates
jug(integer,integer)
Clauses
jug(0,0):-write("\nFill 3g jug."),jug(0,3).
jug(0,3):-write("\nPour water from 3g jug to 4g jug."),jug(3,0).
jug(3,0):-write("\nFill 3g jug."),jug(3,3).
jug(3,3):-write("\nPour water from 3g jug to 4g jug until 4g jug is full."),jug(4,2).
jug(4,2):-write("\nEmpty 4g jug."),jug(0,2).
jug(0,2):-write("Pour water from 3g jug to 4g jug."),jug(2,0).
jug(2,0):-write("Goal state.").

jug(X,Y):-X>4,not(Y>3),write("\n4g jug overflowed."),not(jug(2,0)).
jug(X,Y):-not(X>4),Y>3,write("\n3g jug is overflowed."),not(jug(2,0)).
jug(X,Y):-X>4,Y>3,write("\nBoth jugs overflowed."),not(jug(2,0)).

jug(0,0):-write("\nFill 4g jug."),jug(4,0).
jug(4,0):-write("\nPour water from 4g to 3g jug."),jug(1,3).
jug(1,3):-write("\nEmpty 3g jug."),jug(1,0).
jug(1,0):-write("\nPour water from 4g to 3g jug."),jug(0,1).
jug(0,1):-write("\nFill 4g jug."),jug(4,1).
jug(4,1):-write("\nPour water from 4g jug to 3g jug until 3g jug is full."),jug(2,3).
jug(2,3):-write("\nEmpty 3g jug."),jug(2,0).
jug(2,0):-write("\nGoal State.").




Prolog code for Monkey-Banana Problem.


Problem: A hungry monkey finds himself in a room in which a bunch of bananas is hanging from the ceiling. The monkey, unfortunately cannot reach the bananas. However, in the room there are also a chair and a stick. The ceiling is just the right height so that a monkey standing on a chair could knock the bananas down with the stick. The monkey knows how to move around, carry other things around, reach for the bananas, and wave a stick in the air. What is the best sequence of actions for the monkey to take to acquire the lunch?

Domains
X,Y,Z = symbol
Predicates
in_room(symbol)
dexterous(symbol)
tall(symbol)
close(symbol,symbol)
under(symbol,symbol)
can_move(symbol,symbol,symbol)
get_on(symbol,symbol)
can_climb(symbol,symbol)
can_reach(symbol,symbol)
Clauses
in_room("monkey").
in_room("chair").
in_room("banana").
dexterous("monkey").
tall("chair").
can_move("monkey","chair","banana").
can_climb("monkey","chair").
can_reach(X,Y):-dexterous(X),close(X,Y).
close(X,"banana"):-get_on(X,Y),under(Y,"banana"),tall(Y).
close(Y,"floor"):-in_room(X),in_room(Y),in_room(Z),can_move(X,Y,Z).
close(_,_):-not(close("banana","floor")).
under("chair","banana").
under(Y,Z):-in_room(Y),in_room(Z),under(Y,Z).
get_on(X,Y):-can_climb(X,Y).

Thursday, November 5, 2009

Logic Programming with Prolog (contd...)


Prolog code to convert decimal number into its binary equivalent.



Domains
N = integer
Predicates
convert(N)
Clauses
convert(0).
convert(N):- R = (N mod 2),
N1 = (N div 2),
convert(N1),
write(R).




Prolog code to take input from user at runtime.



Domains
N,R = integer
Predicates
fact(integer,integer)
run
Clauses
run:- write("Enter a positive number :"),
readint(N),
fact(N,R),
write("Factorial of ",N," is ",R);
fact(1,1).
fact(N,R):- N1 = N-1,
fact(N1,R1),
R = R1*N.




Tower of Hanoi Problem



Domains
N = integer
Predicates
toh(integer,char,char,char)
Clauses
toh(1,X,Y,_):-write("Move disk from "),
write(X),
write(" to "),
write(Y),nl.
toh(N,X,Z,Y):-N>1,
M=N-1,
toh(M,X,Y,Z),
toh(1,X,Z,Y),
toh(M,Y,Z,X).

Tuesday, October 6, 2009

Logic Programming with Prolog


To find sum of n natural numbers



Domains
N,R = integer
Predicates
sum(integer,integer)
Clauses
sum(1,1).
sum(N,R):-N>1,
N1=N-1,
sum(N1,R1),
R=R1+N.




To find factorial of a number



Domains
N,F = integer
Predicates
fact(integer,integer)
Clauses
fact(0,1).
fact(N,F):-N>0,
N1=N-1,
fact(N1,F1),
F=F1*N.




To calculate y=x^n.



Domains
X,N,Y=integer
Predicates
expo(integer,integer,integer)
Clauses
expo(X,0,1).
expo(X,N,Y):-N>0,
N1=N-1,
expo(X,N1,Y1),
Y=Y1*X.




To find maximum of two numbers



Domains
N = real
Predicates
max(real,real,real)
Clauses
max(X,X,X).
max(X,Y,X):-X>Y.
max(X,Y,Y):-Y>X.




To calculate the sum of digits of a number



Domains
N,S=integer
Predicates
sum_digits(integer,integer)
Clauses
sum_digits(0,0).
sum_digits(N,S):-N>0,
R=N mod 10,
N1=N div 10,
sum_digits(N1,S1),
S=S1+R.




To find length of a list



Domains
slist = symbol*
clist = char*
ilist = integer*
rlist = real*
Predicates
length(slist,integer)
length(clist,integer)
length(ilist,integer)
length(rlist,integer)
Clauses
length([],0).
length([H|T],N):-
length(T,N1),
N=1+N1.




To check for an element to be a member of the list.



Domains
slist = symbol*
clist = char*
ilist = integer*
rlist = real*
Predicates
member(symbol,slist)
member(char,clist)
member(integer,ilist)
member(real,rlist)
Clauses
member(X,[X|_]).
member(X,[_|Tail]):-member(X,Tail).




To print first and last element of a list.



Domains
slist=symbol*
ilist=integer*
clist=char*
rlist=real*
Predicates
fele(slist,symbol).
fele(clist,char).
fele(ilist,integer).
fele(rlist,real).
lele(slist,symbol).
lele(clist,char).
lele(ilist,integer).
lele(rlist,real).
Clauses
fele([H|_],H):-write(H," is the first element\n").
lele([X],X):-write(X," is the last element \n").
lele([_|T],X):-lele(T,X).




Append a list to a given list.



Domains
slist=symbol*
ilist=integer*
clist=char*
rlist=real*
Predicates
append(slist,slist,slist)
append(ilist,ilist,ilist)
append(clist,clist,clist)
append(rlist,rlist,rlist)
Clauses
append([],L,L).
append([H|Tail1],List2,[H|Tail3]):-
append(Tail1,List2,Tail3).




To print maximum of a list.



Domains
rlist = real*
Predicates
max(rlist,real).
maxlist(real,real,real).
Clauses
maxlist(H,S,X):-H>=S,X=H,!.
maxlist(_,S,X):-X=S.
max([H],H).
max([H|T],X):-max(T,S),
maxlist(H,S,X).




To delete nth element from the list



Domains
slist=symbol*
ilist=integer*
clist=char*
rlist=real*
Predicates
deleten(slist,integer,slist)
deleten(ilist,integer,ilist)
deleten(clist,integer,clist)
deleten(rlist,integer,rlist)
Clauses
deleten(L,0,L).
deleten([_|T],1,T).
deleten([H|T],N,[H|T1]):-
N1=N-1,
deleten(T,N1,T1).




To insert an element in the list



Domains
slist=symbol*
ilist=integer*
clist=char*
rlist=real*
Predicates
insertn(slist,symbol,integer,slist)
insertn(ilist,integer,integer,ilist)
insertn(clist,char,integer,clist)
insertn(rlist,real,integer,rlist)
Clauses
insertn(L,X,1,[X|L]).
insertn([H|T],X,N,[H|T1]):-
N1=N-1,
insertn(T,X,N1,T1).




To reverse a given list



Domains
ilist = integer*
Predicates
append(ilist,ilist,ilist)
reverse(ilist,ilist)
Clauses
append([],L,L)
append([H|T1],L2,[H|T3]):-
append(T1,L2,T3).
reverse([],[]).
reverse([X|Xs],Zs):-
reverse(Xs,Ys),
append(Ys,[X],Zs).




To print the union of 2 lists



Domains
ilist=integer*
Predicates
union(ilist,ilist,ilist)
Clauses
union([],L,L).
union([H|T],L2,[H|T3]):-
member(H,L2),
delete(L2,H,L3),
union(T1,L3,T3).
union([H|T],L2,[H|T3]):-
not(member(H,L2)),
union(T1,L2,T3).




To print the intersection of 2 lists



Domains
ilist=integer*
Predicates
intersect(ilist,ilist,ilist)
Clauses
intersect([],[_|_],[]).
intersect([H|T],L2,[H|T3]):-
member(H,L2),
intersect(T1,L3,T3).
intersect([H|T],L2,T3):-
not(member(H,L2)),
intersect(T1,L2,T3).




To check whether list1 is a subset of list2 or not



Domains
slist=symbol*
ilist=integer*
clist=char*
rlist=real*
Predicates
subset(slist,slist)
subset(clist,clist)
subset(ilist,ilist)
subset(rlist,rlist)
Clauses
subset([],[_|_]).
subset([H|Tail],L):-member(H,L),
subset(Tail,L).




To split a list into 2 lists such that one contains all the even numbers and other odd



Domains
ilist = integer*
Predicates
split(ilist,ilist,ilist)
Clauses
split([],[],[]).
split([H|T],[H|T1],T2):-
(H mod 2)=0,
split(T,T1,T2).
split([H|T],T1,[H|T2]):-
(H mod 2)<>0,
split(T,T1,T2).




To split a list into 2 lists such that one contains all the smaller numbers than a given number and other greater.



Domains
rlist = real*
Predicates
split(rlist,real,rlist,rlist)
Clauses
split([],_,[],[]).
split([H|T],X,[H|T1],T2):-H<=X,
split(T,X,T1,T2).
split([H|T],X,T1,[H|T2]):-H>X,
split(T,X,T1,T2).




To merge two ordered lists to form 1 ordered list.



Domains
slist = symbol*
clist = char*
ilist = integer*
rlist = real*
Predicates
merge(slist,slist,slist)
merge(clist,clist,clist)
merge(ilist,ilist,ilist)
merge(rlist,rlist,rlist)
Clauses
merge([],[],[]).
merge(L,[],L).
merge([],L,L).
merge([H1|T1],[H2|T2],[H1|T]):-H1<=H2,
merge(T1,[H2|T2],T).
merge([H1|T1],[H2|T2],[H2|T]):-H1>H2,
merge([H1|T1],T2,T).

Monday, August 17, 2009

Creating Invisible Magic Folder in Windows

This is amazing. It tells you how to create an invisible magic folder in Windows that is almost invisible to the other users and it is slways shown empty and hidden whatsoever you keep in it.

Step 1.
Right Click and make a New Folder anywhere you want to create your invisbile magic folder.

Step 2.
Right Click on that folder and goto its Properties window.




Step 3.

In the properties window, Goto Customize. Click on the "Change Icon" button. A small window will open where you ususally change the icons. There you will notice that there are some blank spaces somewhere in between. Actually they are not blank, they are those icons which we use to create our invisible magic folder. Select any of the them and click OK to close the window. Click OK again to close and apply the properties of the new folder.




Step 4.

You'll notice that the folder's icon is vanished. Click over it and press F2, that is shortcut to Rename. Turn on the NumLock key on your keyboard, and press Alt + 0160 (on the numpad) and press enter.



Step 5.

You can set some adavnced properties like encryption to encrypt the contents of the folder. For that, Right Click on the folder and goto its Properties window. In the Attributes section, click on the "Advanced.." button. Advanced Attributes window will appear. In the last section, tick the "Encrypt contents to secure data" and click OK to close the window.



Click OK again by selecting "Apply to this folder, subfolders and files". Click OK again to close and apply the changes to the folder.



Its simple how you create the invisible magic folder.
I hope you enjoyed this tutorial and you would like to use it to keep those documents and files that you donot want to fall into wrong hands.

Friday, March 20, 2009

Can RC4 be used in either CBC or ECB mode?

An explanation of what CBC and ECB modes are.
These modes only apply to block ciphers, as they are designed to function using each block output. Block ciphers encrypt plaintext in blocks of a predefined size. RC4 (which, btw, is trademarked, so you should legally implement it under the pseduo-name ARCFOUR ) is a stream cipher, meaning that it encrypts each bit/byte individually "on the fly", if you will. Thus these block cipher modes do not direcly apply to stream cipher modes.
However, let's try a bit of creativity, to see if is possible to stretch these concepts to apply to stream ciphers, such as RC4.
ECB (Eletronic CodeBook) is just a fancy terminology for saying "this input always maps to that output". Meaning that the output ciphertext of certain input plaintext is always the same, regardless of what ciphertext preceeded it. Stream ciphers generate the keysteam used to XOR by the plaintext bit by bit, with each bit's value relient on it's position in the keystream. In a block cipher ECB mode, the same input block maps to the same output block every single time regardless of it's location. In a stream cipher, by definition, the same plaintext in different locations will be encrypted differently, because (by definition) a stream cipher generates keystream values critical to the position of the plaintext. Thus, one could argue that it is impossible to relate ECB to stream ciphers, based on the very principle that stream ciphers rely on.
Now consider CBC (Cipher Block Chaining) mode. In CBC mode, each block of input plaintext is first XOR'd by the previous output block of ciphertext before being encrypted. Thus, the plaintext for block, say, 5 is XOR'd by the output ciphertext of block 4, and the result is then encrypted. This idea works for a stream cipher, consider the following:
A stream cipher generates what is called a "keystream" of values, each of which is used once to encrypt one value of the plaintext, meaning that there are as many keystream values generated as there are plaintext values. As each byte of the keystream is generated, it is XOR'd by the corresponding byte in the plaintext.
So, to apply CBC mode to a stream cipher you first XOR the plaintext byte by the output ciphertext byte that preceeded it, then XOR it by the keystream byte. Or you could do it in blocks, and XOR a block of plaintext by a similarly-sized block of ciphertext from the plaintext block just before it.
Although there is no inherient need to apply CBC mode to RC4, it is possible to do, and you lose nothing by doing it.