Matrix prolog中的转置矩阵

Matrix prolog中的转置矩阵,matrix,prolog,program-slicing,Matrix,Prolog,Program Slicing,我想在prolog中转置一个矩阵,例如 [1,2,3],[1,2,3],[1,2,3]]应该成为 [1,1,1],[2,2,2],[3,3,3]] 以下是我所做的: %transpose(M,T) transpose([],[]). transpose(M,[H|T]):-row(H,M,M1),transpose(M1,T). %row(H, M, M1). row([],[],[]). row([H|Tt] , [[H|T1]|T] , [T1|Z]) :- row(Tt,T,Z). 其

我想在
prolog
中转置一个矩阵,例如 [1,2,3],[1,2,3],[1,2,3]]应该成为 [1,1,1],[2,2,2],[3,3,3]]

以下是我所做的:

%transpose(M,T)
transpose([],[]).
transpose(M,[H|T]):-row(H,M,M1),transpose(M1,T).

%row(H, M, M1).
row([],[],[]).
row([H|Tt] , [[H|T1]|T] , [T1|Z]) :- row(Tt,T,Z).
其中,
M
将在
T
中转置。 行谓词(不确定谓词和函数之间的差异)获取M中每个子列表的头部,因此我可以获取新的转置矩阵
T
的整个第一行。 我分别测试了行,它给出了正确的结果。但是,当我尝试
转置
时,我只得到'false',什么也没有发生,没有打印新矩阵
T
的信息

有人能帮我吗?问题出在我构建程序的方式上了吗?或者我期望的结果只是
真/假
如果是,如何得到新的矩阵?谢谢:)

Prolog只有谓词,没有函数。谓词定义了一个关系,通常不认为它是“做某事”的“定义某事。您的
行/3
实际上定义了其3个参数之间的关系。这三个参数是相关的,因为第一个和第三个列表的元素是第二个列表的参数的正反两面。我将展示3个不同的查询,以说明:

| ?- row([a,b,c], L, M).

L = [[a|A],[b|B],[c|C]]
M = [A,B,C]

yes
| ?- row(A, [[a,b,c],[d,e,f],[g,h,i]], L).

A = [a,d,g]
L = [[b,c],[e,f],[h,i]] ? ;

no
| ?- row(A, B, [[a,b],[c,d],[e,f]]).

A = [C,D,E]
B = [[C,a,b],[D,c,d],[E,e,f]] ? ;

no
| ?- 
函数不会以这种方式运行。你也可以看到,知道了这种关系,这个名字有点通用<代码>行并不能充分描述这种关系。也许它可以被称为
heads\u and\u tails/3
,也许可以交换第一个和第二个参数

transpose/2
谓词失败的原因是它会递归到一个空列表列表(
[[],[],[]]
对于有3行的矩阵),但是
transpose/2
基本情况是基于
[]


让我们看一下,如注释中所建议的,将
转置([],[])
的基本情况替换为:

transpose([[] | _], []).
以下示例查询结果:

| ?- transpose([[a,b,c],[d,e,f]], T).

T = [[a,d],[b,e],[c,f]] ? ;

no
| ?- transpose([[a,b,c],[d,e,f], [a]], T).

no
| ?- transpose(T, [[a,b,c],[d,e,f]]).

T = [[a,d],[b,e|_],[c,f|_]] ? ;

no
因此,第二个查询的结果不正确。解决此问题的一种方法是,遵循此谓词的逻辑,将基本情况从
转置([],[])
更改为:

transpose(Empty, []) :- maplist(=([]), Empty).
这将产生一个谓词,该谓词将给出以下结果:

| ?- transpose(T, [[a,b,c],[d,e,f]]).

T = [[a,d],[b,e],[c,f]] ? a

no
| ?- transpose([[a,b,c],[d,e,f]], T).

T = [[a,d],[b,e],[c,f]] ? a

no
Prolog只有谓词,没有函数。谓词定义了一个关系,通常不认为它是“做某事”的“定义某事。您的
行/3
实际上定义了其3个参数之间的关系。这三个参数是相关的,因为第一个和第三个列表的元素是第二个列表的参数的正反两面。我将展示3个不同的查询,以说明:

| ?- row([a,b,c], L, M).

L = [[a|A],[b|B],[c|C]]
M = [A,B,C]

yes
| ?- row(A, [[a,b,c],[d,e,f],[g,h,i]], L).

A = [a,d,g]
L = [[b,c],[e,f],[h,i]] ? ;

no
| ?- row(A, B, [[a,b],[c,d],[e,f]]).

A = [C,D,E]
B = [[C,a,b],[D,c,d],[E,e,f]] ? ;

no
| ?- 
函数不会以这种方式运行。你也可以看到,知道了这种关系,这个名字有点通用<代码>行并不能充分描述这种关系。也许它可以被称为
heads\u and\u tails/3
,也许可以交换第一个和第二个参数

transpose/2
谓词失败的原因是它会递归到一个空列表列表(
[[],[],[]]
对于有3行的矩阵),但是
transpose/2
基本情况是基于
[]


让我们看一下,如注释中所建议的,将
转置([],[])
的基本情况替换为:

transpose([[] | _], []).
以下示例查询结果:

| ?- transpose([[a,b,c],[d,e,f]], T).

T = [[a,d],[b,e],[c,f]] ? ;

no
| ?- transpose([[a,b,c],[d,e,f], [a]], T).

no
| ?- transpose(T, [[a,b,c],[d,e,f]]).

T = [[a,d],[b,e|_],[c,f|_]] ? ;

no
因此,第二个查询的结果不正确。解决此问题的一种方法是,遵循此谓词的逻辑,将基本情况从
转置([],[])
更改为:

transpose(Empty, []) :- maplist(=([]), Empty).
这将产生一个谓词,该谓词将给出以下结果:

| ?- transpose(T, [[a,b,c],[d,e,f]]).

T = [[a,d],[b,e],[c,f]] ? a

no
| ?- transpose([[a,b,c],[d,e,f]], T).

T = [[a,d],[b,e],[c,f]] ? a

no

首先,关于术语的注释:函数的一个特征是每个输入只与一个输出相关。另一方面,一个关系可以适用于多个这样的组合。Prolog谓词在它们的参数之间产生关系,回溯时可能出现多个答案

至于你的具体问题,@潜伏者已经给出了一些可靠的建议

然而,正如您已经注意到的,跟踪很快在inProlog中变得非常复杂,因此我想通过解释声明性调试的一些原则来补充潜伏者所写的内容

本质上,我们的目标是使我们的问题更简单,而不是更难。我们从您发布的程序中提到的案例开始:

?- transpose([[1,2,3],[1,2,3],[1,2,3]], Ls). false. 例如,我们可以将
行/3
概括如下:

row([], [], []). row([H|Tt], [[H|T1]|T], [T1|Z]) :- * row(Tt,T,Z). 这意味着:要使此查询成功,您必须向代码中添加额外的子句(使其更通用),或者更改剩余的片段


像潜行者一样,我也把其余部分留作练习。

首先,关于术语的注释:函数的一个特征是每个输入只与一个输出相关。另一方面,一个关系可以适用于多个这样的组合。Prolog谓词在它们的参数之间产生关系,回溯时可能出现多个答案

至于你的具体问题,@潜伏者已经给出了一些可靠的建议

然而,正如您已经注意到的,跟踪很快在inProlog中变得非常复杂,因此我想通过解释声明性调试的一些原则来补充潜伏者所写的内容

本质上,我们的目标是使我们的问题更简单,而不是更难。我们从您发布的程序中提到的案例开始:

?- transpose([[1,2,3],[1,2,3],[1,2,3]], Ls). false. 例如,我们可以将
行/3
概括如下:

row([], [], []). row([H|Tt], [[H|T1]|T], [T1|Z]) :- * row(Tt,T,Z). 这意味着:要使此查询成功,您必须向代码中添加额外的子句(使其更通用),或者更改剩余的片段


和潜伏者一样,我也把剩下的部分作为练习来处理。

结果表明,以前的解决方案是不够的,因为它只是一个描述 ?- transpose([[_]], Ls). false. :- op(950,fy, *). *_. row([], [], []). row([H|Tt], [[H|T1]|T], [T1|Z]) :- * row(Tt,T,Z). ?- transpose([[_]], Ls). false.
    */

    (
        program(INPUT_VECTOR,OUTPUT_VECTOR)
    )
    :-
    (
        (
            (
                INPUT_TRUTH_GOAL
            )
            =
            (
                item(INPUT_VECTOR,J_INDEX,K_INDEX,ITEM)
            )
        )
        ,
        (
            (
                OUTPUT_TRUTH_GOAL
            )
            =
            (
                item(OUTPUT_VECTOR,K_INDEX,J_INDEX,ITEM)
            )
        )
        ,
        (
            (
                nonvar(INPUT_VECTOR)
            )
            *->
            (
                once(foreach(INPUT_TRUTH_GOAL,OUTPUT_TRUTH_GOAL))
            )
            ;
            (
                (
                    nonvar(OUTPUT_VECTOR)
                )
                *->
                (
                    once(foreach(OUTPUT_TRUTH_GOAL,INPUT_TRUTH_GOAL))
                )
            )
        )
    )
    .

    (
        item(VECTOR,J_INDEX,K_INDEX,ITEM)
    )
    :-
    (
        (
            nth1(J_INDEX,VECTOR,SUBVECTOR)
        )
        ,
        (
            nth1(K_INDEX,SUBVECTOR,ITEM)
        )
    )
    .

    /*
    ?-
    program([[1,2,3],[4,5,6],[7,8,9]],[[1,4,7],[2,5,8],[3,6,9]])
    .
    true.

    ?-
    program([[1,2,3],[4,5,6],[7,8,9]],OUTPUT_VECTOR)
    .
    OUTPUT_VECTOR = [[1, 4, 7|_830], [2, 5, 8|_962], [3, 6, 9|_1100]|_356]  .

    ?-
    program(INPUT_VECTOR,[[1,4,7],[2,5,8],[3,6,9]])
    .
    INPUT_VECTOR = [[1, 2, 3|_560], [4, 5, 6|_626], [7, 8, 9|_698]|_350]    .

    ?-
    ?-
    program(INPUT_VECTOR,OUTPUT_VECTOR)
    ,
    INPUT_VECTOR = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    .

    false .

    ?-