ChatGPT prompts - Programming - Coding - Source Code

Explain code

Just posting the code with no question often results in an explanation.

Prompt

fib(0, 1) :- !.
fib(1, 1) :- !.
fib(N, F) :-
        N > 1,
        N1 is N-1,
        N2 is N-2,
        fib(N1, F1),
        fib(N2, F2),
        F is F1+F2.

ChatGPT Continuation

This is a Prolog program that defines a function to compute the Fibonacci sequence. The function fib/2 takes two arguments, N and F, where N is the term number in the Fibonacci sequence and F is the value of that term. The ! symbol is the cut operator, which is used to prevent backtracking and make the code more efficient.


Prompt

:- use_module(library(clpfd)).

n_queens(N, Qs) :-
    length(Qs, N),
    Qs ins 1..N,
    safe_queens(Qs).

safe_queens([]).
safe_queens([Q|Qs]) :-
    safe_queens(Qs, Q, 1),
    safe_queens(Qs).

safe_queens([], _, _).
safe_queens([Q|Qs], Q0, D0) :-
    Q0 #\= Q,
    abs(Q0 - Q) #\= D0,
    D1 #= D0 + 1,
    safe_queens(Qs, Q0, D1).

ChatGPT Continuation

This is a Prolog program that solves the N-Queens problem. It defines two predicates n_queens/2 and safe_queens/2 that determine the placement of N queens on a chessboard such that no two queens attack each other. The n_queens/2 predicate takes two arguments: N, the number of queens, and Qs, a list of the positions of the queens. The safe_queens/2 predicate takes a list of queens, Qs, and checks that no two queens are on the same row, column, or diagonal. The program uses constraint programming with the library clpfd to find a solution. The constraint Qs ins 1..N ensures that each queen is placed in a separate column, and the safe_queens/2 predicate ensures that each queen is placed in a separate row and on a separate diagonal. The constraint Q0 #\= Q ensures that two queens are not placed in the same row, and the constraint abs(Q0 - Q) #\= D0 ensures that they are not placed on the same diagonal.

For a more detailed human answer see: Understanding CLP(FD) Prolog code of N-queens problem

Comment code

Prompt

Add inline comments to this Prolog code

fib(0, 1) :- !.
fib(1, 1) :- !.
fib(N, F) :-
        N > 1,
        N1 is N-1,
        N2 is N-2,
        fib(N1, F1),
        fib(N2, F2),
        F is F1+F2.

ChatGPT Continuation

fib(0, 1) :- !. % define the 0th Fibonacci number as 1
fib(1, 1) :- !. % define the 1st Fibonacci number as 1
fib(N, F) :- % define the Nth Fibonacci number as F
   N > 1, % N must be greater than 1
   N1 is N-1, % find the (N-1)th Fibonacci number
   N2 is N-2, % find the (N-2)th Fibonacci number
   fib(N1, F1), % call the fib predicate to find F1
   fib(N2, F2), % call the fib predicate to find F2
   F is F1+F2. % calculate the Nth Fibonacci number as the sum of F1 and F2

Create example code

Prompt

Show me an example of recursion in Prolog.

ChatGPT Completion

Here’s an example of recursion in Prolog: finding the factorial of a number. The factorial of a number is the product of all positive integers less than or equal to that number.

factorial(0, 1).
factorial(N, F) :-
    N > 0,
    N1 is N - 1,
    factorial(N1, F1),
    F is N * F1.

In this example, the factorial predicate takes two arguments: the number N and its factorial F. The base case is defined as factorial(0, 1), meaning that the factorial of 0 is 1. For any N greater than 0, the predicate calculates the factorial of N-1 using a recursive call to factorial, then multiplies the result by N to find the factorial of N.


Prompt

Create recursive Prolog code to process each item in list [1,2,3,4].

ChatGPT Completion

Here’s an example of a recursive Prolog predicate that processes each item in the list [1, 2, 3, 4] :

process_list([], _).
process_list([H|T], Process) :-
    call(Process, H),
    process_list(T, Process).

In this example, the process_list predicate takes two arguments: the list to process and the predicate Process to apply to each item in the list. The base case is defined as process_list([], _), meaning that the predicate does nothing when the list is empty. For any non-empty list [H|T], the predicate applies the Process predicate to the head H of the list, then makes a recursive call to process_list with the tail T of the list and the Process predicate. This way, Process is applied to each item in the list.

Here’s an example of how to use the process_list predicate:

print_item(Item) :-
    write(Item), nl.

?- process_list([1, 2, 3, 4], print_item).

This will output:

1
2
3
4

Notes:

When requesting code from ChatGPT, there are potential problems that could arise, such as:

  • The generated code may not be correct, though it might be close enough for a skilled programmer to fix it.
  • The generated code may be too complex for ChatGPT to complete within a time limit (which seems likely, given the common use of time limits with nondeterministic generation).
  • The generated code may not be in the correct programming language.
  • The generated code may lack comments, making it difficult to understand.
  • The generated code may include comments that push the code beyond the token limit, requiring the use of “continue.”
  • The generated code may have security issues.

Before asking ChatGPT for an example of existing code, it is advisable to check if there are any included examples or test cases. If there are issues with the provided code or test case, ChatGPT may be helpful in resolving them, such as understanding the code or troubleshooting issues with building and running it.


Intelligent find and replace

First some facts were generated

Prompt

Create Prolog connection facts for these London tube stops [‘Oxford Circus’,‘Tottenham Court Road’,‘Holborn’,‘Leicester Square’,‘Piccadilly Circus’,‘Green Park’,‘Bond Street’].

ChatGPT Completion

Here’s an example of Prolog facts for connections between the stops:

connects(oxford_circus, tottenham_court_road).
connects(tottenham_court_road, holborn).
connects(holborn, leicester_square).
connects(leicester_square, piccadilly_circus).
connects(piccadilly_circus, green_park).
connects(green_park, bond_street).

This code defines the connections between the tube stops. The connects/2 predicate takes two arguments: the first argument is the starting stop and the second argument is the stop that it connects to. These connections define the tube network, and can be used to answer questions about the relationships between stops.

Prompt

Convert connects/2 to use quoted atoms and proper names for the values.

ChatGPT Completion

connects('Oxford Circus', 'Tottenham Court Road').
connects('Tottenham Court Road', 'Holborn').
connects('Holborn', 'Leicester Square').
connects('Leicester Square', 'Piccadilly Circus').
connects('Piccadilly Circus', 'Green Park').
connects('Green Park', 'Bond Street').

This code defines the connections between the tube stops using quoted atoms, which are enclosed in single quotes, and proper names for the values. The connects/2 predicate takes two arguments: the first argument is the starting stop and the second argument is the stop that it connects to. These connections define the tube network, and can be used to answer questions about the relationships between stops.

Rose Tree (Data Structure)

Prompt

What is a Rose Tree data structure?

ChatGPT Completion

A Rose Tree is a tree data structure where each node has an ordered list of child nodes, and there is a single root node at the top. It is sometimes also called a “tree with a single parent.” Each node can have an arbitrary number of children, and the structure is often used to represent hierarchical data or structures such as the syntax tree of a programming language.

Prompt

Create sample data for a Rose Tree.

ChatGPT Completion

Sure, here’s an example of a Rose Tree data structure:

    A
   /|\
  B C D
 /|  | \
E F  G  H

In this example, “A” is the root node, and it has three child nodes: “B”, “C”, and “D”. Each of these nodes has its own set of child nodes as well. Node “B” has two child nodes, “E” and “F”, while node “D” has one child node, “H”. Node “C” has no child nodes, but it still counts as a node in the tree. Node “G” is a child of “D” and has no children of its own.

Prompt

Convert that to JSON.

ChatGPT Completion

Here’s an example of the Rose Tree data structure in JSON format:

{
    "name": "A",
    "children": [
        {
            "name": "B",
            "children": [
                {"name": "E", "children": []},
                {"name": "F", "children": []}
            ]
        },
        {
            "name": "C",
            "children": []
        },
        {
            "name": "D",
            "children": [
                {"name": "G", "children": []},
                {"name": "H", "children": []}
            ]
        }
    ]
}

In this JSON representation, each node is an object with a “name” attribute and a “children” attribute. The “name” attribute is a string representing the name of the node, and the “children” attribute is an array of child nodes, each of which is represented in the same way as the parent node. If a node has no children, the “children” array is empty.

Prompt

Convert that to Prolog facts.

ChatGPT Completion

Here’s an example of the Rose Tree data structure in Prolog facts:

node(a, [b, c, d]).
node(b, [e, f]).
node(c, []).
node(d, [g, h]).
node(e, []).
node(f, []).
node(g, []).
node(h, []).

In this Prolog representation, each node is represented as a fact with the node’s name as the first argument and a list of its child nodes as the second argument. If a node has no child nodes, an empty list is used as the second argument. Note that I have used lowercase letters for the node names as per Prolog naming conventions.

Prompt

Create a Prolog predicate to demonstrate traversing the Rose Tree data structure of Prolog facts in the previous response.

ChatGPT Completion

Sure! Here’s an example Prolog predicate to traverse the Rose Tree data structure and print out the name of each node in a depth-first order:

traverse(Node) :-
    node(Node, Children),
    write(Node), nl,
    traverse_children(Children).

traverse_children([]).
traverse_children([Child|Rest]) :-
    traverse(Child),
    traverse_children(Rest).

You can call the traverse/1 predicate with the name of the root node to traverse the Rose Tree data structure. For example, to traverse the tree in the previous response, you would call traverse(a).

This predicate uses the node/2 facts to get the list of child nodes for the current node, and then recursively calls traverse/1 on each child node. The write/1 predicate is used to print out the name of each node, and nl is used to add a newline character after each name for readability. The traverse_children/1 predicate is used to handle the base case where a node has no child nodes.

Writing test cases

Prompt

Write test cases for the predicate append/3.

ChatGPT Completion

Here are some sample test cases for the append/3 predicate in Prolog:

  1. Test the basic functionality of append/3:
append([1,2,3],[4,5,6],Result).
Expected output: Result = [1,2,3,4,5,6].
  1. Test the case where both input lists are empty:
append([],[],Result).
Expected output: Result = [].
  1. Test the case where the first input list is empty:
append([], [4,5,6], Result).
Expected output: Result = [4,5,6].
  1. Test the case where the second input list is empty:
append([1,2,3], [], Result).
Expected output: Result = [1,2,3].
  1. Test the case where the input lists have different data types:
append([1,2,3], [a,b,c], Result).
Expected output: Result = [1,2,3,a,b,c].
  1. Test the case where the input lists contain nested lists:
append([[1,2],[3,4]], [[5,6],[7,8]], Result).
Expected output: Result = [[1,2],[3,4],[5,6],[7,8]].

The problem with these test are that they test append/3 like a function with two inputs and one output. There is no test where Result is ground.

Improving/modifying existing code

Prompt

Modify JavaScript to use async and Promise.allSettled

fetch("elements.json")
  .then(res => res.json())
  .then(elements => {
    fetch("style.json")
      .then(res => res.json())
      .then(style => {
        var cy = cytoscape({
          container: document.getElementById("cy"),
          elements: elements,
          style: style
        });
      });
  });

ChatGPT Completion

async function initCytoscape() {
  const elementsPromise = fetch("elements.json").then(res => res.json());
  const stylePromise = fetch("style.json").then(res => res.json());

  const [elements, style] = await Promise.allSettled([elementsPromise, stylePromise]);

  var cy = cytoscape({
    container: document.getElementById("cy"),
    elements: elements.value,
    style: style.value
  });
}

initCytoscape();

A code review for correctness

Prompt

Do a code review of the following JavaScript for correctness

async function initCytoscape() {
  const elementsPromise = fetch("elements.json").then(res => res.json());
  const stylePromise = fetch("style.json").then(res => res.json());

  const [elements, style] = await Promise.allSettled([elementsPromise, stylePromise]);

  var cy = cytoscape({
    container: document.getElementById("cy"),
    elements: elements.value,
    style: style.value
  });
}

initCytoscape();

ChatGPT Completion

The code is generally correct, but there are a few improvements that can be made.

  1. The fetch function should have error handling to catch any errors that may occur during the request.
  2. The await statement can cause the code to block, so it’s better to wrap it in a try-catch block for better error handling.
  3. The code is using the value property of the resolved promises, which is not ideal. A better approach would be to use the .then() method to access the resolved value directly.

Here is an updated version of the code with these improvements:

async function initCytoscape() {
  try {
    const elementsPromise = fetch("elements.json")
      .then(res => {
        if (!res.ok) {
          throw new Error(`Unable to fetch elements.json: ${res.status} ${res.statusText}`);
        }
        return res.json();
      })
      .catch(error => {
        console.error(error);
      });

    const stylePromise = fetch("style.json")
      .then(res => {
        if (!res.ok) {
          throw new Error(`Unable to fetch style.json: ${res.status} ${res.statusText}`);
        }
        return res.json();
      })
      .catch(error => {
        console.error(error);
      });

    const [elements, style] = await Promise.all([elementsPromise, stylePromise]);

    var cy = cytoscape({
      container: document.getElementById("cy"),
      elements: elements,
      style: style
    });
  } catch (error) {
    console.error(error);
  }
}

initCytoscape();

A code review for security

Prompt

Do a code review of the following JavaScript for security

async function initCytoscape() {
  const elementsPromise = fetch("elements.json").then(res => res.json());
  const stylePromise = fetch("style.json").then(res => res.json());

  const [elements, style] = await Promise.allSettled([elementsPromise, stylePromise]);

  var cy = cytoscape({
    container: document.getElementById("cy"),
    elements: elements.value,
    style: style.value
  });
}

initCytoscape();

ChatGPT Completion

The code is using fetch API to get data from two JSON files: elements.json and style.json. The fetch API returns a Promise and the .then() method is used to parse the response to JSON.

The two promises are then combined into a single promise using Promise.allSettled() which returns an array of resolved or rejected promises. The elements and style are destructured from the returned array and used as options for the cytoscape visualization.

From a security perspective, there are no immediate risks with this code. However, the following considerations should be kept in mind:

  1. The code assumes that the two JSON files are accessible on the same origin as the JavaScript file. If the files are hosted on a different origin, it could lead to Cross-Origin Resource Sharing (CORS) issues.
  2. The code does not have any error handling to handle the case when either of the JSON files are not found or are not parseable. This could result in unexpected behavior.
  3. The code is trusting the contents of the JSON files without any validation. If the contents of the JSON files are untrusted or malicious, it could lead to security vulnerabilities.

To address these concerns, the following improvements can be made:

  1. Use a library like Axios to handle CORS issues.
  2. Implement error handling to catch any errors that might occur during the fetch or JSON parse.
  3. Validate the contents of the JSON files to ensure they are not malicious.
async function initCytoscape() {
  try {
    const elementsResponse = await axios.get("elements.json");
    const styleResponse = await axios.get("style.json");
    
    const elements = validateJson(elementsResponse.data);
    const style = validateJson(styleResponse.data);
    
    var cy = cytoscape({
      container: document.getElementById("cy"),
      elements: elements,
      style: style
    });
  } catch (error) {
    console.error(error);
  }
}

function validateJson(json) {
  // Implement validation logic here
}

initCytoscape();

Error messages

This is part of a conversation that noted gcc add.o -shared -o mylib.dll which upon running resulted in the error. The error was given as the prompt in the conversation and ChatGPT gave a reasonable explanation and updated instructions. This was much better than using a search engine or other forum to resolve the error.

Prompt

$ gcc add.o -shared -o mylib.dll
/usr/lib/gcc/x86_64-pc-msys/11.3.0/…/…/…/…/x86_64-pc-msys/bin/ld: add.o:add.c:(.text+0x20): undefined reference to PL_get_integer' /usr/lib/gcc/x86_64-pc-msys/11.3.0/../../../../x86_64-pc-msys/bin/ld: add.o:add.c:(.text+0x34): undefined reference to PL_get_integer’
/usr/lib/gcc/x86_64-pc-msys/11.3.0/…/…/…/…/x86_64-pc-msys/bin/ld: add.o:add.c:(.text+0x55): undefined reference to PL_unify_integer' /usr/lib/gcc/x86_64-pc-msys/11.3.0/../../../../x86_64-pc-msys/bin/ld: add.o:add.c:(.text+0x8d): undefined reference to PL_register_foreign’
collect2: error: ld returned 1 exit status

ChatGPT Completion

The error message indicates that the linker cannot find the definitions for the SWI-Prolog foreign language interface functions used in the C code. This is likely due to missing or incorrect compiler flags.

To fix this error, you need to include the necessary SWI-Prolog libraries and headers when compiling the C code. Here’s an updated set of instructions to compile pl_add using MSYS2 and gcc:

Install MSYS2: Download and run the MSYS2 installer from the official website, and follow the instructions to complete the installation.

Install the required packages: Open the MSYS2 terminal and update the package database by running pacman -Syu. Then, install the necessary packages for building SWI-Prolog foreign language interfaces by running pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make swi-prolog.

Write the C code: Create a new C file (e.g. add.c) and write the pl_add function as described in the previous example.

Compile the C code: In the MSYS2 terminal, navigate to the directory containing the C file and run the following command to compile it into a shared library:

gcc -c add.c -o add.o -I /usr/lib/swipl/include
gcc add.o -shared -o mylib.dll -L /usr/lib/swipl/lib/x86_64-w64-mingw32 -lswipl

This will create a shared library file mylib.dll that contains the pl_add function.

Load the shared library in SWI-Prolog: In a Prolog session, use the load_foreign_library/1 predicate to load the shared library file:

?- load_foreign_library('path/to/mylib.dll').
true.

Use the add/3 predicate: Now that the shared library is loaded, you can use the add/3 predicate in Prolog to add two integers:

?- add(2, 3, Result).
Result = 5.

That’s it! With these steps, you should be able to compile the pl_add function into a shared library using gcc and MSYS2, and load it into SWI-Prolog to use as a foreign language interface.

Regenerate response may help

In building zlib for Windows the ChatGPT completion noted a command that resulted in errors

cl -I…\ -O2 -nologo -DWIN64 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS zpipe.c …\zlib.lib

regenerating response gave a correct command

cl /nologo /MT /O2 /DASMV /DASMINF /I. /Icontrib\vstudio\vc14\x64\ZlibStat\include /Fezpipe.exe examples\zpipe.c /link /LIBPATH:contrib\vstudio\vc14\x64\ZlibStat\lib zdll.lib

It is worth noting that sometimes a completion may contain an incorrect portion alongside a correct one. Therefore, it is advisable to save the current completion before generating a new response.

Breaking commands apart

Often when trying to resolve an error it is best to isolate the cause of the error to a minimal example. When a build instrstion does both the compile and linking in one command, splitting the command into separate compile and link commands can narrow down the cause of the error.

Prompt

Convert this build command into two steps, one for compile, one for link.

$ gcc -o disasm disasm.c -lcapstone

ChatGPT Completion (ChatGPT Mar 14 Version)

Step 1 - Compile:

gcc -c disasm.c -o disasm.o

This command will compile the source code file “disasm.c” and create an object file “disasm.o”.

Step 2 - Link:

gcc disasm.o -o disasm -lcapstone

This command will link the object file “disasm.o” with the Capstone library and create the executable file “disasm”.

MSYS2 Environments

ChatGPT Mar 14 Version

Prompt

Please explain the differences in building code using MSYS2 for the following

  • Cross build for Windows
  • MSYS2 posix emulation

For the different tool chains include

  • Which shell to use, include Windows executable name
  • Command line to install tool chain
  • Create C code for an Hello World example
  • Command line to compile
  • Command line to link
  • Command line to run

Completion

Here are the differences in building code using MSYS2 for cross-build for Windows or MSYS2 posix emulation, including the toolchains used and the steps required:

Cross build for Windows using MSYS2:

  • Shell: Use the MSYS2 MinGW 64-bit shell (mingw64.exe) to build code for cross-build on Windows.
  • Toolchain installation: You can install the MinGW-w64 toolchain using the Pacman package manager that comes with MSYS2. You can install the toolchain using the following command:
pacman -S mingw-w64-x86_64-toolchain
  • Hello World example: To create a C code for a “Hello World” example, create a new file called “hello.c” with the following contents:
#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}
  • Compiling: To compile the “Hello World” example using the MinGW-w64 toolchain, use the following command:
x86_64-w64-mingw32-gcc -c hello.c
  • Linking: To link the compiled object file and create an executable using the MinGW-w64 toolchain, use the following command:
x86_64-w64-mingw32-gcc -o hello.exe hello.o
  • Running: To run the “Hello World” executable on Windows, use the following command:
./hello.exe

MSYS2 posix emulation:

  • Shell: Use the MSYS2 64-bit shell (msys2.exe) to build code for MSYS2 posix emulation.
  • Toolchain installation: You can install the GCC toolchain using the Pacman package manager that comes with MSYS2. You can install the toolchain using the following command:
pacman -S base-devel mingw-w64-x86_64-toolchain
  • Hello World example: To create a C code for a “Hello World” example, create a new file called “hello.c” with the following contents:
#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}
  • Compiling: To compile the “Hello World” example using the GCC toolchain, use the following command:
gcc -c hello.c
  • Linking: To link the compiled object file and create an executable using the GCC toolchain, use the following command:
gcc -o hello.exe hello.o
  • Running: To run the “Hello World” executable on MSYS2 posix emulation, use the following command:
./hello.exe

Note that the specific commands and steps may vary depending on the project requirements and the tools used, but the key differences involve the toolchains used, the environment variables set, and the commands used to install, compile, link, and run the code.


Generating OpenAPI Specification (OAS) from a cURL command

Prompt
ChatGPT May 24 Version

Convert this cURL command to an Open API Spec

curl -X GET "http://localhost:5003/hello"

Completion

Sure, here’s a basic OpenAPI Specification (OAS) for the provided cURL command:

openapi: "3.0.0"
info:
  version: "1.0.0"
  title: "Hello API"
paths:
  /hello:
    get:
      summary: "Get Hello"
      operationId: "getHello"
      responses:
        '200':
          description: "Successful operation"
servers:
  - url: "http://localhost:5003"

This is a very basic specification. In a real-world scenario, you would likely have more information to include, such as parameters, request bodies, response bodies, and more detailed descriptions. Also, you might have more endpoints to include in the paths section.