Prolog在Matrix上使用findall / 3

时间:2016-04-05 15:04:58

标签: matrix prolog prolog-findall

我的SWI序言中有以下矩阵;

 matrix(1,[  [*,*,*,*,*,*,*,*,*,*,*,*],
        [*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],
        [*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],
        [*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],
        [*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],
        [*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],
        [*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],
        [*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],
        [*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],
        [*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*]
        [*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],
        [*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]]).

我想使用findall / 3谓词,这样我就可以获得所有现场(X,Y)事实的列表,例如>>>

 findall(spots(X,Y),matrix(1,Map),X). 

哪个应该返回如下内容;

 X = (spots(2,4), spots(2,5), spots(2,10), spots(2,11), spots(3,4) etc .... spots(12,10)). 

但是,由于矩阵由列表中的列表组成,我对如何实现这一点感到很困惑。如果有人能够向我显示已配置的谓词以获得所述的列表,我将不胜感激。

感谢您的帮助!!! - 非常感谢!

编辑 - 也许可以使用下面找到的代码,无法看到我如何将其实现为第二个findall / 3语句。真的卡住了所以感谢任何帮助。

at(Mat, Row, Col, Val) :- nth1(Row, Mat, ARow), nth1(Col, ARow, Val).

1 个答案:

答案 0 :(得分:3)

只需考虑谓词应该描述的内容:您希望在列表中找到<?php //mysql_ $connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname); if(mysqli_connect_errno()) { die("Database connection failed: " . mysqli_connect_error() . " (" . mysqli_connect_errno() . ")"); } $result = ""; //collect info from database if(isset($_POST['search'])) { $searchq = $_POST['search']; $searchq = preg_replace("#[^0-9a-z]#i", "", $searchq); //echo $searchq; //SQL query $query = "SELECT institute_id, name FROM institutes WHERE category1 LIKE '%$searchq%' OR category2 LIKE '%$searchq%' OR category3 LIKE '%$searchq%' OR category4 LIKE '%$searchq%'"; $result = mysqli_query($connection, $query); // Test if there was a query failure if(!$result){ die("Database query failed."); } $count = mysqli_num_rows($result); if($count == 0) { $output = "There's no search result"; } else { while($row = mysqli_fetch_assoc($result)) { $id = $row["institute_id"]; ?> <li> <h3> <a href="institute_profile_test.php?id=<?php echo $id; ?>"><?php echo $row["name"];?> </a> </h3> </li> <div class = "rating">Rating: x/5</div> <?php } } } ?> 形式的所有术语,否则这些列表将包含原子spots(_,_)

*

现在,您可以查询矩阵的所有位置:

:- use_module(library(lists)).

matrix_spots([],[]).                % no spots in the empty matrix
matrix_spots([R|Rs],S) :-
    row_spots(R,RSs),               % RSs ... spots in row R
    matrix_spots(Rs,S1),            % S1 ... spots in the remaining rows
    append(RSs,S1,S).               % S ... RSs followed by S1

row_spots([],[]).                   % no spots in an empty row
row_spots([E|Es],[E|RSs]) :-        % E is in the list of spots
    E=spots(_,_),                   % if it is a spot
    row_spots(Es,RSs).              % RSs ... spots in rest of row
row_spots([*|Es],RSs) :-            % * is not in the list of spots
    row_spots(Es,RSs).              % Rss ... spots in rest of row

请注意,示例矩阵中有拼写错误:在第10个列表的末尾,缺少逗号: ?- matrix(1,M), matrix_spots(M,S). M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]], S = [spots(2,4),spots(2,5),spots(2,10),spots(2,11),spots(3,4),spots(3,5),spots(3,6),spots(3,7),spots(3,10),spots(3,11),spots(4,3),spots(4,4),spots(4,6),spots(4,7),spots(4,8),spots(4,9),spots(4,11),spots(4,12),spots(5,2),spots(5,3),spots(5,4),spots(5,5),spots(5,8),spots(5,9),spots(5,11),spots(5,12),spots(6,2),spots(6,3),spots(6,5),spots(6,6),spots(6,7),spots(6,8),spots(6,10),spots(6,11),spots(6,12),spots(7,3),spots(7,4),spots(7,6),spots(7,7),spots(7,8),spots(7,10),spots(7,11),spots(8,2),spots(8,3),spots(8,4),spots(8,6),spots(8,7),spots(8,8),spots(8,9),spots(8,11),spots(8,12),spots(9,2),spots(9,3),spots(9,5),spots(9,6),spots(9,9),spots(9,10),spots(9,11),spots(9,12),spots(10,2),spots(10,3),spots(10,5),spots(10,6),spots(10,7),spots(10,8),spots(10,10),spots(10,11),spots(11,3),spots(11,4),spots(11,7),spots(11,8),spots(11,9),spots(1ts(12,4),spots(12,9),spots(12,10)] ? ; no

编辑:

以下是@mat在评论中建议的dcg版本。这确实更容易阅读:

...spots(10,11),*],

上述查询可与此dcg版本一对一使用。

关于你的(@ User15388472)在评论中的findall / 3问题:想象一下,你有一个谓词matrix_spot / 2,它匹配matrix_spots(M,S) :- phrase(rows(M),S). rows([]) --> % no spots in the empty matrix []. rows([R|Rs]) --> row(R), % all spots in row R rows(Rs). % all spots in the remaining rows row([]) --> % no spots in an empty row []. row([*|Xs]) --> % no spot at this position in the row row(Xs). % but there might be in the remainder row([spots(A,B)|Xs]) --> % spot at this position [spots(A,B)], % is in the list row(Xs). % and the spots in the rest of the row 形式的一个术语作为第二个参数,而不是所有斑点的列表。该谓词可能看起来像这样:

spots(A,B)

如果您查询此谓词,则一次只能获得一个matrix_spot([R|Rs],S) :- row_spot(R,S). % S is in row R matrix_spot([R|Rs],S) :- % S is not in R but matrix_spot(Rs,S). % in one of the other rows Rs row_spot([spots(A,B)|Xs],spots(A,B)). % head of the list is the spot row_spot([X|Xs],S) :- row_spot(Xs,S). % S is in the tail of the list 作为答案:

spots(A,B)

在这样的场景中,您可以使用findall / 3查找矩阵中的所有术语 ?- matrix(1,M), matrix_spot(M,S). M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]], S = spots(2,4) ? ; M = [[*,*,*,*,*,*,*,*,*,*,*,*],[*,*,*,spots(2,4),spots(2,5),*,*,*,*,spots(2,10),spots(2,11),*],[*,*,*,spots(3,4),spots(3,5),spots(3,6),spots(3,7),*,*,spots(3,10),spots(3,11),*],[*,*,spots(4,3),spots(4,4),*,spots(4,6),spots(4,7),spots(4,8),spots(4,9),*,spots(4,11),spots(4,12)],[*,spots(5,2),spots(5,3),spots(5,4),spots(5,5),*,*,spots(5,8),spots(5,9),*,spots(5,11),spots(5,12)],[*,spots(6,2),spots(6,3),*,spots(6,5),spots(6,6),spots(6,7),spots(6,8),*,spots(6,10),spots(6,11),spots(6,12)],[*,*,spots(7,3),spots(7,4),*,spots(7,6),spots(7,7),spots(7,8),*,spots(7,10),spots(7,11),*],[*,spots(8,2),spots(8,3),spots(8,4),*,spots(8,6),spots(8,7),spots(8,8),spots(8,9),*,spots(8,11),spots(8,12)],[*,spots(9,2),spots(9,3),*,spots(9,5),spots(9,6),*,*,spots(9,9),spots(9,10),spots(9,11),spots(9,12)],[*,spots(10,2),spots(10,3),*,spots(10,5),spots(10,6),spots(10,7),spots(10,8),*,spots(10,10),spots(10,11),*],[*,*,spots(11,3),spots(11,4),*,*,spots(11,7),spots(11,8),spots(11,9),spots(11,10),*,*],[*,*,spots(12,3),spots(12,4),*,*,*,*,spots(12,9),spots(12,10),*,*]], S = spots(2,5) ? ; ...

spots(A,B)