먼저 모델에 기본 세계 모델이 지나치게 복잡하게 표시되어 있다고 생각합니다. 나는 당신이 일하려고하는 문제를 알아 차리고 도주합니다. 그리고 그것은 확실히 더러운 지역입니다.
나를위한 열쇠는 Char의 순서이기 때문에 모델 사용 seq
을 만드는 것입니다.
abstract sig Char {}
abstract sig EscapedCharacter extends Char {}
one sig A,B,C extends Char {}
one sig Backslash, Comma extends EscapedCharacter {}
pred valid[ string : seq Char ] {
string.isEmpty
or
string[0] = Backslash
implies {
# string > 1
and string[1] in EscapedCharacter
and valid[ string.subseq[2,#string]]
}
else string[0] != Comma and valid[ string.rest ]
}
run valid for 4
불행히도 이것은 재귀를 사용합니다. 재귀없이 이것을 지정할 수있는 방법은 실제로 실패합니다.하지만 찾으려고합니다. 메뉴에서 재귀를 활성화해야하기 때문에 이것은 불행한 일입니다. 이것은 3 단계로 제한되어 있습니다. 이는 작은 문제조차도 낮은 수준으로 나타납니다. 이 제한의 이유는 상태 공간을 폭발시키는 재귀가 전개되어야한다는 것입니다. 그러나 대부분의 개발자에게는 가독성이 매우 높기 때문에 재귀를 일류 시민으로 만들기위한 방법을 찾길 바랍니다. 우리는 몇 가지 예 주장 할 때 작동처럼
어쨌든, 보이는 : 쉼표 항상에 있던 원래의 요구 사항에 놓친
assert InvalidExample {
not valid[ 0->Backslash ]
}
check InvalidExample for 4
assert InvalidExample2 {
not valid[ (0->A) + (1->Backslash) + (2->Backslash)+ (3->Comma) ]
}
check InvalidExample2 for 4
assert ValidExample {
valid[ (0->Backslash) + (1->Comma) ]
}
check ValidExample for 4
업데이트는 앞에 백 슬래시를 (내가 대신 내 상식을 적용)
안녕하세요. @ Peter Kriens. 합금이 재귀를 허용하지 않는다고 생각 했나요? 귀하의 솔루션이 잘못된 문자열을 금지한다고 생각하지 않습니다 : A \\, B –
나는 \\이 (가) 정상적인 이스케이프 처리를 수행했다고 생각했습니다. 그러나 나는 항상 쉼표가 이스케이프되기를 원한다는 것을 알았다 (왜 ??). 그때 그 변화는 그렇게 어렵지 않습니다. else 절에서 문자열 [0]이 쉼표가 아닌지 확인하십시오. 예를 업데이트했습니다. 예, 재귀는 옵션에서 최대 3 단계까지 허용됩니다. 나는 우리가 이것을 부딪 칠 필요가 있다고 생각한다. 나는 또한 그것이 매우 분명하기 때문에 이것이 다르게 쓰여질 수 있는지 이해하려고 노력한다. imho –