crepe
v0.1.8
Crepe는 Datalog와 같은 구문으로 Rust에서 선언적 논리 프로그램을 작성할 수있는 라이브러리입니다. 효율적이고 안전한 코드를 생성하고 Rust 프로그램과 원활하게 상호 운용하는 절차 매크로를 제공합니다.
@input 관계를 초기화하는 TypeSafe 방법 아래 프로그램은 지시 된 그래프의 전이 폐쇄를 계산합니다. crepe! 매크로.
use crepe :: crepe ;
crepe ! {
@input
struct Edge ( i32 , i32 ) ;
@output
struct Reachable ( i32 , i32 ) ;
Reachable ( x , y ) <- Edge ( x , y ) ;
Reachable ( x , z ) <- Edge ( x , y ) , Reachable ( y , z ) ;
}
fn main ( ) {
let mut runtime = Crepe :: new ( ) ;
runtime . extend ( [ Edge ( 1 , 2 ) , Edge ( 2 , 3 ) , Edge ( 3 , 4 ) , Edge ( 2 , 5 ) ] ) ;
let ( reachable , ) = runtime . run ( ) ;
for Reachable ( x , y ) in reachable {
println ! ( "node {} can reach node {}" , x , y ) ;
}
}산출:
node 1 can reach node 2
node 1 can reach node 3
node 1 can reach node 4
node 1 can reach node 5
node 2 can reach node 3
node 2 can reach node 4
node 2 can reach node 5
node 3 can reach node 4
Crepe로 더 많은 일을 할 수 있습니다. 다음 예제는 계층화 된 부정, 녹 발현 구문 및 반세 평가를 사용하여 길이가 최대 MAX_PATH_LEN 길이를 가진 가중 그래프에서 모든 경로를 찾는 방법을 보여줍니다.
use crepe :: crepe ;
const MAX_PATH_LEN : u32 = 20 ;
crepe ! {
@input
struct Edge ( i32 , i32 , u32 ) ;
@output
struct Walk ( i32 , i32 , u32 ) ;
@output
struct NoWalk ( i32 , i32 ) ;
struct Node ( i32 ) ;
Node ( x ) <- Edge ( x , _ , _ ) ;
Node ( x ) <- Edge ( _ , x , _ ) ;
Walk ( x , x , 0 ) <- Node ( x ) ;
Walk ( x , z , len1 + len2 ) <-
Edge ( x , y , len1 ) ,
Walk ( y , z , len2 ) ,
( len1 + len2 <= MAX_PATH_LEN ) ;
NoWalk ( x , y ) <- Node ( x ) , Node ( y ) , ! Walk ( x , y , _ ) ;
}
fn main ( ) {
let n = 256 ;
let mut edges = Vec :: new ( ) ;
for i in 0 ..n {
for j in 0 ..n {
if rand :: random :: < f32 > ( ) < 0.02 {
edges . push ( Edge ( i , j , 5 ) ) ;
}
}
}
let mut runtime = Crepe :: new ( ) ;
runtime . extend ( edges ) ;
let ( walk , nowalk ) = runtime . run ( ) ;
println ! ( "Walk: {}" , walk . len ( ) ) ;
println ! ( "NoWalk: {}" , nowalk . len ( ) ) ;
}산출:
Walk: 89203
NoWalk: 8207
초기 테스트에서 생성 된 코드는 매우 빠릅니다. 큰 그래프 (~ 10 6 관계)의 전이 폐쇄 변형은 컴파일 된 수플레와 비슷한 속도로 실행되며 컴파일 시간의 일부를 사용합니다.
벤치 마크는 benches/ 디렉토리를 참조하십시오. 벤치 마크는 cargo bench 사용하여 실행할 수 있습니다.
이 매크로는 현재 모듈에서 Crepe 구조를 생성하고 선언 된 모든 관계에 대한 structs를 생성합니다. 즉, 크레페를 더 큰 프로그램 내에 통합하려면 관련 코드와 함께 자체 모듈에 넣어야합니다. 자세한 내용은 문서를 참조하십시오.
이 프로젝트는 Souffle과 Formulog에서 영감을 얻었으며, 이는 정적 분석을 위해 유사한 데이터 로그 컴파일 모델을 사용합니다.