Seven languages in seven weeks (notes on Prolog)

1 篇文章 0 订阅

Prolog:


facts, rules, queries (like SQL)

capitalization: word begin with lowercase character --> atom (fixed value) ;  begin with uppercase letter or underscore --> variable

(swi-prolog in cygwin: open the interpreter with "swipl")

(each line end with ".")

"\+" does logical negation, so \+(X = Y) means X is not equal to Y

a fact, e.g.

likes(wallace, cheese).

a rule, e.g. (a rule with 2 parameters, 3 variables, and 3 subgoals)

friend(X, Y) :- \+(X = Y), likes (X, Z), likes(Y, Z).

load a file and compile,

?- ['friends.pl'].

query

flavor(sweet, What).

when typed the ";", prolog find another one

prolog is not procedural (we have no algorithm), but a declarative language. prolog is not about writing algorithms to solve logical problems. prolog is about describing your world as it is and presenting logical problems that your computer can try to solve.

"unification" means "find the values that make both sides match". "=" means unify, or make both sides the same.

in general, if you can describe the problem, you have solved the problem. you don't have to describe the solution to a problem. you have only to describe the problem.

queries: two forms: 1. the query specifies a fact, and prolog tells yes or no; 2. query with variables, and prolog compute all possibilities that make the facts true.


tail recursion optimization: if position the recursive subgoal at the end of  a recursive rule, prolog can optimize the call to discard  the call stack, keeping memory constant.

ancestor(X, Y) :- father(X, Y).
ancestor(X, Y) :- father(X, Z), ancestor(Z, Y).

list and tuple:

?- [a, b, c] = [Head|Tail].
Head = a
Tail = [b,c]

[Head|Tail] won’t unify with an empty list, but a one-element list is fine. for example, grab the third element:

?- [a, b, c, d, e] = [_, _|[Head|_]].
Head = c

_ is a wildcard and unifies with anything.

math:

count(0, []).
count(Count, [Head|Tail]) :- count(TailCount, Tail), Count is TailCount + 1.
sum(0, []).
sum(Total, [Head|Tail]) :- sum(Sum, Tail), Total is Head + Sum.
average(Average, List) :- sum(Sum, List), count(Count, List), Average is Sum/Count.

list append, concatenate:

concatenate([], List, List).
concatenate([Head|Tail1], List, [Head|Tail2]) :- concatenate(Tail1, List, Tail2).

thus, rules applied in both directions of :-


GNU Prolog has a built-in predicate to express possible values, called fd_domain(List, LowerBound, UpperBound) .  We’ll use a GNU Prolog predicate to test for repeated elements. fd_all_different(List) succeeds if all the elements in List are different.

4x4 Sudoku:

valid([]).
valid([Head|Tail]) :- 
    fd_all_different(Head), 
    valid(Tail).

sudoku(Puzzle, Solution) :-
        Solution = Puzzle,
        Puzzle = [S11, S12, S13, S14, 
                  S21, S22, S23, S24, 
                  S31, S32, S33, S34, 
                  S41, S42, S43, S44], 
                  
        fd_domain(Solution, 1, 4), 
        
        Row1 = [S11, S12, S13, S14],
        Row2 = [S21, S22, S23, S24],
        Row3 = [S31, S32, S33, S34],
        Row4 = [S41, S42, S43, S44],
        
        Col1 = [S11, S21, S31, S41],
        Col2 = [S12, S22, S32, S42],
        Col3 = [S13, S23, S33, S43],
        Col4 = [S14, S24, S34, S44],
        
        Square1 = [S11, S12, S21, S22],
        Square2 = [S13, S14, S23, S24],
        Square3 = [S31, S32, S41, S42],
        Square4 = [S33, S34, S43, S44], 
        
        valid([Row1, Row2, Row3, Row4, 
               Col1, Col2, Col3, Col4, 
               Square1, Square2, Square3, Square4]).

Eight-Queens:

valid_queen((Row, Col)) :- 
    Range = [1,2,3,4,5,6,7,8], 
    member(Row, Range), member(Col, Range).

valid_board([]).
valid_board([Head|Tail]) :- valid_queen(Head), valid_board(Tail). 
    
rows([], []).
rows([(Row, _)|QueensTail], [Row|RowsTail]) :- 
  rows(QueensTail, RowsTail).
  
cols([], []).
cols([(_, Col)|QueensTail], [Col|ColsTail]) :- 
  cols(QueensTail, ColsTail).
  
diags1([], []).
diags1([(Row, Col)|QueensTail], [Diagonal|DiagonalsTail]) :- 
  Diagonal is Col - Row, 
  diags1(QueensTail, DiagonalsTail).

diags2([], []).
diags2([(Row, Col)|QueensTail], [Diagonal|DiagonalsTail]) :- 
  Diagonal is Col + Row, 
  diags2(QueensTail, DiagonalsTail).

eight_queens(Board) :- 
  length(Board, 8),
  valid_board(Board), 

  rows(Board, Rows), 
  cols(Board, Cols), 
  diags1(Board, Diags1), 
  diags2(Board, Diags2), 
  
  fd_all_different(Rows),   
  fd_all_different(Cols), 
  fd_all_different(Diags1),   
  fd_all_different(Diags2).

an optimized 8-queen program:

valid_queen((Row, Col)) :- member(Col, [1,2,3,4,5,6,7,8]).
valid_board([]).
valid_board([Head|Tail]) :- valid_queen(Head), valid_board(Tail). 
    
cols([], []).
cols([(_, Col)|QueensTail], [Col|ColsTail]) :- 
  cols(QueensTail, ColsTail).
  
diags1([], []).
diags1([(Row, Col)|QueensTail], [Diagonal|DiagonalsTail]) :- 
  Diagonal is Col - Row, 
  diags1(QueensTail, DiagonalsTail).
  
  
diags2([], []).
diags2([(Row, Col)|QueensTail], [Diagonal|DiagonalsTail]) :- 
  Diagonal is Col + Row, 
  diags2(QueensTail, DiagonalsTail).

eight_queens(Board) :- 
  Board = [(1, _), (2, _), (3, _), (4, _), (5, _), (6, _), (7, _), (8, _)], 
  valid_board(Board), 

  cols(Board, Cols), 
  diags1(Board, Diags1), 
  diags2(Board, Diags2), 
  fd_all_different(Cols), 
  fd_all_different(Diags1),   
  fd_all_different(Diags2).

prolog programming: step 1, build a knowledge base; step 2, compile the knowledge base and ask questions

rather than simple assignment, prolog uses a process called unification that makes variables on both sides of a system match.




Prolog Tutorials:

http://en.wikipedia.org/wiki/Prolog

http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/contents.html

http://www.lix.polytechnique.fr/~liberti/public/computing/prog/prolog/prolog-tutorial.html

http://kti.mff.cuni.cz/~bartak/prolog/contents.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值