我正在尝试编写谓词,以根据公共索引在列表中添加元素。到目前为止我所做的当然不值得展示...... =(
预期的行为类似于:
List = [ ]
add_to_list( List, Index1, Param1, Value1 )
List = [
[ Index1, [ Param1, Value1 ] ]
]
add_to_list( List, Index1, Param2, Value2 )
List = [
[ Index1, [ Param1, Value1 ], [ Param2, Value2 ] ]
]
add_to_list( List, Index2, Param3, Value3 )
List = [
[ Index1, [ Param1, Value1 ], [ Param2, Value2 ] ],
[ Index2, [ Param3, Value3 ] ]
]
答案 0 :(得分:2)
嗯,这种行为是不可能的(除非我们用像setarg/3
这样的东西进行破解。
(有关详细信息,请查看d estructive vs single assignment)
一个非常相似的行为是:
List0 = [ ]
add_to_list( List0, Index1, Param1, Value1, List1)
List1 = [
[ Index1, [ Param1, Value1 ] ]
]
add_to_list( List1, Index1, Param2, Value2, List2)
List2 = [
[ Index1, [ Param1, Value1 ], [ Param2, Value2 ] ]
]
add_to_list( List2, Index2, Param3, Value3, List3)
List3 = [
[ Index1, [ Param1, Value1 ], [ Param2, Value2 ] ],
[ Index2, [ Param3, Value3 ] ]
]
当然,由于我们不对Param
和Value
做单独的事情,我们可以将它们作为一个变量传递:
add_to_list(List1, Index, Val, List2)
其中Val = [Param, Value]
一个简单的实现是:
add_to_list(L1,I,Val,L2): - 成员([I,Rest],L1) - > (追加(Val,Rest,FRest), 选择([I,Rest],L1,[I,FRest],L2) );追加([[I,Val]],L1)。
但这很慢;将新元素添加到列表的头部会更快(也更容易!)。
最后,最好使用association lists,根据我的经验,这是非常快的,可以轻松地模拟您的问题
答案 1 :(得分:1)
我这样做了:
add_to_list( [ ], Param, Val, Val2, [ [ Param, [ [ Val, Val2 ] ] ] ] ).
add_to_list( L, Param, Val, Val2, LNew ) :-
member( [ Param, Vals ], L ) ->
( select( [ Param, Vals ], L, L2 ),
not( member( [ Val, Val2 ], Vals ) ) ->
( append( Vals, [ [ Val, Val2 ] ], Vals2 ),
append( [ [ Param, Vals2 ] ], L2, LNew )
); append( L, L2, LNew )
); append( L, [ [ Param, [ Val, Val2 ] ] ], LNew ).
所以行为是:
List1 = []
add_to_list( List1, Index1, Param1, Value1, List2 )
List2 = [
[ Index1, [ [ Param1, Value1 ] ] ]
]
add_to_list( List2, Index1, Param2, Value2, List3 )
List3 = [
[ Index1, [ [ Param1, Value1 ], [ Param2, Value2 ] ] ]
]
add_to_list( List3, Index2, Param3, Value3, List4 )
List4 = [
[ Index1, [ [ Param1, Value1 ], [ Param2, Value2 ] ] ],
[ Index2, [ [ Param3, Value3 ] ] ]
]
谢谢,thanosQR。