我之前已动态定义了一些事实,如下所示。
% declare dynamic facts
:- dynamic title/2.
:- dynamic author/2.
:- dynamic publisher/2.
:- dynamic price/2.
:- dynamic call_number/2.
:- dynamic edition/2.
:- dynamic data_disk/2.
每次程序运行时并断言这些事实
:- assert(title(book1, 'Elementary Statistics')).
:- assert(title(book2, 'Statistics for Engineers')).
:- assert(title(book3, 'Statistics for Engineers and Scientists')).
:- assert(title(book4, 'IT in Language Learning')).
:- assert(author(book1, 'Patricia Wilson')).
:- assert(author(book2, 'James Mori')).
:- assert(author(book3, 'James Mori')).
:- assert(author(book4, 'O Ivan')).
:- assert(publisher(book1, 'Addison Wesley')).
:- assert(publisher(book2, 'World Scientific')).
:- assert(publisher(book3, 'World Scientific')).
:- assert(publisher(book4, 'Universal Press')).
:- assert(price(book1, 75)).
:- assert(price(book2, 125)).
:- assert(price(book3, 125)).
:- assert(price(book4, 5)).
:- assert(call_number(book1, 'QA373')).
:- assert(call_number(book2, 'QA673')).
:- assert(call_number(book3, 'QA674')).
:- assert(call_number(book4, 'QA007')).
:- assert(edition(book1, 1)).
:- assert(edition(book2, 3)).
:- assert(edition(book3, 2)).
:- assert(edition(book4, 1)).
:- assert(data_disk(book1, 'No')).
:- assert(data_disk(book2, 'Yes')).
:- assert(data_disk(book3, 'Yes')).
:- assert(data_disk(book4, 'No')).
正如您所看到的那样,事实是按照一定的顺序
book1
book2
book3
book4
如何获得最后的X,其中X是bookX,并且增加1,以便插入的新书总是(X + 1)?
答案 0 :(得分:1)
您找到了一个解决方案(即计算现有事实,并添加1),这有效但有一个主要缺点:它使添加单个新事实的运行时间与已经断言的事实数量成比例即可。这意味着声明一系列N
个事实需要的时间与N
2 成正比。
理想情况下,我们希望断言单个事实在?(1)中,并且断言 N 事实因此在?( N )。
实现这一目标的一种方法是重新考虑您对书籍的初始陈述。
例如,假设您像这样展示您的书籍(为简洁起见省略了一些数据):
book([title('Elementary Statistics'), author('Patricia Wilson'), price(75)]). book([title('Statistics for Engineers'), author('James Mori'), publisher('World Scientific')]).
请注意,此表示允许我们省略仅存在于某些书籍中的字段。其他陈述也是有道理的。
我们可以使用findall/3
轻松获取所有这些事实:
?- findall(Book, book(Book), Books).
这些事实的数量是线性。
此外,让我们按如下方式定义assert_book_/3
:
assert_book_(Book, N0, N) :- memberchk(title(Title), Book), memberchk(author(Author), Book), assertz(title(N0,Title)), assertz(author(N0,Author)), N #= N0 + 1.
为了举例,我专注于标题和作者。我将此作为练习留下来。
这个谓词的参数是:
N0
N1
,它只是一个而不是N0
。现在要点:这些参数使用meta-predicate {{1}以适当的顺序弃用谓词书籍 }:
?- findall(Book, book(Book), Books), foldl(assert_book_, Books, 1, _).
运行此查询后,我们有:
?- title(N, T). N = 1, T = 'Elementary Statistics' ; N = 2, T = 'Statistics for Engineers'.
数据库中foldl/4
的类似事实:
?- author(N, T). N = 1, T = 'Patricia Wilson' ; N = 2, T = 'James Mori'.
因此,我们使用author/2
来隐式跟踪我们需要的运行索引,并实现了具有所需运行时间的解决方案。
请注意,您的任务还有一个明智的解决方案:
assert_title(Book, Title) :- atom_concat(book, N0, Book), atom_number(N0, N), assertz(title(N, Title)).
这显然不是你想要的,但如果你使用的话,它会适用于你展示的例子:
:- assert_title(book1, 'Elementary Statistics'). :- assert_title(book2, 'Statistics for Engineers').
现在我们又来了:
?- title(N, Title). N = 1, Title = 'Elementary Statistics' ; N = 2, Title = 'Statistics for Engineers'.
这里的笑话是你已经实际输入了运行索引,我们可以使用foldl/4
来获取它:
?- atom_concat(book, N0, book1), atom_number(N0, N). N0 = '1', N = 1.
- )
答案 1 :(得分:0)
我在最近的星巴克清醒过来,想出了最简单的答案。
@Autowired
@Qualifier("datasource")
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource);
}
@Bean
protected AuthorizationCodeServices authorizationCodeServices() {
return new JdbcAuthorizationCodeServices(dataSource);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer)
throws Exception {
oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.authorizationCodeServices(authorizationCodeServices())
.authenticationManager(authenticationManager).tokenStore(tokenStore())
.approvalStoreDisabled();
}
aggregate_all函数将计算我的知识库中可用的标题谓词数,并将执行一些计算。
我愿意接受更好的建议,如果你有更好的方法,请回复。