2013-07-21 3 views
2

1과 0의 목록에서 연속적인 1의 수를 제한하는 매우 간단한 자동 연산을 구현하고 싶습니다 (예 : [0,1,1,0,1,1,1]).clpfd : automaton을 사용하여 SICStus Prolog에서 카운터 값을 제한하는 방법?

내 자동 장치는 다음과 같습니다

% 'Day' is a list of clpfd variables 
% 'Allowed' is an integer 
% 
% consecutiveOnes(+Day, +Allowed) 
consecutiveOnes(Day, Allowed) :- 

    automaton(Day, _, Day, 
     [source(n)], 
     [ 
     arc(n, 0, n, [0] ), 
     arc(n, 1, n, [C+1]) 
     ], 
     [C], 
     [0], 
     [_N] 
    ). 



% example 1: 
% consecutiveOnes([0,0,0,1,1,1], 2) -> there are three consecutive 1s and we allow only 2 -> Fail. 

% example 2: 
% consecutiveOnes([0,1,1,1,0,0], 2) -> there are three consecutive 1s and we allow only 2 -> Fail. 


% example 3: 
% consecutiveOnes([0,1,1,0,0,0], 2) -> there are only two consecutive 1s and we allow 2 -> OK 

어떻게 위의 프롤로그 코드에 C <= Allowed를 지정 카운터 C에 대한 제약 조건을 추가 할 수 있습니까?

답변

2

추가 상태로 공식화하는 것이 가장 좋습니다. 예를 들어, 대부분의 두 개의 연속 1 초 동안 :

:- use_module(library(clpfd)). 

at_most_two_consecutive_ones(Day) :- 
    automaton(Day, 
     [source(n),sink(n),sink(n1),sink(n2)], 
     [arc(n, 0, n), 
     arc(n, 1, n1), 
     arc(n1, 1, n2), 
     arc(n1, 0, n), 
     arc(n2, 1, false), 
     arc(n2, 0, n) 
     ]). 

예 조회 : 더 일반적인 솔루션을

?- at_most_two_consecutive_ones([0,0,0,1,1,1]). 
false. 

?- at_most_two_consecutive_ones([0,1,1,0,1,1]). 
true. 

?- at_most_two_consecutive_ones([0,1,1,0,1,0]). 
true. 

, 당신은 실행의 최대 길이가 주어 졌을 때 필요에 따라 자동 장치를 구축해야합니다.