未捕获的异常:错误 (instantiation_error,(is)/2)

uncaught exception: error(instantiation_error,(is)/2)

我正在编写一个程序来识别字符串中是否只有字母和空格,但它给我一个错误,我无法解决它。

未捕获的异常:错误(instantiation_error,(is)/2)

我认为错误仍然存​​在于 validazione_lista 但我无法解决它。

validazione_input(Input) :-
repeat,
    read(Input),
    validazione_lista(Input, A),
(   A == 0 -> write('\ninput non valido, inserire solamente lettere maiuscole, minuscole e spazi:'), nl, fail
;   A == 1 -> !
).

validazione_lista([], _).
    validazione_lista([TESTA|CODA], A) :-
    validazione_lettera(TESTA, B),
    if_validazione(B, (validazione_lista(CODA, C), A is C), A is B).

validazione_lettera(Lettera, A) :-
    Lettera == 32,
    A is 1,
    !.
validazione_lettera(Lettera, A) :-
    (Lettera >= 65, Lettera =< 90),
    A is 1,
    !.  
validazione_lettera(Lettera, A) :-
    (Lettera >= 97, Lettera =< 122),
    A is 1,
    !.
validazione_lettera(_, A) :-
    A is 0.

if_validazione(C, I1, _) :- C=1, !, I1.
if_validazione(C, _, I2) :- C=0, !, I2.

这一行是问题所在:

validazione_lista([], _).

不说空表是有效还是无效,它让空表不确定。现在代码

(validazione_lista(CODA, C), A is C)

有一个未知的 A 和未知的 C,并且 _ is _ 给出了错误。改成

validazione_lista([], 1).

所以空列表是有效输入,代码有效。


注意。在 Prolog 变量中编码所有 truth/false 信息并编写您自己的 if/else 是不需要的,并且使代码更难理解。例如

validazione_lettera(Lettera, A) :-
    Lettera == 32,
    A is 1,
    !.

“如果字母是 space 并且 A 是 1,则该字母有效”可以写成:

validazione_lettera(Lettera) :-
    Lettera == 32,
    !.

“如果字母是 space,则该字母有效”。这简化为:

validazione_lettera(32).

“32 是一个有效的字母代码”。您不需要“其他代码无效”,这是默认情况下发生的。

所有的代码都这样简化了。 validazione_lista([]). 表示空列表有效。然后主列表检查简化为“如果第一项有效且其余项有效,则列表有效”,两行短行:

validazione_lista([]).
validazione_lista([TESTA|CODA]) :-
    validazione_lettera(TESTA),
    validazione_lista(CODA).

然后你就可以完全删除if_validazione了。可以直接做主循环测试:

(   validazione_lista(Input) -> true 
;  write('\ninput non valido, inserire solamente lettere maiuscole, minuscole e spazi:'), nl, fail
).

那你可以通过代码把A,B,C全部去掉,去掉A是B,A是C。也许用between(65, 90, Lettera).也可以。