use pddl_ish_parser::{ models::problem::Problem, parser::{action::Action, object::Object, parameter::Parameter, problem_parser::parse_problem}, }; #[test] fn test_parse_pddl_problem() { let input = r#"(define (problem find-ai-news) (:domain web-processing) (:objects website-url - url all-hyperlinks - links ai-news-links - links ) (:init (website-known website-url) ) (:goal (and (all-links-extracted website-url all-hyperlinks) (relevant-links-found all-hyperlinks ai-news-links) ) ) (:action extract-html :parameters (?url - url) :precondition (website-known ?url) :effect (html-content-available ?url) ) (:action extract-links :parameters (?url - url) :precondition (html-content-available ?url) :effect (all-links-extracted ?url all-hyperlinks) ) (:action summarize-and-filter-links :parameters (?links - links) :precondition (all-links-extracted website-url ?links) :effect (relevant-links-found ?links ai-news-links) ) )"#; let expected = Problem { name: "find-ai-news".to_string(), domain: "web-processing".to_string(), objects: vec![ Object { name: "website-url".to_string(), object_type: "url".to_string(), }, Object { name: "all-hyperlinks".to_string(), object_type: "links".to_string(), }, Object { name: "ai-news-links".to_string(), object_type: "links".to_string(), }, ], init: vec![], goal: vec![], actions: vec![ Action { name: "extract-html".to_string(), parameters: vec![Parameter { name: "url".to_string(), param_type: "url".to_string(), }], preconditions: vec!["(website-known ?url)".to_string()], effects: vec!["(html-content-available ?url)".to_string()], }, Action { name: "extract-links".to_string(), parameters: vec![Parameter { name: "url".to_string(), param_type: "url".to_string(), }], preconditions: vec!["(html-content-available ?url)".to_string()], effects: vec!["(all-links-extracted ?url all-hyperlinks)".to_string()], }, Action { name: "summarize-and-filter-links".to_string(), parameters: vec![Parameter { name: "links".to_string(), param_type: "links".to_string(), }], preconditions: vec!["(all-links-extracted website-url ?links)".to_string()], effects: vec!["(relevant-links-found ?links ai-news-links)".to_string()], }, ], }; let result = parse_problem(input); match result { Ok((remaining_input, parsed_problem)) => { println!("{:?}", parsed_problem); assert_eq!(parsed_problem, expected); } Err(e) => { println!("Error parsing problem: {:?}", e); assert!(false, "Parsing failed"); } } } #[test] fn test_parse_news_finding_pddl_problem() { let input = r#"(define (problem find-ai-news) (:domain news-finding) (:objects agent - toolkit website - url html_content - html links - hyperlink_list summaries - content_list ) (:init (has-url website) (toolkit-ready agent) ) (:goal (has-ai-news-summaries summaries) ) (:action fetch-html :parameters (agent - toolkit website - url) :precondition (and (has-url website) (toolkit-ready agent) ) :effect (and (not (toolkit-ready agent)) (has-html website html_content) ) ) (:action extract-links :parameters (agent - toolkit html_content - html) :precondition (and (has-html website html_content) (not (toolkit-ready agent)) ) :effect (and (has-links html_content links) (toolkit-ready agent) ) ) (:action summarize-content :parameters (agent - toolkit links - hyperlink_list) :precondition (and (has-links html_content links) (toolkit-ready agent) ) :effect (and (has-ai-news-summaries summaries) (toolkit-ready agent) ) ) )"#; let expected = Problem { name: "find-ai-news".to_string(), domain: "news-finding".to_string(), objects: vec![ Object { name: "agent".to_string(), object_type: "toolkit".to_string(), }, Object { name: "website".to_string(), object_type: "url".to_string(), }, Object { name: "html_content".to_string(), object_type: "html".to_string(), }, Object { name: "links".to_string(), object_type: "hyperlink_list".to_string(), }, Object { name: "summaries".to_string(), object_type: "content_list".to_string(), }, ], init: vec![], goal: vec![], actions: vec![ Action { name: "fetch-html".to_string(), parameters: vec![ Parameter { name: "agent".to_string(), param_type: "toolkit".to_string(), }, Parameter { name: "website".to_string(), param_type: "url".to_string(), }, ], preconditions: vec!["(and\n (has-url website)\n (toolkit-ready agent)\n )".to_string()], effects: vec!["(and\n (not (toolkit-ready agent))\n (has-html website html_content)\n )".to_string()], }, Action { name: "extract-links".to_string(), parameters: vec![ Parameter { name: "agent".to_string(), param_type: "toolkit".to_string(), }, Parameter { name: "html_content".to_string(), param_type: "html".to_string(), }, ], preconditions: vec!["(and\n (has-html website html_content)\n (not (toolkit-ready agent))\n )".to_string()], effects: vec!["(and\n (has-links html_content links)\n (toolkit-ready agent)\n )".to_string()], }, Action { name: "summarize-content".to_string(), parameters: vec![ Parameter { name: "agent".to_string(), param_type: "toolkit".to_string(), }, Parameter { name: "links".to_string(), param_type: "hyperlink_list".to_string(), }, ], preconditions: vec!["(and\n (has-links html_content links)\n (toolkit-ready agent)\n )".to_string()], effects: vec!["(and\n (has-ai-news-summaries summaries)\n (toolkit-ready agent)\n )".to_string()] }, ], }; let result = parse_problem(input); match result { Ok((remaining_input, parsed_problem)) => { println!("{:?}", parsed_problem); assert_eq!(parsed_problem, expected); } Err(e) => { println!("Error parsing problem: {:?}", e); assert!(false, "Parsing failed"); } } } #[test] fn test_parse_robot_cleanup_pddl_problem() { let input = r#"(define (problem robot-cleanup-task) ; This is the problem definition for a robot performing cleanup tasks (:domain robot-cleanup) ; The domain 'robot-cleanup' defines the general rules and actions for robot cleanup tasks. (:objects room1 - room trash1 - trash robot1 - robot ; Objects are defined with their types. We have one room, one trash object, and one robot. ) (:init (at robot1 room1) (trash-in trash1 room1) (clean room1) ; The initial state: robot is in room1, trash1 is in room1, and room1 is clean. ) (:goal (clean room1) ; The goal is to have the room clean. ) (:action move :parameters (?r - robot ?from - room ?to - room) :precondition (at ?r ?from) :effect (and (not (at ?r ?from)) (at ?r ?to)) ; Action for moving the robot from one room to another. ) (:action pick-up :parameters (?r - robot ?t - trash ?room - room) :precondition (and (at ?r ?room) (trash-in ?t ?room)) :effect (and (not (trash-in ?t ?room)) (holding ?r ?t)) ; Action for picking up trash in the same room as the robot. ) (:action dispose-of :parameters (?r - robot ?t - trash) :precondition (holding ?r ?t) :effect (and (not (holding ?r ?t)) (clean (room-of ?t))) ; Action for disposing of the trash, which results in a clean room. ) )"#; let expected = Problem { name: "robot-cleanup-task".to_string(), domain: "robot-cleanup".to_string(), objects: vec![ Object { name: "room1".to_string(), object_type: "room".to_string(), }, Object { name: "trash1".to_string(), object_type: "trash".to_string(), }, Object { name: "robot1".to_string(), object_type: "robot".to_string(), }, ], init: vec![], goal: vec![], actions: vec![ Action { name: "move".to_string(), parameters: vec![ Parameter { name: "r".to_string(), param_type: "robot".to_string(), }, Parameter { name: "from".to_string(), param_type: "room".to_string(), }, Parameter { name: "to".to_string(), param_type: "room".to_string(), }, ], preconditions: vec!["(at ?r ?from)".to_string()], effects: vec!["(and (not (at ?r ?from)) (at ?r ?to))".to_string()], }, Action { name: "pick-up".to_string(), parameters: vec![ Parameter { name: "r".to_string(), param_type: "robot".to_string(), }, Parameter { name: "t".to_string(), param_type: "trash".to_string(), }, Parameter { name: "room".to_string(), param_type: "room".to_string(), }, ], preconditions: vec!["(and (at ?r ?room) (trash-in ?t ?room))".to_string()], effects: vec!["(and (not (trash-in ?t ?room)) (holding ?r ?t))".to_string()], }, Action { name: "dispose-of".to_string(), parameters: vec![ Parameter { name: "r".to_string(), param_type: "robot".to_string(), }, Parameter { name: "t".to_string(), param_type: "trash".to_string(), }, ], preconditions: vec!["(holding ?r ?t)".to_string()], effects: vec!["(and (not (holding ?r ?t)) (clean (room-of ?t)))".to_string()], }, ], }; let result = parse_problem(input); match result { Ok((remaining_input, parsed_problem)) => { println!("{:?}", parsed_problem); assert_eq!(parsed_problem, expected); } Err(e) => { println!("Error parsing problem: {:?}", e); assert!(false, "Parsing failed"); } } } #[test] fn test_parse_news_extraction_pddl_problem() { let input = r#"(define (problem find-ai-news) (:domain news-extraction) (:objects website - website content - text news_link - hyperlink ) (:init (website-content-fetched website) (all-hyperlinks-extracted website) ) (:goal (and (ai-news-summarized news_link) ) ) )"#; let expected = Problem { name: "find-ai-news".to_string(), domain: "news-extraction".to_string(), objects: vec![ Object { name: "website".to_string(), object_type: "website".to_string(), }, Object { name: "content".to_string(), object_type: "text".to_string(), }, Object { name: "news_link".to_string(), object_type: "hyperlink".to_string(), }, ], init: vec![], goal: vec![], actions: vec![], }; let result = parse_problem(input); match result { Ok((remaining_input, parsed_problem)) => { println!("{:?}", parsed_problem); assert_eq!(parsed_problem, expected); } Err(e) => { println!("Error parsing problem: {:?}", e); assert!(false, "Parsing failed"); } } }