作为项目的一部分,我需要编写一个解析器,它可以读取文件并解析我可以在程序中使用的事实.
文件结构如下所示:
property = { el1 , el2 , ... }.
Run Code Online (Sandbox Code Playgroud)
我最终想要的是:
property(el1).
property(el2).
...
Run Code Online (Sandbox Code Playgroud)
我这样读了我的文件:
main :-
open('myFile.txt', read, Str),
read_file(Str,Lines),
close(Str),
write(Lines), nl.
read_file(Stream,[]) :-
at_end_of_stream(Stream).
read_file(Stream,[X|L]) :-
\+ at_end_of_stream(Stream),
read(Stream,X),
parse(X), % Here I call upon my parser.
read_file(Stream,L).
Run Code Online (Sandbox Code Playgroud)
现在我已经阅读了几本书和网上关于DCG的内容,但他们都解释了相同的简单例子,你可以生成句子,如"猫吃蝙蝠"等......当我想用它来做上面的例子时我惨遭失败.
我所做的是"解析"下面的行:
property = el1.
Run Code Online (Sandbox Code Playgroud)
至
property(el1).
Run Code Online (Sandbox Code Playgroud)
有了这个:
parse(X) :-
X =.. List, % Reason I do this is because X is one atom and not a list.
phrase(sentence(Statement), List),
asserta(Statement).
sentence(Statement) --> ['=', Gender, Person] , { …Run Code Online (Sandbox Code Playgroud) 我想用
catch(:Goal, +Catcher, :Recover)
Run Code Online (Sandbox Code Playgroud)
目标在哪里
call_with_time_limit(+Time, :Goal)
Run Code Online (Sandbox Code Playgroud)
它搞砸了,我无法找到正确的方法来了解上述情况之一发生时间:
1)由于超时,目标停止了.
2)目标失败(有时候会失败).
我试过了:
(catch(call_with_time_limit(Time, Goal), Catcher, Recover) ->
(ground(Catcher), Catcher = time_limit_exceeded), **TIMEOUT ACTIONS**)
;
(**SUCCESS ACTIONS**))
;
**FAILURE ACTIONS**
)
Run Code Online (Sandbox Code Playgroud)
*编辑*
图案:
我使用以下模式:
((catch(call_with_time_limit(6,goal),
Exception,
true),(var(Exception);Exception=time_limit_exceeded))
->
(var(Exception) -> writeln(succ) ; writeln(timeout))
;
writeln(fail)
).
Run Code Online (Sandbox Code Playgroud)
该模式在4秒或更长时间内不起作用 - 它只是忽略了超时请求.
我试图在SWI-Prolog中为switch-statements实现一个简单的宏.
这是一系列条件陈述:
(X = a ->
Output = case1;
X = b ->
Output = case2;
X = c ->
Output = case3).
Run Code Online (Sandbox Code Playgroud)
这是一个具有相同效果的等效(但速度要慢得多)的表达式:
switch(X, [
a : (Output = case1),
b : (Output = case2),
c : (Output = case3)
])
Run Code Online (Sandbox Code Playgroud)
我在一个应用程序中使用了很多这样的谓词,但这会大大减慢它的速度.是否可以将此开关谓词实现为宏,以便在编译时将其更改为正常的条件表达式,以提高应用程序的性能?
我是Prolog的新手,我正在使用SWI-Prolog来解决以下问题.我有几个文件dataBase1.pl,dataBase2.pl...具有相同的结构(基于此线程)
:- module(dataBase1,[]).
:- use_module(library(persistency)).
:- persistent
predicate1(A:any, B:any),
predicate2(A:any, B:any).
:- initialization(init).
init :-
absolute_file_name('dataBase1.db', File, [access(write)]),
db_attach(File, []).
Run Code Online (Sandbox Code Playgroud)
predicate1/2, predicate2/2 对所有数据库文件都是通用的.
然后,我在第三个文件中定义了predicates.pl几个使用以前数据库中的子句的子句,例如testPredicate(A,B) :- predicate1(A,B), predicate2(A,B).
我的问题是我希望predicate1/2, predicate2/2从与数据库文件对应的所有模块中使用上面的子句.在当前状态下,我需要精确上下文模块才能使用
predicate1/2, predicate2/2(即dataBase1:predicate1/2, dataBase2:predicate1/2,....)
我无法使用,use_module/1因为我将动态添加/删除数据库文件.
提前感谢任何建议!
编辑:在评论中讨论之后,如何将表单的可查询谓词定义head(X,Y) :- body()为持久动态谓词?
据我所知,通过健全的统一,SLD 解析不应该创建循环数据结构(这是正确的吗?)
如果是这样,理论上可以以不需要垃圾收集 (GC) 的方式实现 Prolog。但话又说回来,一个人可能不会。
对于基于 WAM 的 Prolog 实现来说,这是真的吗?
SWI-Prolog 是这样吗?(我相信它不是基于 WAM 的)当发生检查全局启用时,在 SWI-Prolog 中禁用 GC 是否安全?
具体来说:
:- set_prolog_flag(occurs_check, true).
:- set_prolog_flag(gc, false). /* is this safe? */
Run Code Online (Sandbox Code Playgroud) prolog logic-programming swi-prolog warren-abstract-machine occurs-check
我想知道是否可以使用predsort/3而不会丢失重复值?如果没有,我应该如何排序这个术语列表?
当前排序功能:
compareSecond(Delta, n(_, A, _), n(_, B, _)):-
compare(Delta, A, B).
Run Code Online (Sandbox Code Playgroud)
结果:
predsort(compareSecond, [n(3, 1, 5), n(0, 0, 0), n(8, 0, 9)], X).
X = [n(0, 0, 0), n(3, 1, 5)].
Run Code Online (Sandbox Code Playgroud)
你看,这个词n(8,0,9)已经消失了,这不是我需要的.
许多Prolog系统都有一个freeze/2谓词,一个应该有名字的谓词,geler/2因为它甚至是在Prolog-II之前发明的.
假设我对同一个变量有条件,但有两个不同的目标,即:
?- freeze(X, G1), freeze(X, G2), X=1.
Run Code Online (Sandbox Code Playgroud)
什么是首选的唤醒策略,G1首先执行还是G2首次执行?如果G1和G2确实会产生新的冻结,这也会被唤醒:
G1 :- freeze(Y, G3), Y=1.
G2 :- freeze(Z, G4), Z=1.
Run Code Online (Sandbox Code Playgroud)
G3或G4是否始终在G1和G2之间执行,或者可能是G1和G2之后执行G3或G4,甚至是以后的任何时间?
再见
我想使用键盘快捷键或命令清除 SWI-prolog 控制台内的屏幕(我猜在 Prolog 中你称之为“谓词”)。
这是类似的问题,我有点找到我需要的东西 - 有一个适合我的谓词:
write('\33\[2J').
Run Code Online (Sandbox Code Playgroud)
有没有更好(更简单)的方法来清除屏幕?
我试图call_with_depth_limit/3在 SWI-Prolog 中使用来实现迭代深化,要么我不明白它是如何工作的,要么它行为不端。我有一个例子,其中发生以下情况:
?- call_with_depth_limit(mygoal, 29, Result).
Result = 29 ;
Result = 25 ;
Result = 27 ;
Result = 27 ;
false.
Run Code Online (Sandbox Code Playgroud)
?- call_with_depth_limit(mygoal, 26, Result).
Result = depth_limit_exceeded ;
false.
Run Code Online (Sandbox Code Playgroud)
根据文档,如果目标可以用限制最大递归或更少来证明,它应该会成功。在限制为 30 的第一次调用中,我们看到结果为 25,因此我希望以 26 的限制调用它会成功。我在模块中使用约束处理规则,以防那里可能有一些交互使其行为不端。
编辑:玩过伊莎贝尔的回答后,我想我明白它的行为方式了:
看这个例子:
loop :- loop.
succeed(0).
succeed(N) :- N > 0, N1 is N - 1, succeed(N1).
fail(N) :- N > 0, N1 is N - 1, fail(N1).
Run Code Online (Sandbox Code Playgroud)
?- call_with_depth_limit(succeed(0), 1000, Result). …Run Code Online (Sandbox Code Playgroud) 我在这里找到了 Haskell 中移位重置分隔延续的示例:
Run Code Online (Sandbox Code Playgroud)resetT $ do alfa bravo x <- shiftT $ \esc -> do charlie lift $ esc 1 delta lift $ esc 2 return 0 zulu x这会:
履行
alfa履行
bravo履行
charlie绑定
x到1,从而执行zulu 1从末尾掉下来
resetT,然后跳回到后面esc 1履行
delta绑定
x到2,从而执行zulu 2从末尾掉下来
resetT,然后跳回到后面esc 2逃离
resetT,导致它产生 0
我不知道如何使用 SWI-Prolog 的shift/1和reset/3编写等效代码。
下面的代码是我的尝试。输出是相同的,但看起来很混乱和倒退,我觉得我误用了与Haskell 示例中的和Ball类似的东西。另外,我不知道该怎么办。esc 1esc 2return 0 …
continuations haskell prolog swi-prolog delimited-continuations